19

I have this structure:

public class LogRequestParameters
{
    public string RequestID { get; set; }

    public string Type { get; set; }

    public string Level { get; set; }

    public string DateTime { get; set; }

    public string MachineName { get; set; }

    public Request Request { get; set; }
}

public class Request
{
    public string URLVerb { get; set; }
}

I am writing following line for logging:

Serilog.Log.Information("{@LogRequestParameters}", logRequestParameters);

I am getting following output:

LogRequestParameters { RequestID: "bf14ff78-d553-4749-b2ac-0e5c333e4fce", Type: "Request", Level: "Debug", DateTime: "9/28/2016 3:12:27 PM", MachineName: "DXBKUSHAL", Request: Request { URLVerb: "GET /Violation/UnpaidViolationsSummary" } }

This is not a valid json. "LogRequestParameters" (name of class) is coming in the begining. "Request" (name of the property) is coming twice. How can I log a valid json?

user1780538
  • 732
  • 1
  • 11
  • 19
  • I recommend [Json.NET](http://www.newtonsoft.com/json) from Newtonsoft. – ThePerplexedOne Sep 28 '16 at 13:50
  • Can you please provide sample code so that I can log the required json format. – user1780538 Sep 28 '16 at 13:54
  • 2
    With Json.NET you can serialize any instance of an object by using `var json = JsonConvert.Serialize(logRequestParameters);` – ThePerplexedOne Sep 28 '16 at 13:56
  • 1
    @ThePerplexedOne: You can't replace a logging framework with a serialization framework and if I'm not mistaken Serilog has a dependency on Json.NET anyway. – Martin Liversage Sep 28 '16 at 14:05
  • @ThePerplexedOne It means first I need to convert my object into json string and then log this json string. Then what is the point of using Serilog? I thought Serilog can log object in json format. – user1780538 Sep 28 '16 at 14:12
  • I don't even know what serilog is. Clearly it can't be that good if it doesn't serialize correctly. – ThePerplexedOne Sep 28 '16 at 14:13
  • 2
    Serilog is a logging framework that supports structured error logging. How that structure is persisted is dependent on the particular Sink being used. Could you show how you're initializing Serilog? It would help know which sink you're using. – PatrickSteele Sep 28 '16 at 16:51
  • 2
    @MartinLiversage no, Serilog doesn't use JSON.NET (it's 100% dependency-free, except for the base .NET Framework/Core packages :-)) – Nicholas Blumhardt Sep 28 '16 at 21:59
  • I have similar problem. I need to deserialize logs generated by serilog but it has invalid json format. Looks like it adds .net class name to logs (second Request in your example) – Jekyll Jul 01 '19 at 10:48

2 Answers2

10

Assuming you are using the file, rolling file or console sinks, you need to specify a JsonFormatter:

Log.Logger = new LoggerConfiguration()
    .WriteTo.RollingFile(new JsonFormatter(), "myapp-{Date}.json")
    .CreateLogger();

A few different JSON formats are supported by Serilog; see this post for discussion of some alternatives.

Nicholas Blumhardt
  • 25,642
  • 3
  • 71
  • 87
5

Make sure your Message template includes :lj format specifier at the end:

Log.Logger = new LoggerConfiguration()
    .WriteTo.Console(outputTemplate:
        "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}")
    .CreateLogger();

From documentation:

Message - The log event's message, rendered as plain text. The :l format specifier switches of quoting of strings, and :j uses JSON-style rendering for any embedded structured data.

On front docs page with JSON example there is no mention of it, took plenty of time for me to solve this problem too.

Jim Aho
  • 6,204
  • 8
  • 45
  • 72
Autiarii
  • 61
  • 1
  • 7