简体   繁体   中英

Logback JsonLayout printing all logs on the same line

I am using JsonLayout with Spring Boot to log messages in JSON format. I only want the log messages to be logged to the console and not to a log file.

I notice that the JSON logs are logged continuously on the same line. On production this would be alright, since we would be shipping the logs to a log aggregator. But this becomes a bit difficult to analyze on local development.

Logs

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

Below is the logback configuration
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>

Am I missing something in the configuration so that they are logged on separate lines on the console.

Thanks for any help on this.

You need to set appendLineSeparator option to true for ch.qos.logback.contrib.json.classic.JsonLayout . Example of this:

<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>

Setting prettyPrint true is one solution. But there are cases where we need logs in single line like for sreaming to services like cloud watch. Add following in layout

<appendLineSeparator>true</appendLineSeparator>

The above answer from @mvnm worked fine for me. Just in case, if required pretty print and new line separator, can use the following configuration.

<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>

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

Pipe the output of your Spring Boot application (or JSON log files) to jq using something like this:

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

This will provide nice, color-highlighted, pretty-printed json that follows the output of your application. Anything output by your application that isn't JSON will be ignored (for example: the Spring Boot banner).

You can use filters in jq to display only the INFO level message output:

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

Or you can use filters to remove keys you don't want to see:

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

Editted : Try changing the prettyPrint to true -> <prettyPrint>true</prettyPrint>

You re writing the logs twice in the consoleAppender

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

change to

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM