I've just started using serilog and have set up my logging the following way.
public static Serilog.LoggerConfiguration DefaultConfiguration = new LoggerConfiguration()
.WriteTo
.Console(formatProvider: CultureInfo.InvariantCulture, outputTemplate: DefaultConsoleTemplate)
.WriteTo.Sink(new FileSink(Logfile, new JsonFormatter(), null));
Now in the sink file I notice that a log entry is not really JSON. Each property is destructured or stringified and stored as a string within the properties structure of the log entry which means when de-serializing the log for analysis
So contrary to your homepage example I find the storage is not
{ "SensorInput": { "Latitude": 25, "Longitude": 134 },
"Elapsed": 34 }
but
{ "SensorInput": "{ \"Latitude\": 25, \"Longitude\": 134 }",
"Elapsed": 34 }
Why is destructured data stored as a stringified JSON and not as JSON?
I notice that this is a design decision. LogEventPropertyValue is designed to convert a property to a string rather than output to a JSON writer.
I'm using the JSON.Net library for general JSON serialization and they have the class JsonWriter
If Serilog was based on
JSON.NET then you could redefine LogEventPropertyValue simply as
public abstract class LogEventPropertyValue : IFormattable
public abstract void Render(JsonWriter output);
and then the log entry could be JSON all the way down. As well you could take advantage of the superior JSON.Net serialization capability. I annotate all my serializable classes using [DataContract] and [DataMember] attributes which serilog doesn't recognise. I've worked around this by creating my own destructuring policy
public class JSonNetDestructuringPolicy : IDestructuringPolicy
public class JsonNetLogEventPropertyValue : LogEventPropertyValue
private readonly object _Data;
public JsonNetLogEventPropertyValue(object data)
public override void Render
IFormatProvider formatProvider = null)
// ToJson is an extension method to serialize to string
// using the NewtonSoft JSON.Net library
output.Write(_Data.ToJson(Json.NonIndentedSettings));
public bool TryDestructure
ILogEventPropertyValueFactory propertyValueFactory,
out LogEventPropertyValue result)
result = new JsonNetLogEventPropertyValue(value);
but because I have to render to a string (TextWriter) I get the effect that I get individual blobs of stringified json in the log.
Am I missing something here or doing something wrong?
Thanks for the library. The idea of structured logging was just what I was looking for.
Regards
Brad