Reputation: 213
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.
Upvotes: 7
Views: 9095
Reputation: 1014
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
Upvotes: 3
Reputation: 213
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.
Upvotes: 6