Serilog with Elasticsearch sink, indexformat 没有滚动日期
Serilog with Elasticsearch sink, indexformat has no rolling date
我使用 Serilog 和 Elasticsearch 接收器将我的日志推送到 Elastic,以及我在 .net 5 应用程序中的 APM 中的事务。
创建记录器时,它使用当前日期时间作为索引格式的一部分 (mslogs-yyyy.MM.dd),但一旦容器为 运行,它仍然是相同的索引名称无论当前时间如何,都会使用它。
例如,如果容器在 2021 年 6 月 25 日启动,则索引创建为 mslogs-2021.06.25
并在容器的整个生命周期内保留,因此在接下来几天生成的日志仍会推送到该索引中。
由于我的 Ops 在 Elk 上制定了删除旧日志的政策,基于索引名称(日期时间部分),新日志可能会被删除,因为它们被放入“旧索引”。
这是我的记录器生成器
public static Logger GetELKLogger(IConfiguration config, string varEnv = "ElasticSearchLog")
{
var configuration = config.Get<Configuration>(varEnv);
return new LoggerConfiguration()
.ReadFrom.Configuration(config)
.Enrich.WithElasticApmCorrelationInfo()
.WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri(configuration.ElasticSearchLog))
{
AutoRegisterTemplate = true,
IndexFormat = $"mslogs-{DateTime.UtcNow:yyyy.MM.dd}", // called once at startup !!
DetectElasticsearchVersion = true,
RegisterTemplateFailure = RegisterTemplateRecovery.IndexAnyway,
AutoRegisterTemplateVersion = AutoRegisterTemplateVersion.ESv7,
FailureCallback = e => Console.WriteLine($"Unable to submit event {e.RenderMessage()} to ElasticSearch. Full message : " + e.Serialize()),
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();
}
和记录器创建
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Logger
Log.Logger = SharedLibraries.Logging.LoggerFactory.GetELKLogger(Configuration);
我是否应该强制每天重新创建一次记录器实例以受益于 DateTime.UtcNow
更新?
或者有没有更优雅的解决方案?
依赖关系
<TargetFramework>net5.0</TargetFramework>
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="4.1.2" />
<PackageReference Include="Serilog.Extensions.Logging" Version="3.0.1" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="Serilog.Sinks.ElasticSearch" Version="8.4.1" />
<PackageReference Include="Serilog.Sinks.Seq" Version="5.0.1" />
<PackageReference Include="Elastic.Apm.NetCoreAll" Version="1.11.0" />
<PackageReference Include="Elastic.Apm.SerilogEnricher" Version="1.5.3" />
<PackageReference Include="Elastic.CommonSchema.Serilog" Version="1.5.3" />
IndexFormat
属性 是 a .NET format string 超过事件的时间戳(UTC),所以你不应该使用 $
来插入值:
IndexFormat = "mslogs-{0:yyyy.MM.dd}"
我使用 Serilog 和 Elasticsearch 接收器将我的日志推送到 Elastic,以及我在 .net 5 应用程序中的 APM 中的事务。
创建记录器时,它使用当前日期时间作为索引格式的一部分 (mslogs-yyyy.MM.dd),但一旦容器为 运行,它仍然是相同的索引名称无论当前时间如何,都会使用它。
例如,如果容器在 2021 年 6 月 25 日启动,则索引创建为 mslogs-2021.06.25
并在容器的整个生命周期内保留,因此在接下来几天生成的日志仍会推送到该索引中。
由于我的 Ops 在 Elk 上制定了删除旧日志的政策,基于索引名称(日期时间部分),新日志可能会被删除,因为它们被放入“旧索引”。
这是我的记录器生成器
public static Logger GetELKLogger(IConfiguration config, string varEnv = "ElasticSearchLog")
{
var configuration = config.Get<Configuration>(varEnv);
return new LoggerConfiguration()
.ReadFrom.Configuration(config)
.Enrich.WithElasticApmCorrelationInfo()
.WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri(configuration.ElasticSearchLog))
{
AutoRegisterTemplate = true,
IndexFormat = $"mslogs-{DateTime.UtcNow:yyyy.MM.dd}", // called once at startup !!
DetectElasticsearchVersion = true,
RegisterTemplateFailure = RegisterTemplateRecovery.IndexAnyway,
AutoRegisterTemplateVersion = AutoRegisterTemplateVersion.ESv7,
FailureCallback = e => Console.WriteLine($"Unable to submit event {e.RenderMessage()} to ElasticSearch. Full message : " + e.Serialize()),
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();
}
和记录器创建
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Logger
Log.Logger = SharedLibraries.Logging.LoggerFactory.GetELKLogger(Configuration);
我是否应该强制每天重新创建一次记录器实例以受益于 DateTime.UtcNow
更新?
或者有没有更优雅的解决方案?
依赖关系
<TargetFramework>net5.0</TargetFramework>
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="4.1.2" />
<PackageReference Include="Serilog.Extensions.Logging" Version="3.0.1" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="Serilog.Sinks.ElasticSearch" Version="8.4.1" />
<PackageReference Include="Serilog.Sinks.Seq" Version="5.0.1" />
<PackageReference Include="Elastic.Apm.NetCoreAll" Version="1.11.0" />
<PackageReference Include="Elastic.Apm.SerilogEnricher" Version="1.5.3" />
<PackageReference Include="Elastic.CommonSchema.Serilog" Version="1.5.3" />
IndexFormat
属性 是 a .NET format string 超过事件的时间戳(UTC),所以你不应该使用 $
来插入值:
IndexFormat = "mslogs-{0:yyyy.MM.dd}"