Logback JsonLayout 在同一行打印所有日志

Posted

技术标签:

【中文标题】Logback JsonLayout 在同一行打印所有日志【英文标题】:Logback JsonLayout printing all logs on the same line 【发布时间】:2017-03-27 09:28:19 【问题描述】:

我正在使用 JsonLayout 和 Spring Boot 以 JSON 格式记录消息。我只希望将日志消息记录到控制台而不是日志文件。

我注意到 JSON 日志连续记录在同一行上。在生产环境中这没问题,因为我们会将日志传送到日志聚合器。但这变得有点难以分析当地的发展。

日志

"timestamp":"2016-11-13 23:06:17.727","level":"INFO","thread":"qtp745835029-19","logger":"com.test.controller.TestController","message":"Info log:: printme 1","context":"default""timestamp":"2016-11-13 23:06:17.727","level":"DEBUG","thread":"qtp745835029-19","logger":"com.test.controller.TestController","message":"Debug log:: printme","context":"default""timestamp":"2016-11-13 23:06:17.727","level":"WARN","thread":"qtp745835029-19","logger":"com.test.controller.TestController","message":"Warn log:: printme","context":"default""timestamp":"2016-11-13 23:06:17.727","level":"ERROR","thread":"qtp745835029-19","logger":"com.test.controller.TestController","message":"Error log:: printme","context":"default"

下面是logback配置logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml" />
    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
            <jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
                <prettyPrint>false</prettyPrint>
            </jsonFormatter>
            <timestampFormat>yyyy-MM-dd' 'HH:mm:ss.SSS</timestampFormat>
        </layout>
    </appender>
    <logger name="jsonLogger" additivity="false" level="DEBUG">
        <appender-ref ref="consoleAppender"/>
    </logger>
    <root level="INFO">
        <appender-ref ref="consoleAppender"/>
    </root>
</configuration>

我是否在配置中遗漏了某些内容,以便将它们记录在控制台上的不同行上。

感谢您对此的任何帮助。

【问题讨论】:

【参考方案1】:

来自@mvnm 的上述answer 对我来说效果很好。以防万一,如果需要漂亮的打印和换行符,可以使用以下配置。

<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
        <jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
            <prettyPrint>true</prettyPrint>
        </jsonFormatter>
        <timestampFormat>yyyy-MM-dd' 'HH:mm:ss.SSS</timestampFormat>
        <appendLineSeparator>true</appendLineSeparator>
    </layout>
</appender>

<root level="debug">
    <appender-ref ref="STDOUT" />
</root>

【讨论】:

不推荐用于生产漂亮打印以减少空间消耗。在本地开发的情况下,有助于提高可读性。【参考方案2】:

将 prettyPrint 设置为 true 是一种解决方案。但是在某些情况下,我们需要单行日志,例如向云手表等服务发送信息。 在布局中添加以下内容

<appendLineSeparator>true</appendLineSeparator>

【讨论】:

【参考方案3】:

对于ch.qos.logback.contrib.json.classic.JsonLayout,您需要将appendLineSeparator 选项设置为true。示例:

<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
        <jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter" />
        <timestampFormat>yyyy-MM-dd' 'HH:mm:ss.SSS</timestampFormat>
        <appendLineSeparator>true</appendLineSeparator>
    </layout>
</appender>

<root level="debug">
    <appender-ref ref="STDOUT" />
</root>

【讨论】:

这就是答案!不漂亮的印刷品。您仍然可以使用漂亮的打印,但它不会解决问题,因为在每条消息的末尾写 而没有 appendSeparator=true。【参考方案4】:

使用类似这样的方式将 Spring Boot 应用程序(或 JSON 日志文件)的输出传输到 jq:

java -jar target/myapp.jar | jq -R 'fromjson?'

这将在应用程序的输出之后提供漂亮、颜色突出、打印漂亮的 json。您的应用程序输出的不是 JSON 的任何内容都将被忽略(例如:Spring Boot 横幅)。

您可以在 jq 中使用过滤器来仅显示 INFO 级别的消息输出:

java -jar target/myapp.jar | jq -c -R 'fromjson? | select(.level="INFO") | message'

或者您可以使用过滤器删除您不想看到的键:

java -jar target/myapp.jar | jq -c -R 'fromjson? | del(.timestamp,.thread)'

【讨论】:

【参考方案5】:

我改用 logstah-logback-encoder,它没有 JSONLayout 的问题。

【讨论】:

这里是为 Spring Boot 设置 logstash-logback-encoder 的好方法:development.wombatsecurity.com/development/2017/09/29/…【参考方案6】:

已编辑:尝试将 prettyPrint 更改为 true -> &lt;prettyPrint&gt;true&lt;/prettyPrint&gt;

你在consoleAppender中写了两次日志

   <logger name="jsonLogger" additivity="false" level="DEBUG">
        <appender-ref ref="consoleAppender"/>
    </logger>
    <root level="INFO">
        <appender-ref ref="consoleAppender"/>
    </root>

改成

<logger name="jsonLogger" additivity="false" level="DEBUG"/>
<root level="INFO">
    <appender-ref ref="consoleAppender"/>
</root>

【讨论】:

感谢萨加尔的回复。但是删除 appender 并不能解决日志打印在同一行的问题。 尝试将 prettyPrint 改为 true -> true 参考文档:logging.apache.org/log4j/2.0/log4j-core/apidocs/org/apache/…,可能需要在 中添加 complete = "true" logback 中的 JSONLayout 类没有这样的选项。 您提供了 Log4J 文档的链接,但问题是关于 Logback,而不是 Log4J。

以上是关于Logback JsonLayout 在同一行打印所有日志的主要内容,如果未能解决你的问题,请参考以下文章

Python print() 函数,在同一行打印

在同一行打印多个值

在同一行操场上打印字符 swift 3 [重复]

Lua 打印在同一行

如何在同一行打印2个项目[重复]

python 打印在同一行