Anoop
Anoop

Reputation: 903

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.

Upvotes: 37

Views: 30183

Answers (6)

Paramesh Korrakuti
Paramesh Korrakuti

Reputation: 2067

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>

Upvotes: 4

Santhosh V
Santhosh V

Reputation: 85

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>

Upvotes: 7

mvmn
mvmn

Reputation: 4047

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>

Upvotes: 76

Paul Cunningham
Paul Cunningham

Reputation: 91

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

Upvotes: 1

Anoop
Anoop

Reputation: 903

I switched to using logstah-logback-encoder which did not have the issue as JSONLayout.

Upvotes: 2

Sagar
Sagar

Reputation: 838

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>

Upvotes: -3

Related Questions