Java 是否有创建带有消息参数作为属性的 JSON 对象的 Logback 布局?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22615311/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 16:52:39  来源:igfitidea点击:

Is there a Logback Layout that Creates JSON Objects with Message Parameters as Attributes?

javajsonslf4jlogbackloggly

提问by MusikPolice

I want to send log events to Loggly as JSON objects with parameterized string messages. Our project currently has a lot of code that looks like this:

我想将日志事件作为带有参数化字符串消息的 JSON 对象发送到 Loggly。我们的项目目前有很多代码看起来像这样:

String someParameter = "1234";
logger.log("This is a log message with a parameter {}", someParameter);

We're currently using Logback as our SLF4J backend, and Logback's JsonLayoutto serialize our ILogEvent objects into JSON. Consequentially, by they time our log events are shipped to Loggly, they look like this:

我们目前使用 Logback 作为我们的 SLF4J 后端,并使用 Logback 的JsonLayout将我们的 ILogEvent 对象序列化为 JSON。因此,当我们的日志事件被传送到 Loggly 时,它们看起来像这样:

{
    "message": "This is a log message with a parameter 1234",
    "level": INFO,
    ....
}

While this does work, it sends a different messagestring for every value of someParameter, which renders Loggly's automatic filters next to useless.

虽然这确实有效,但它会message为 的每个值发送一个不同的字符串someParameter,这使得 Loggly 的自动过滤器几乎无用。

Instead, I'd like to have a Layout that creates JSON that looks like this:

相反,我想要一个创建 JSON 的布局,如下所示:

{
    "message": "This is a log message with a parameter {}",
    "level": INFO,
    "parameters": [
        "1234"
    ]
}

This format would allow Loggly to group all log events with the message This is a log message with a parametertogether, regardless of the value of someParameter.

这种格式将允许 Loggly 将所有日志事件与消息This is a log message with a parameter组合在一起,而不管someParameter.

It looks like Logstash's KV filterdoes something like this - is there any way to accomplish this task with Logback, short of writing my own layout that performs custom serialization of the ILogEvent object?

看起来Logstash 的 KV 过滤器做了这样的事情 - 有没有办法用 Logback 完成这个任务,除了编写我自己的布局来执行 ILogEvent 对象的自定义序列化?

采纳答案by muttonUp

You could use a Mapped Diagnostic Contextto set a stamp for each of those type of log messages that you could then filter on once in loggly.

您可以使用映射诊断上下文为每种类型的日志消息设置一个标记,然后您可以在 loggly 中过滤一次。

According to the source of JsonLayoutthe stamp is stored as a separate value in the JSON.

根据JsonLayout的来源,标记作为单独的值存储在 JSON 中。

回答by Mark Roper

There is a JSON logstash encoder for Logback, logstash-logback-encoder

Logback 有一个 JSON logstash 编码器,logstash-logback-encoder

回答by ash

Here's a recently created project that provides a JSON-specific logging API and works with SLF4J:

这是一个最近创建的项目,它提供了一个 JSON 特定的日志 API 并与 SLF4J 一起使用:

https://github.com/savtheitroadtech/slf4j-json-logger

https://github.com/savtheitroadtech/slf4j-json-logger

回答by andrewps

So for me I was trying to log execution times, I created a pojo called ExecutionTime with name, method, class, duration.

所以对我来说,我试图记录执行时间,我创建了一个名为 ExecutionTime 的 pojo,其中包含名称、方法、类、持续时间。

I was then able to create it:

然后我能够创建它:

ExecutionTime time = new ExecutionTime("Controller Hit", methodName, className, sw.getTotalTimeMillis());

For logging I then used:

对于日志记录,我使用了:

private final Logger logger = LoggerFactory.getLogger(this.getClass());
logger.info(append("metric", time), time.toString());

Make sure you have:

确保你有:

import static net.logstash.logback.marker.Markers.append;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

This will log something like this:

这将记录如下内容:

{  
   "ts":"2017-02-16T07:41:36.680-08:00",
   "msg":"ExecutionTime [name=Controller Hit, method=setupSession, className=class com.xxx.services.controllers.SessionController, duration=3225]",
   "logger":"com.xxx.services.metrics.ExecutionTimeLogger",
   "level":"INFO",
   "metric":{  
      "name":"Controller Hit",
      "method":"setupSession",
      "className":"class com.xxx.services.controllers.SessionController",
      "duration":3225
   }
}

Might be a different set up as I was using logback-spring.xml to output my logs to json:

可能是不同的设置,因为我使用 logback-spring.xml 将我的日志输出到 json:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml"/>
    <property name="PROJECT_ID" value="my_service"/>
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>app/logs/${PROJECT_ID}.json.log</File>
        <encoder class="net.logstash.logback.encoder.LogstashEncoder">
            <fieldNames>
                <timestamp>ts</timestamp>
                <message>msg</message>
                <thread>[ignore]</thread>
                <levelValue>[ignore]</levelValue>
                <logger>logger</logger>
                <version>[ignore]</version>
            </fieldNames>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
            <maxIndex>10</maxIndex>
            <FileNamePattern>app/logs/${PROJECT_ID}.json.log.%i</FileNamePattern>
        </rollingPolicy>
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>20MB</MaxFileSize>
        </triggeringPolicy>
    </appender>
    <logger name="com.xxx" additivity="false" level="DEBUG">
        <appender-ref ref="FILE"/>
        <appender-ref ref="CONSOLE"/>
    </logger>
    <root level="WARN">
        <appender-ref ref="FILE"/>
    </root>
</configuration>

回答by ThomasRS

Like already answered you'll get a one-dimensional JSON tree with MDC and/or using a Marker with logstash-logback-encoder.

就像已经回答的那样,您将获得带有 MDC 和/或使用带有 logstash-logback-encoder 的标记的一维 JSON 树。

If you are also looking for the following:

如果您还在寻找以下内容:

  • codebooks for definition of logged datatype key and type,
  • configuration of log-aggregation tools (like elasticsearch)
  • generated Java helper-code for efficient and correct logging
  • 用于定义记录的数据类型键和类型的码本,
  • 日志聚合工具的配置(如elasticsearch)
  • 生成的 Java 帮助程序代码,用于高效且正确的日志记录

then try a project I've created: json-log-domain. It defines a simple YAML-format definition from which the above can be generated.

然后尝试我创建的一个项目:json-log-domain。它定义了一个简单的 YAML 格式定义,可以从中生成上述内容。

An example helper-code statement would be

一个示例辅助代码语句是

logger.info(host("localhost").port(8080), "Hello world");

while generated markdown would like something like this.

而生成的降价会像这样