Logging is an important part of every software project. Ideally, developers would prefer to attach a debugger to the failing system and investigate it in-situ. In real life, however, systems are rarely available to the developers in the moment the issue is happening. And this is the reason we are heavily rely on logs, which can be analyzed later.

One of the most popular logging library for the .NET applications is log4net. It is a powerful, flexible library and the usual workflow looks like this: a developer needs to log an object state and some action, so he creates a human-readable string which represents the state and the action. The string is passed to log4net and stored in a text file. With the amount of logging data generated by the modern software, it very desirable to be able to process the logs automatically, by some software tool. I this case stored text file will be parsed to extract the object state and analyze it.

When we taking into account the second part of the workflow (parsing and analyzing), it sounds crazy. Nicely structured data available before logging is transformed to unstructured text only to parse and to transform to the structured state a bit late. What a waste of CPU cycles and time!

Serilog, a structured logging library, aims to stop this craziness. With Serilog, data can be logged in an original form and passed to the structured storage (database, Windows Event Log, third-party service) without an additional overhead.

var user = new User {Name="Guest", Ip="127.0.0.1"};
logger.Information("User {@User} logged", user);

If Serilog is configured to output data to console, the logged information will be present as

08:43:12 [Information] User {Name: Guest, Ip: 127.0.0.1} logged

And for other sinks (like Event Log) it will be captured as JSON

{ "User": {"Name": "Guest", "Ip": "127.0.0.1"}}

Serilog supports more than 50 sink, including console, text files, Email, Elasticsearch, RethinkDB and others. Logging sinks are configured for each logger and more than one sink can be used:

var logger = new LoggerConfiguration()
    .MinimumLevel.Debug()
    .WriteTo.RollingFile("log-{Date}.txt")
    .WriteTo.LiterateConsole()
    .CreateLogger(););

Serilog allow to enrich logging data with some static information (like thread id), define custom serializers and filters, for selective logging.

Serilog is published under Apache 2.0 license at https://github.com/serilog

blog comments powered by Disqus