Click here to Skip to main content
12,762,516 members (36,376 online)
Click here to Skip to main content
Add your own
alternative version

Stats

21.8K views
377 downloads
44 bookmarked
Posted 20 Oct 2015

Serilog - An Excellent Logging Framework Integrated With .NET Applications

, 20 Oct 2015 CPOL
Rate this:
Please Sign up or sign in to vote.
Serilog is a portable and structured logging framework to record diagnostic logs into files, console and SQL/NoSQL databases.

Introduction

Logging is an approach to record information about a program's execution for debugging and tracing purposes. Logging usually involves writing text messages to log files or sending data to monitoring applications. The logged information gives you a good understanding about processed data, warnings, errors and more. In practice, logging enables developers and testers to identify software problems, monitor live systems and verify outputs.

In .NET platform, there are multiple matured logging frameworks such as:

They are designed for simplifying developers' work regarding processing logs. All the logging frameworks work basically the same: you include one of the libraries into your programs and add logging statements to your code. If you start your application and logging is enabled, logging information is sent to the configured logging destination like a log file, console or database.

Serilog is an excellent logging framework and has been active for years. Unlike other logging libraries for .NET, Serilog is built with structured log data in mind. This framework is built around the idea that log messages should be more than a collection of strings. Log messages are preserved as structured data(JSON) that can be written in document form to a variety of output providers.

Structure of serilog

Features

  • Simple API and easy to extend
  • Structured data to preserve your data’s semantics
  • Log to any a variety of targets

Overview

Before we get started, let's have a quick overview at how easy it is to apply Serilog into your project. Please see the below examples:

  1. Basic logger:
    using Serilog;
    
    namespace SerilogTutorial
    {
        public class HelloSerilog
        {
            public static void Main(string[] args)
            {
                // Create Logger
                var logger = new LoggerConfiguration()
                        .WriteTo.Console()
                        .CreateLogger();
                // Output logs
                logger.Information("Hello, Serilog!");
            }
        }
    }

    This example writes a line like the following to Console.

    2015-10-19 15:39:06 [Information] Hello, Serilog!
  2. Pass parameters to loggers:
    // Create Logger
    var logger = new LoggerConfiguration()
        .WriteTo.Console()
        .CreateLogger();
    // write structured data
    logger.Information("Processed {Number} records in {Time} ms", 500, 120);

    It writes a line as follows:

    2015-10-19 22:24:09 [Information] Processed 500 records in 120 ms
  3. Create Template loggers:
    // Create Logger
    var logger = new LoggerConfiguration()
        .WriteTo.Console()
        .CreateLogger();
    // prepare data
    var order = new {Id = 12, Total = 128.50, CustomerId = 72};
    var customer = new {Id = 72, Name = "John Smith"};
    // write log message
    logger.Information("New orders {OrderId} by {Customer}", order.Id, customer);

    It prints logs as follows:

    2015-10-19 22:32:43 [Information] New orders 12 by "{ Id = 72, Name = John Smith }"

As we can see, the power of Serilog is it supports process message parameters and structured data. While traditional logging libraries render messages into strings, Serilog defers rendering and captures the parameters separately from the message template.

Using the Code

Now let's go deep into how to apply Serilog into your projects. Here are the basic steps:

  • Preparation
  • Install serilog
  • Create a logger
    • Configure logger
    • Add sinks
  • Write log messages
  • Customize logger
    • Define log output template
    • Specify minimal level
    • Install database sink

Preparation

Of course, you need to have Visual Studio installed and have a project ready. For simplify purpose, you just need to create a console application.

Install serilog

Typically, there are two ways to install nuget packages.

Way 1 - via Nuget Package Manager

Right click your project > Manage nuget packages > search serilog

Way 2 - via Project Manager Console

Goto Menu > Tools > NuGet PackageManager > Project Manager Console
PM> Install-Package Serilog

Create a Logger

Logger is the fundamental of writing logs and it is used to output log messages. To create a logger, you need to specify two settings.

Configure Logger

You need to create a LoggerConfiguration object

Add Sinks

Sink is a place or destination to process logs. Sink could be console, file or data store. Sink is configured using WriteTo() method.

Now, you can build a logger to write events to Console:

var logger = = new LoggerConfiguration()
    .WriteTo.ColoredConsole()
    .CreateLogger();

Multiple additional sinks can be added through chaining WriteTo methods:

var logger = new LoggerConfiguration()
    .WriteTo.ColoredConsole()
    .WriteTo.RollingFile(@"C:\Log-{Date}.txt")
    .CreateLogger();

Write Log Messages

Now the logger is ready to use. You can simply write logs as follows:

log.Debug("Debugging message");
log.Information("Information message");
log.Warning("Warning message");
log.Error("Error message");
log.Fatal("Fatal message");

Customize Logger

In order to modify logger to fit your needs, you need to tune the logger.

Define Log Output Template

Log message template controls how the sink renders events. Message templates are a superset of standard .NET format strings and compatible with string.Format() method. Moreover, it supports JSON objects or regular C# objects(with @ symbol) as parameters.

var position = new { Latitude = 25, Longitude = 134 };
var elapsedMs = 34;
log.Information("Processed {@Position} in {Elapsed} ms.", position, elapsedMs);

It prints logs like the following:

