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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With