Java: How to log raw JSON as JSON and avoid escaping during logging with logback / slf4j

后端 未结 7 2175
攒了一身酷
攒了一身酷 2021-02-05 13:09

I\'m using SLF4J with Logback in a JAX-RS application... I want to log to JSON in such a way that my message is not encoded again but printed raw into the logfile:

At t

相关标签:
7条回答
  • 2021-02-05 13:35

    Use the RawJsonAppendingMarker:

    log.trace(net.logstash.logback.marker.Markers.appendRaw("jsonMessage", jsonString), null);
    
    0 讨论(0)
  • 2021-02-05 13:38

    I can't see the original code that's causing your problem, but I suspect it might look like this

    JsonNode logOutput;
    String messageJSONAsString;
    

    ...

    logOutput.put("@message", messageJSONAsString);
    logger.info(objectMapper.writeValueAsString(logOutput);
    

    This will produce escaped JSON in your output because when you put the message into the output JsonNode, Jackson will re-escape it for you to make sure the output is valid JSON.

    The solution here is to put the message in your output as an ObjectNode rather than as a string. Usually you already have access to the object as an Object, in which case you can do

    ObjectNode jsonObject = objectMapper.valueToTree(messageObject);
    logOutput.put("@message", jsonObject)
    

    Otherwise, if your message is a JSON string, then parse it and add it to the output

    logoutput.put("@message", objectMapper.readTree(messageJSONAsString));
    
    0 讨论(0)
  • 2021-02-05 13:39

    I ran into the same problem. I solved it with

    <encoder
     class="net.logstash.logback.encoder.LogstashEncoder">          
    </encoder
    

    instead of

    <encoder
     class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
    

    In my java code I used:

    SRV_PERF_LOGGER.info(net.logstash.logback.marker.Markers.appendRaw("message", jackson.writeValueAsString(dto)), null);
    
    0 讨论(0)
  • 2021-02-05 13:40

    here is an updated (2016) groovy logback config that dumps out your logs in json format to a file, and debug lines in the console. Took me all day to figure out so i thought i'd update the thread.

        import ch.qos.logback.classic.encoder.PatternLayoutEncoder
    import ch.qos.logback.core.ConsoleAppender
    import ch.qos.logback.core.rolling.FixedWindowRollingPolicy
    import ch.qos.logback.core.rolling.RollingFileAppender
    import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy
    import net.logstash.logback.encoder.LogstashEncoder
    
    import static ch.qos.logback.classic.Level.INFO
    import static ch.qos.logback.classic.Level.WARN
    
    def PROJECT_ID = "com.foo"
    
        appender("file", RollingFileAppender) {
            file = "/tmp/logs/${PROJECT_ID}.json"
            encoder(LogstashEncoder)
            rollingPolicy(FixedWindowRollingPolicy) {
                maxIndex = 1
                fileNamePattern = "logs/${PROJECT_ID}.json.%i"
            }
            triggeringPolicy(SizeBasedTriggeringPolicy) {
                maxFileSize = "1MB"
            }
        }
    
    
        appender("STDOUT", ConsoleAppender) {
            encoder(PatternLayoutEncoder) {
                pattern = "%d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n"
            }
        }
    
        logger("com.foo", INFO, ["STDOUT", "file"], false)
    
        root(WARN, ["STDOUT", "file"])
    
    0 讨论(0)
  • 2021-02-05 13:54

    If you have a Json formatted messages, the upper solutions work, but are not so nice, since you don´t want to call a logstash specific code, each time you use your logger in the code.

    Just adding a

    net.logstash.logback.encoder.LogstashEncoder
    

    is not enough, since the message itsself stays escaped. To solve this, try the following in your logback.xml:

    <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
         <providers>
            <timestamp/>
            <version/>
            <loggerName/>
            <pattern>
                <pattern>
                    {
                    "jsonMessage": "#asJson{%message}"
                    }
                </pattern>
            </pattern>
        </providers>
    </encoder>
    

    The #asJson pattern will unescape your message.

    0 讨论(0)
  • 2021-02-05 13:57

    Logback doesn't do anything unusual with JSON. It's just a string that gets logged as normal. The escaping is probably happening on your end, unless you're talking about some kind of JSON Appender that's writing it out in that format. I'm pretty sure Logback itself doesn't have anything like that, so you'd want to look at wherever you got the Appender from instead if that's your problem. An SSCCE would help with further troubleshooting.

    0 讨论(0)
提交回复
热议问题