09:14:22 [Information] Processed { Latitude: 25, Longitude: 134 } in 34 ms.

Specify Minimal Level

There are five levels of logs:

LevelUsage
VerboseTracing information and debugging minutiae; generally only switched on in unusual situations
DebugInternal control flow and diagnostic state dumps to facilitate pinpointing of recognized problems
InformationEvents of interest or that have relevance to outside observers; the default enabled minimum logging level
WarningIndicators of possible issues or service/functionality degradation
ErrorIndicating a failure within the application or connected system
FatalCritical errors causing complete failure of the application

Serilog writes the logs with minimal level as well as higher and ignore lower levels. For instance, specify minimal level as Debug will output logs except Verbose.

var logger = new LoggerConfiguration()
         .MinimumLevel.Debug()
         .WriteTo.ColoredConsole()
         .CreateLogger();

You can also override minimal level. For instance, we want to display all logs higher than Debug in the console but save all error logs to databases. In order to meet this requirement, you can specify global level as Debug and set database sink with Warning level.

var logger = new LoggerConfiguration()
         .MinimumLevel.Debug()
    .WriteTo.ColoredConsole()
    .WriteTo.MongoDB("mongo://myserver/logs", minimumLevel: LogEventLevel.Warning)
    .CreateLogger();
logger.Information("I am an information log"); // will print in console
log.Error("I am an error log");// will print in console and also store in database

Write error-level logs events to File:

var logger = new LoggerConfiguration()
    .WriteTo.File("log.txt", LogEventLevel.Error)
    .CreateLogger();
logger.Information("I am an information log"); // will not in log file
logger.Error("I am an error log"); // will write to log file

If no MinimumLevel is specified, Serilog will use Information level events as default - Information and higher levels will be processed. 

Install Database Sink

Serilog supports build-in sinks include Console, File (single/rolling) and TextWriter. In order to enable serilog export logs to different destinations, additional sinks need to be installed.

A typical case is to write logs to database, you need to install additional sinks. For instance, using SQL Server database as destination needs to install SQL Server sink.

PM> Install-Package Serilog.Sinks.MSSqlServer

Create database LogEvents and table Logs using SQL script:

if not exists(select * from sys.databases where name='LogEvents')
         create database LogEvents;
Go
Use LogEvents;
Go
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [Logs](
         [Id] [int] IDENTITY(1,1) NOT NULL,
         [Message] [nvarchar](max) NULL,
         [MessageTemplate] [nvarchar](max) NULL,
         [Level] [nvarchar](128) NULL,
         [TimeStamp] [datetime] NOT NULL,
         [Exception] [nvarchar](max) NULL,
         [Properties] [xml] NULL,
 CONSTRAINT [PK_Logs] PRIMARY KEY CLUSTERED
(
         [Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, _
	ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]) ON [PRIMARY]
GO

The script will create LogEvents database and Logs table:

Write to SQL Server database sink:

var logger = new LoggerConfiguration()
        .WriteTo.MSSqlServer(@"Server=.;Database=LogEvents;
        	Trusted_Connection=True;", "Logs")
        .CreateLogger();
logger.Information("I am an information log");
logger.Error("Hello, I am an error log");

You will get:

More

This article only covers essential conceptions of Serilog. More advanced features can be available here. Advance topics include:

  • Add dynamic properties through Enrichers
  • Add log filters to filter out noisy events and select particular logs
  • Add sub loggers to process complex logging requirements
  • More sinks such as MongoDB, Seq, RavenDB, Email and Azure DocumentDB. The complete list can be found here.

History

  • October 20, 2015: First version posted
  • October 20, 2015: Fix format

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Andy Feng
Software Developer
Canada Canada
Andy Feng is a software analyst/developer based in Toronto, Canada. He has 9+ years experience in software design and development. He specializes in Java/J2EE and .Net solutions, focusing on Spring, Hibernate, JavaFX, ASP.NET MVC, Entity framework, Web services, JQuery, SQL and related technologies.

Follow up with my blogs at: http://andyfengc.github.io/

You may also be interested in...

Pro
Pro

Comments and Discussions

 
QuestionThread safety question Pin
Tachyonx21-Oct-15 0:26
memberTachyonx21-Oct-15 0:26 
AnswerRe: Thread safety question Pin
Andy Feng21-Oct-15 4:51
memberAndy Feng21-Oct-15 4:51 
GeneralRe: Thread safety question Pin
Tachyonx22-Oct-15 5:47
memberTachyonx22-Oct-15 5:47 
Generalit might... Pin
John Torjo20-Oct-15 10:43
professionalJohn Torjo20-Oct-15 10:43 
GeneralRe: it might... Pin
Andy Feng20-Oct-15 11:13
memberAndy Feng20-Oct-15 11:13 
GeneralRe: it might... Pin
John Torjo20-Oct-15 11:40
professionalJohn Torjo20-Oct-15 11:40 
GeneralRe: it might... Pin
Andy Feng20-Oct-15 12:30
memberAndy Feng20-Oct-15 12:30 
GeneralRe: it might... Pin
John Torjo21-Oct-15 0:27
professionalJohn Torjo21-Oct-15 0:27 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170217.1 | Last Updated 20 Oct 2015
Article Copyright 2015 by Andy Feng
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid