API Logging in Json format -
i log api request/response json format.
the expected logentry
{ "timestamp" : "...", "level" : "debug", "headers" : [ "header1" : "value1", "header2" : "value2", "header3" : "value3" ], "requestpayload" : "<request json>" // prefereablly sub-document, worst case string fine. "labels" : [ //key fields can used searching logentry "searchfield1" : "....", "searchfield2" : "....", "searchfield3" : "...." ] }
my question :
using logback, how log nested fields (e.g. headers, labels, requestpaylod in above example), json sub-document. tried mdc, limited map of 'string, string' only, , considers fields after first level string.
i hate write custom logger this, , use goodness of proven logging frameworks(logback/log4j) control logging level, time stamping log event, etc.
you can use logback-contrib's jsonlayout
inside logback appender. example:
<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>false</prettyprint> </jsonformatter> <timestampformat>yyyy-mm-dd' 'hh:mm:ss.sss</timestampformat> <appendlineseparator>true</appendlineseparator> </layout> </appender>
given log statements ...
mdc.put("header1", "headervalue1"); logger.info("hello!"); logger.info("good bye!");
... use of jsonlayout
result in logback writing this:
{"timestamp":"2017-08-15 09:06:41.813","level":"info","thread":"main","mdc":{"header1":"headervalue1"},"logger":"com.stackoverflow.logback.logbacktest","message":"hello!","context":"default"} {"timestamp":"2017-08-15 09:06:41.887","level":"info","thread":"main","mdc":{"header1":"headervalue1"},"logger":"com.stackoverflow.logback.logbacktest","message":"good bye!","context":"default"}
i think ticks boxes of writing log events json documents whilst still retaining logback's behaviour such "control logging level, time stamping log event, etc". there built-in support changing json format (e.g. can include/exclude context, logger name etc) jsonlayout class provides extension point allow change attribute names in resulting json extending jsonlayout
, overriding tojsonmap()
.
edit 1: addressing reply ("my question more on how achieve json subdocument/nesting mentioned. mdc limited map of only") ... could serialise complex mdc values json , add serialised json representations mdc. example:
map<string, object> complexmdcvalue = new hashmap<>(); map<string, object> childmdcvalue = new hashmap<>(); childmdcvalue.put("name", "joe"); childmdcvalue.put("type", "martian"); complexmdcvalue.put("child", childmdcvalue); complexmdcvalue.put("category", "etc"); mdc.put("complexnestedvalue", objectmapper.writevalueasstring(complexmdcvalue)); logger.info("hello!");
would produce output (in mvc logged key "complexnestedvalue" is json containing sub document):
{"timestamp":"2017-08-27 18:03:46.706","level":"info","thread":"main","mdc":{"complexnestedvalue":"{\"category\":\"etc\",\"child\":{\"name\":\"joe\",\"type\":\"martian\"}}"},"logger":"com.stackoverflow.logback.logbacktest","message":"hello!","context":"default"}
Comments
Post a Comment