Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NLog: logging an object serialized to JSON

Tags:

json

.net

nlog

I have .Net project with NLog configuration which allows me to produce JSON-formatted log file. It works fine with simple text messages. Now, I need to log a number of arbitrary objects already serialized to JSON. When I log those JSON strings as log messages, NLog puts the text in quotes and subsequently escapes inner JSON syntax. This renders such output unusable. So far I have failed to find an NLog feature or layout setting that would simply dump my JSON string as a literal, without quotation marks and escape characters. Am I missing something?

Example. Currently my log entries look like:]

{ "dateTime": "2017-06-07 11:50:55.7324", "level": "DEBUG", "message": "\"description\": \"blah-blah\", \"Request\": { \"Request URL\":\/somepagepage\/}, \"Content\": { \"Form\": { ... } , \"Body\": \"Blah\" } ", "utcDateTime": "2017-06-05 06:10:34.1411" }

Instead, I need to make them to look like:

{ "dateTime": "2017-06-07 11:50:55.7324", "level": "DEBUG", "message":
 { "description": "blah-blah", "Request": { "Request URL":/somepagepage/, "Content": { "Form": {...}, "Body": "Blah" }  }, "utcDateTime": "2017-06-05 06:10:34.1411" }

Relevant section from NLog.config:

 <layout xsi:type="JsonLayout">
   <attribute name="dateTime" layout="${longdate}" />
   <attribute name="level" layout="${level:upperCase=true}"/>
   <attribute name="message" layout="${message}" /> 
   <attribute name="utcDateTime" layout="${longdate:universalTime=true}" />
 </layout>

Ultimately, I would like to see a log entry with JSON nested inside "message", and not a quoted version of it.

like image 664
Puzzled Avatar asked Jun 07 '17 08:06

Puzzled


2 Answers

As per @Rolf Kristensen's commentary above. Essentially, parameter encode="false" allows to log unquoted JSON:

  <attribute name="message" layout="${message}" encode="false" /> 

Plain text also comes out unquoted now, but this can be dealt with by a custom layout renderer that can tell plain text from JSON.

like image 153
Puzzled Avatar answered Nov 03 '22 14:11

Puzzled


Another way you can add json to your logging is to use the JsonLayout layout type and set includeAllProperties to true.

Your logger layout config should look like this:

<layout xsi:type="JsonLayout" includeAllProperties="true" maxRecursionLimit="4">
</layout>

And your logging code something like this:

ILogger Logger = LogManager.GetCurrentClassLogger();
MyClass request = new MyClass(){ThisProp = "foo", ThatProp = "bar"};

LogEventInfo e = new LogEventInfo(LogLevel.Info, "EmptyResponseLogger", "");
e.Properties["Request"] = request;

Logger.Log(e);

And you should end up with something like:

{ "time": "2019-02-05 19:12:10.1643", "logger": "MyClassLogger", "level": "INFO", "Request": {"ThisProp":"foo", "ThatProp": "bar"} }

Doing this will write out a JSON object on the 'Request' property of the log line and give you the response you are looking for. The maxRecursionLimit sets how far down the object tree

Json Layout Documentation

like image 3
3DPrintScanner Avatar answered Nov 03 '22 13:11

3DPrintScanner