我面临的情况是,在将我所有的Serilog* nuget软件包升级到
<PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="5.0.1" />
<PackageReference Include="Serilog.Extensions.Logging" Version="3.1.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.4.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.ElasticSearch" Version="8.4.1" />
<PackageReference Include="Serilog.Sinks.Seq" Version="5.2.1" />
当我使用
Log.Logger = LoggerConfiguration()
.ReadFrom.Configuration(config)
.Enrich.WithElasticApmCorrelationInfo()
.WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri("http://xxxxxxxxxxxxxxxxxxx"))
{
AutoRegisterTemplate = true,
IndexFormat = "mslogs-{0:yyyy.MM.dd}",
DetectElasticsearchVersion = true,
RegisterTemplateFailure = RegisterTemplateRecovery.IndexAnyway,
AutoRegisterTemplateVersion = AutoRegisterTemplateVersion.ESv7,
FailureCallback = e => Console.WriteLine($"Unable to submit event {e?.RenderMessage()} to ElasticSearch. Exception : " + e?.Exception?.ToString()),
EmitEventFailure = EmitEventFailureHandling.WriteToSelfLog |
EmitEventFailureHandling.WriteToFailureSink |
EmitEventFailureHandling.RaiseCallback,
BufferCleanPayload = (failingEvent, statuscode, exception) =>
{
dynamic e = JObject.Parse(failingEvent);
return JsonConvert.SerializeObject(new Dictionary<string, object>()
{
{ "action", "DeniedByElasticSearch"},
{ "@timestamp",e["@timestamp"]},
{ "level","Error"},
{ "message","Error: "+e.message},
{ "messageTemplate",e.messageTemplate},
{ "failingStatusCode", statuscode},
{ "failingException", exception}
});
},
CustomFormatter = new EcsTextFormatter()
})
.CreateLogger();
使用appsettings.json配置
"Serilog": {
"Using": [],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Information",
"Elastic": "Warning",
"Apm": "Warning"
}
},
"WriteTo": [
{
"Name": "Console"
}
],
"Enrich": [
"FromLogContext",
"WithMachineName",
"WithProcessId",
"WithThreadId"
],
"Properties": {
"ApplicationName": "myapplication"
}
}
它抛出以下异常,显然是在调用.ReadFrom.Configuration(config)
扩展方法时:
Unhandled exception. System.Reflection.CustomAttributeFormatException: Binary format of the specified custom attribute was
invalid.
at System.Reflection.CustomAttributeEncodedArgument.ParseAttributeArguments(IntPtr pCa, Int32 cCa,
CustomAttributeCtorParameter[]& CustomAttributeCtorParameters, CustomAttributeNamedParameter[]&
CustomAttributeTypedArgument, RuntimeAssembly assembly)
at System.Reflection.RuntimeCustomAttributeData..ctor(RuntimeModule scope, MetadataToken caCtorToken, ConstArray& blob)
at System.Reflection.RuntimeCustomAttributeData.GetCustomAttributes(RuntimeModule module, Int32 tkTarget)
at System.Reflection.RuntimeCustomAttributeData.GetCustomAttributesInternal(RuntimeMethodInfo target)
at System.Reflection.RuntimeMethodInfo.GetCustomAttributesData() at System.Reflection.MemberInfo.get_CustomAttributes()
at Serilog.Settings.Configuration.ConfigurationReader. FindConfigurationExtensionMethods>g__HasExtensionAttribute|32_0(MethodInfo m)
at Serilog.Settings.Configuration.ConfigurationReader.<>c.<FindConfigurationExtensionMethods>b__32_3(MethodInfo m)
at System.Linq.Utilities.<>c__DisplayClass1_0`1.<CombinePredicates>b__0(TSource x)
at System.Linq.Enumerable.WhereEnumerableIterator`1.ToList()
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Serilog.Settings.Configuration.ConfigurationReader.FindConfigurationExtensionMethods(IReadOnlyCollection`1
configurationAssemblies, Type configType)
at Serilog.Settings.Configuration.ConfigurationReader.FindEventEnricherConfigurationMethods(IReadOnlyCollection`1
configurationAssemblies)
at Serilog.Settings.Configuration.ConfigurationReader.ApplyEnrichment(LoggerConfiguration
loggerConfiguration)
at Serilog.Settings.Configuration.ConfigurationReader.Configure(LoggerConfiguration
loggerConfiguration)
at Serilog.Configuration.LoggerSettingsConfiguration.Settings(ILoggerSettings settings)
at Serilog.ConfigurationLoggerConfigurationExtensions.Configuration(LoggerSettingsConfiguration settingConfiguration,
IConfiguration configuration, String sectionName, DependencyContext dependencyContext)
at Serilog.ConfigurationLoggerConfigurationExtensions.Configuration(LoggerSettingsConfiguration settingConfiguration,
IConfiguration configuration, DependencyContext dependencyContext)
at ITF.SharedLibraries.Logging.LoggerFactory.GetELKLogger(IConfiguration config, String varEnv)
at MyApplication.Startup.ConfigureServices(IServiceCollection services) in /src/MyApplication/src/Startup.cs:line 46
at System.RuntimeMethodHandle.InvokeMethod(Object target, Span`1& arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Microsoft.AspNetCore.Hosting.MethodInfoExtensions.InvokeWithoutWrappingExceptions(MethodInfo methodInfo, Object obj, Object[] parameters)
at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.InvokeCore(Object instance, IServiceCollection services)
at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.<>c__DisplayClass9_0. <Invoke>g__Startup|0(IServiceCollection serviceCollection)
at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.Invoke(Object instance, IServiceCollection services)
at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.<>c__DisplayClass8_0.<Build>b__0(IServiceCollection services)
at Microsoft.AspNetCore.Hosting.GenericWebHostBuilder.UseStartup(Type startupType, HostBuilderContext context,
IServiceCollection services, Object instance)
at Microsoft.AspNetCore.Hosting.GenericWebHostBuilder.<>c__DisplayClass13_0.
<UseStartup>b__0(HostBuilderContext context, IServiceCollection services)
at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()
at Microsoft.Extensions.Hosting.HostBuilder.Build()
at MyApplication.Program.Main(String[] args) in /src/MyApplication/src/Program.cs:line 12
重要注意事项
- 对于两个独立的微服务来说,这是完全相同的行为,我们将软件包升级推到了生产环境中。
- 它不会在本地抛出(docker环境),也不会在开发环境中的K8S集群中抛出,或者在uat环境中也不会抛出,但是它会在生产环境中系统地抛出。
- 我们从vanilla .net运行时docker映像(mcr.microsoft.com/dotnet/sdk:6.0)系统地(提交触发)构建微服务,并使用Azure代理在Azure Devops上的CI/CD管道中动态地进行基本的. net恢复。
- 当我降级到之前版本的Serilog* 软件包时(在升级之前),在我们所有的环境中,这两个应用程序都能正常运行
- 微服务是在.net 6中开发的,它们托管在K8S集群(AKS)中,而Elasticsearch集群的版本为v 7.17.1
以下是出现问题的降级版本
<PackageReference Include="Serilog" Version="2.11.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="5.0.1" />
<PackageReference Include="Serilog.Extensions.Logging" Version="3.1.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.3.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" />
<PackageReference Include="Serilog.Sinks.ElasticSearch" Version="8.4.1" />
<PackageReference Include="Serilog.Sinks.Seq" Version="5.1.1" />
<PackageReference Include="StackExchange.Redis" Version="2.6.48" />
由于该问题仅发生在我们的生产环境中,因此我感觉Elk中的数据/设置存在问题,新的Serilog* 强调了这一点,但我不知道从何处进行调查。
2条答案
按热度按时间roqulrg31#
最后,Serilog团队提供了一个变通方案https://github.com/serilog/serilog-settings-configuration/pull/333/files
顺便说一句,误差的来源是不确定的,几乎不可再现。
vaqhlq812#
我在一个dotnet 6微服务中也遇到了同样的问题。在阅读了这篇文章之后,查看了gitlab中SeriLog最近的变化,并查看了我的堆栈跟踪-很明显,ReadFromConfig选项中有什么东西被破坏了。
我只在cert中发现了这个问题,所以我把注意力集中在我的工作envs(local,sbx,dev)和坏的envs(cert)之间的差异上。在检查了这些差异之后,我能够通过以下两个调整来解决这个问题:
1.已将appsettings.json中的共享配置部分移动到每个相应的环境文件(appsettings.sbx.json、appsettings.cert.json等)
1.从配置文件中删除了Enrich.FromLogContext(),并在Program.cs中对其进行了编码,因为它不需要通过环境进行配置。