【问题标题】:How to have different log types using Serilog and ElasticSearch如何使用 Serilog 和 ElasticSearch 拥有不同的日志类型
【发布时间】:2018-10-18 11:29:13
【问题描述】:

我目前正在尝试更改我们的系统配置以使用 Serilog而不是使用 FileBeat 作为 LogStash 的托运人

我们还在各种查询中使用日志 type 字段(很容易在 FileBeat 配置文件中配置)并在 Elastic 上索引日志。

问题是在使用 Serilog 时,我们得到了默认类型 logevent,我没有找到可以配置它的地方。 我想有一个选项来确定每个 Serilog 实例的特定日志类型。 目前我的所有日​​志都有默认类型。

我的 Serilop 配置是:

        var path = GetLogPath();
        var logger = new LoggerConfiguration()
            .MinimumLevel.Information()
            .Enrich.WithMachineName()
            .Enrich.WithProperty("RequestId", Guid.NewGuid())
            .WriteTo.RollingFile(
                pathFormat: path,
                outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u4}] [{RequestId}] {Message}{NewLine}{Exception}", buffered: false, shared: true);
        logger.WriteTo.Elasticsearch(
                new ElasticsearchSinkOptions(new Uri(this.configurationService.ElasticSearchUrl())));

如何更改日志类型?

编辑

经过一番调查,我发现我想更改 LoggerConfiguration 中提交的 typeName 并且似乎我只能通过 AppConfig 文件这样做,如果我要更改它,这又是一次事件,更改将影响所有记录器实例。

我错过了什么吗?

【问题讨论】:

  • 更多关于type 对您的意义的信息。一般来说,在 Serilog 中,如果您指的是与记录器关联的类型,则可以将 {SourceContext} 属性作为标记放入发出格式中。如果您的意思是消息模板的 id,github.com/serilog/serilog-formatting-compact 将为您提供线索。 (我对 ES 接收器的了解为零(显然),但如果您发出 json,您通常可以使用该格式来指导要包含的内容)
  • thanx Ruben,我读了一些关于这个属性的文章,这听起来确实是个好习惯。我不确定它是否会解决我与 Elelastic 中的日志索引相关的问题

标签: c# elasticsearch serilog elasticsearch-net


【解决方案1】:

只需为 Elasticsearch 接收器使用另一个重载:

var path = GetLogPath();
var logger = new LoggerConfiguration()
    .MinimumLevel.Information()
    .Enrich.WithMachineName()
    .Enrich.WithProperty("RequestId", Guid.NewGuid())
    .WriteTo.RollingFile(
        pathFormat: path,
        outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u4}] [{RequestId}] {Message}{NewLine}{Exception}", buffered: false, shared: true);
logger.WriteTo.Elasticsearch(
        this.configurationService.ElasticSearchUrl(), typeName: "type");

因此您不必在 appsettings 中指定 typeName,它也不会影响所有实例。

【讨论】:

  • 不编译...Elasticsearch 构造函数不接受这个重载。只有:public static LoggerConfiguration Elasticsearch(this LoggerSinkConfiguration loggerSinkConfiguration, string nodeUris, string indexFormat = null, string templateName = null);
  • @Green 你有旧版本的 Elasticsearch 接收器吗?我尝试了Serilog.Sinks.ElasticSearch的v6.5.0,它公开了新方法。
  • 是的,我刚才看到了,我将我的版本更新到了 6.5 - 他们确实宣传了这个功能。帅哥,谢谢! P.S 我必须给另一个参数(例如:serializer),如果没有,编译器会抱怨他们添加的 2 个构造函数有歧义)
【解决方案2】:

更新答案

要将属性和值添加到您的记录器,您可以使用Contextual logging and Enrichment

上下文记录器

将上下文属性附加到日志事件的最简单、最直接的方法

首先初始化你的记录器:

Log.Logger = new LoggerConfiguration().ReadFrom.AppSettings().CreateLogger();

然后您可以创建上下文记录器:

// adding Log Context
var StudentLogger = Log.Logger.ForContext<Student>();

StudentLogger.Error(/* log message */);

或者您可以使用相关日志条目:

// correlation Log Entries
var orderId = "some value";
var corrLog = Log.Logger.ForContext("orderId", orderId)

corrLog.Error(/* log message */);

充实

在某些情况下,我们希望记录器创建的每个事件都携带 相同的、固定的财产价值。应用示例是其中之一 这些。

Serilog 在 a 级别提供 Enrich.WithProperty() 为此的记录器配置:

Log.Logger = new LoggerConfiguration()
    .Enrich.WithProperty("Application", "e-Commerce")
    .Enrich.WithProperty("Environment", ConfigurationManager.AppSettings["Environment"])
    // Other logger configuration

原答案

Serilog有两种配置方式:

使用 API(需要 serilog.sinks.elasticsearch 包):

var loggerConfig = new LoggerConfiguration()
    .MinimumLevel.Debug()
    .WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri("http://localhost:9200") ){
         AutoRegisterTemplate = true,
 });
var logger = loggerConfig.CreateLogger();

Serilog Documentation

使用 AppSettings 中的配置(除了 serilog.sinks.elasticsearch 还需要 Serilog.Settings.AppSettings)

这样,您将所有设置放在 AppSetting 文件中,例如

<appSettings>
    <add key="serilog:using" value="Serilog.Sinks.Elasticsearch"/>
    <add key="serilog:write-to:Elasticsearch.nodeUris" value="http://localhost:9200;http://remotehost:9200"/>
    <add key="serilog:write-to:Elasticsearch.indexFormat" value="custom-index-{0:yyyy.MM}"/>
    <add key="serilog:write-to:Elasticsearch.templateName" value="myCustomTemplate"/>
  </appSettings>

并告诉 serilog 从 appSettigns 读取配置

Log.Logger = new LoggerConfiguration()
  .ReadFrom.AppSettings()
  ... // Other configuration here, then
  .CreateLogger()

请参阅:AppSettingElasticSearch Configure Sink

我不确定您指的是哪种日志事件类型?就我而言,我在记录错误时传递了对象类型:

catch (Exception ex)
{
    Logger.Error(ex, string.Format("Exception occured in Controller: {0}, Action: Post.", this.GetType()), this.GetType());

【讨论】:

  • 感谢您的详细回答,这听起来确实像是更改 typeName 字段的方式。但是,正如我在编辑中提到的那样,如果我在不同的类中有几种不同类型的日志(假设 A 类写入 LogA 类型日志,B 类写入 LogB 等等),如果我使用相同的配置文件?我可以以某种方式对不同的类使用不同的配置文件吗
  • Elastic 处理索引的问题。因此,如果想像以前一样继续工作(出于方便的原因,我会这样做),我需要更改类型。因为弹性中的索引是基于该字段的。我正在考虑从当前存储库中分叉并自己添加此功能。但我很确定我错过了一种方式
【解决方案3】:

另一种选择是创建一个全局加载器静态类。定义多个 ILogger 字段,一个用于错误,另一个用于诊断等。配置静态构造函数中的字段。然后创建几个公共方法,WriteError()、WriteDebug()、WriteInfo() 等等。例如,从 WriteDebug(logDetail) 方法调用 ILogger.Write(LogEventLevel.Debug, logDetail) 时,您将能够决定 LogEventLevel。

【讨论】:

    猜你喜欢
    • 2016-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-02
    • 1970-01-01
    • 2020-08-10
    • 1970-01-01
    相关资源
    最近更新 更多