Note that there are some explanatory texts on larger screens.

plurals
  1. POJava: How to log raw JSON as JSON and avoid escaping during logging with logback / slf4j
    text
    copied!<p>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: </p> <p>At the moment it looks like this:</p> <pre><code>{"@timestamp":1363834123012,"@message":"{\"text\":\"From MLK to Barack Ob...\n\"}" </code></pre> <p>But I want to have this: </p> <pre><code> {"@timestamp":1363834123012,"@message": { "text ": "From MLK to Barack Ob...\n\} </code></pre> <p>The reason is I want to parse the JSON again and want to avoid the unescaping of the data. </p> <p>I've written a custom logback encoder but I found no way to avoid the escaping. Can I pass a object to logback and change the settings based on the type of the object? </p> <p>Edit: I've found a way - not exactly elegant - as requested a SSCE: </p> <p>In my Application</p> <pre><code>// SLF4J Logger private static Logger logger = LoggerFactory.getLogger(MyClass.class); // A logback? Marker private Marker foo = MarkerFactory.getMarker("foo"); // Jackson ObjectMapper() ObjectMapper mapper = new ObjectMapper(); // Log something... logger.info(foo, mapper.writeValueAsString(json)); </code></pre> <p>I've used a variation of the Logstash-Encoder found here: <a href="https://github.com/logstash/logstash-logback-encoder">https://github.com/logstash/logstash-logback-encoder</a></p> <pre><code>package my.package; import static org.apache.commons.io.IOUtils.*; import java.io.IOException; import java.util.Map; import java.util.Map.Entry; import org.codehaus.jackson.JsonGenerator.Feature; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.node.ObjectNode; import org.slf4j.Marker; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.classic.spi.IThrowableProxy; import ch.qos.logback.classic.spi.ThrowableProxyUtil; import ch.qos.logback.core.CoreConstants; import ch.qos.logback.core.encoder.EncoderBase; public class JsonEncoder extends EncoderBase&lt;ILoggingEvent&gt; { private static final ObjectMapper MAPPER = new ObjectMapper().configure( Feature.ESCAPE_NON_ASCII, true); private static Marker M; private boolean immediateFlush = true; @Override public void doEncode(ILoggingEvent event) throws IOException { M = event.getMarker(); ObjectNode eventNode = MAPPER.createObjectNode(); eventNode.put("@timestamp", event.getTimeStamp()); // if (M != null) { if (M.getName().equals("foo")) { JsonNode j = MAPPER.readTree(event.getFormattedMessage()); eventNode.put("@foo", j); } } else { eventNode.put("@message", event.getFormattedMessage()); } eventNode.put("@fields", createFields(event)); write(MAPPER.writeValueAsBytes(eventNode), outputStream); write(CoreConstants.LINE_SEPARATOR, outputStream); if (immediateFlush) { outputStream.flush(); } } private ObjectNode createFields(ILoggingEvent event) { // not important here return fieldsNode; } @Override public void close() throws IOException { write(LINE_SEPARATOR, outputStream); } public boolean isImmediateFlush() { return immediateFlush; } public void setImmediateFlush(boolean immediateFlush) { this.immediateFlush = immediateFlush; } } </code></pre> <p>It's works now! Yeah! But I guess it's not the best way to do it (serialize, deserialize the JSON...) </p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload