【问题标题】:NLog ElasticSearch structuredloggingNLog ElasticSearch 结构化日志记录
【发布时间】:2018-03-24 12:34:49
【问题描述】:

我需要将 NLog 日志消息发送到 Kibana。现在我将 NLog.Targets.ElasticSearch 与结构化日志记录.json 一起使用,但在这种情况下,elastic 将消息视为字符串而不是 json。一般来说,我需要 Kibana 将消息视为对象,我可以通过这些字段进行未来分析。

那么如何强制 nlog 或 NLog.Targets.ElasticSearch 将数据发送到 elasticsearch 被视为 json 呢?

这是我现在拥有的:

  {
    "_index": "logstash-2017.10.12",
    "_type": "logevent",
    "_id": "AV8QvCAHXFqCIKUdDl_1",
    "_score": 1,
    "_source": {
      "@timestamp": "2017-10-12T13:18:05.0609218Z",
      "level": "Error",
      "message": """{"TimeStamp":"2017-10-12T13:18:05.060Z","Level":"Error","LoggerName":"testApp.Program","Message":"error","CallSite":"testApp.Program.Main","error":"error0"}"""
    }
  }

它必须是这样的:

  {
    "_index": "logstash-2017.10.12",
    "_type": "logevent",
    "_id": "AV8QvCAHXFqCIKUdDl_1",
    "_score": 1,
    "_source": {
      "@timestamp": "2017-10-12T13:18:05.0609218Z",
      "level": "Error",
      "message": {
        "TimeStamp":"2017-10-12T13:18:05.060Z",
        "Level":"Error",
        "LoggerName":"testApp.Program",
        "Message":"error",
        "CallSite":"testApp.Program.Main",
        "error":"error0"
      }
    }
  }

当前的 NLog.config 看起来是这样的:

<target name="elastic" xsi:type="BufferingWrapper" flushTimeout="5000" >
  <target xsi:type="ElasticSearch" layout="${structuredlogging.json}">
  </target>
</target>

【问题讨论】:

  • 看起来消息已经被编码为 Json,然后 ${structuredlogging.json} 再执行一次编码。也许您应该只使用 NLog-JsonLayout 并自己配置格式:github.com/NLog/NLog/wiki/JsonLayout (encode = false for the ${message})
  • 不,第一次使用 ${structuredlogging.json} 编码的消息。据我了解,NLog-JsonLayout 只会制作一个 json,但问题出在 NLog.Targets.ElasticSearch 中。根据它的源代码,它将消息作为字符串发送,并且无法将其作为字典的一部分发送,即 Json。
  • NLog.Targets.ElasticSearch 和 NLog.StructuredLogging.Json 不能开箱即用。您必须选择,如果您选择后者,则必须创建一个自定义目标,该目标使用从 NLog.StructuredLogging.Json 接收的 Json 调用 IElasticLowLevelClient。可能会为 NLog.StructuredLogging.Json 创建一个关于如何与弹性搜索集成的问题。
  • @show 你解决了这个问题吗?
  • @yosbel ,不,我没有。

标签: c# elasticsearch kibana nlog


【解决方案1】:

也许这会起作用:

<target name="elastic" xsi:type="BufferingWrapper" flushTimeout="500" >
  <target xsi:type="ElasticSearch">
     <field name="msg" layout="${structuredlogging.json}" layoutType="System.Object" />
  </target>
</target>

您也可以这样做(没有 NLog.StructuredLogging.Json):

<target name="elastic" xsi:type="BufferingWrapper" flushTimeout="500" >
  <target xsi:type="ElasticSearch" includeAllProperties="true">
     <field name="TimeStamp" layout="${date:format=o}" />
     <field name="Level" layout="${level}" />
     <field name="LoggerName" layout="${logger}" />
     <field name="Message" layout="${message}" />
     <field name="CallSite" layout="${callsite}" />
     <field name="error" layout="${exception:format=tostring}" />
  </target>
</target>

您也可以这样做(使用EcsLayout):

<extensions>
    <add assembly="NLog.Targets.ElasticSearch"/>
    <add assembly="Elastic.Apm.NLog"/>
    <add assembly="Elastic.CommonSchema.NLog"/>
</extensions>
<targets>
   <target xsi:type="ElasticSearch" enableJsonLayout="true">
       <layout xsi:type="EcsLayout" />
   </target>
</targets>

【讨论】:

【解决方案2】:

你可以这样做:

<field name="MessageObject" layout="${message}" layoutType="System.Object" />

然后使用以下命令进行日志记录:

_logger.LogInformation("{@ExampleObject}", exampleLoggingObject);

输出是:

 "Message": {
     "ExecutionTime": 12,
     "Level": "Information",
     "Type": "ABC",
     ....
 }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多