Formatting Output

Adam Chester edited this page May 17, 2018 · 12 revisions

Serilog provides several output formatting mechanisms.

Formatting plain text

Sinks that write plain text output, such as the console and file-based sinks, generally accept output templates to control how log event data is formatted.

The format of events written by these sinks can be modified using the outputTemplate configuration parameter. For example, to control the console sink:

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

A number of built-in properties can appear in output templates:

  • Exception - The full exception message and stack trace, formatted across multiple lines. Empty if no exception is associated with the event.
  • Level - The log event level, formatted as the full level name. For more compact level names, use a format such as {Level:u3} or {Level:w3} for three-character upper- or lowercase level names, respectively.
  • 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.
  • NewLine - A property with the value of System.Environment.NewLine.
  • Properties - All event property values that don't appear elsewhere in the output. Use the :j format to use JSON rendering.
  • Timestamp - The event's timestamp, as a DateTimeOffset.

Properties from events, including those attached using enrichers, can also appear in the output template.

Formatting JSON

Many sinks record log events as JSON, or can be configured to do so. To emit JSON, rather than plain text, a formatter can be specified. This example configures the file sink using the formatter from Serilog.Formatting.Compact.

Log.Logger = new LoggerConfiguration()
    .WriteTo.File(new CompactJsonFormatter(), "log.txt")
    .CreateLogger();

There are three JSON formatters provided by the Serilog project:

  • Serilog.Formatting.Json.JsonFormatter - This is the historical default shipped in the Serilog package. It produces a complete rendering of the log event and supports a few configuration options.
  • Serilog.Formatting.Compact.CompactJsonFormatter - A newer, more space-efficient JSON formatter shipped in Serilog.Formatting.Compact.
  • Serilog.Formatting.Compact.RenderedCompactJsonFormatter - Also shipped in Serilog.Formatting.Compact, this formatter pre-renders message templates into text.

Custom JSON formatters can be built around the JsonValueFormatter class included in Serilog. For some details see this blog post.

Custom text formatters

Both plain text and JSON formatting are implemented using the ITextFormatter interface. Implementations of this interface can format log events into any text-based format.

Format providers

There are a number of options available to formatting the output of individual types like dates. One example is the use of the format provider that is accepted by most sinks.

Below is a simple console sample using the Serilog.Sinks.Console sink. This is using the default behavior for rendering a date.

class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime Created { get; set; }
}

public class Program
{
    public static void Main(string[] args)
    {
        Log.Logger = new LoggerConfiguration()
            .WriteTo.Console()
            .CreateLogger();

        var exampleUser = new User { Id = 1, Name = "Adam", Created = DateTime.Now };
        Log.Information("Created {@User} on {Created}", exampleUser, DateTime.Now);

        Log.CloseAndFlush();
    }
}

This writes the following output to the console.

[18:46:45 INF] Created {"Id": 1, "Name": "Adam", "Created": "2018-05-17T18:46:45.9064879+10:00", "$type": "User"} on 05/17/2018 18:46:45

There may be scenarios where it is desirable to override or specify the way a DateTime is formatted. This can be done via the implementation of IFormatProvider. This strategy applies to any type that you pass to Serilog.

class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime Created { get; set; }
}

class CustomDateFormatter : IFormatProvider
{
    readonly IFormatProvider basedOn;
    readonly string shortDatePattern;
    public CustomDateFormatter(string shortDatePattern, IFormatProvider basedOn)
    {
        this.shortDatePattern = shortDatePattern;
        this.basedOn = basedOn;
    }
    public object GetFormat(Type formatType)
    {
        if (formatType == typeof(DateTimeFormatInfo))
        {
            var basedOnFormatInfo = (DateTimeFormatInfo)basedOn.GetFormat(formatType);
            var dateFormatInfo = (DateTimeFormatInfo)basedOnFormatInfo.Clone();
            dateFormatInfo.ShortDatePattern = this.shortDatePattern;
            return dateFormatInfo;
        }
        return this.basedOn.GetFormat(formatType);
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        var formatter = new CustomDateFormatter("dd-MMM-yyyy", new CultureInfo("en-AU"));
        Log.Logger = new LoggerConfiguration() 
            .WriteTo.Console(formatProvider: new CultureInfo("en-AU")) //Console1
            .WriteTo.Console(formatProvider: formatter)                //Console2
            .CreateLogger();

        var exampleUser = new User { Id = 1, Name = "Adam", Created = DateTime.Now };
        Log.Information("Created {@User} on {Created}", exampleUser, DateTime.Now);

        Log.CloseAndFlush();
    }
}

The following is the output of the above example, with two consoles sinks configured.

Created User {Id=1, Name="Adam", Created=17/05/2018 7:08:44 PM} on 17/05/2018 7:08:44 PM // Console1
Created {"Id": 1, "Name": "Adam", "Created": "2018-05-17T19:08:44.0500574+10:00", "$type": "User"} on 17-May-2018 7:08:44 PM // Console2
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.