28

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

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

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

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

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

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

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

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

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

4

5 回答 5

21

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

于 2014-05-28T12:26:35.713 回答
10

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

然后我能够创建它:

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

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

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

确保你有:

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

这将记录如下内容:

{  
   "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
   }
}

可能是不同的设置,因为我使用 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>
于 2017-02-16T15:57:11.620 回答
5

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

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

于 2014-08-07T19:51:30.893 回答
5

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

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

于 2016-08-17T22:45:02.323 回答
1

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

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

  • 用于定义记录的数据类型键和类型的码本,
  • 日志聚合工具的配置(如elasticsearch)
  • 生成 Java 帮助程序代码以实现高效和正确的日志记录

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

一个示例帮助代码语句将是

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

而生成的降价会像这样

于 2017-10-26T21:06:05.877 回答