Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementation and usage of logger wrapper for Serilog

This question is related to Steven’s answer - here. He proposed a very good logger wrapper. I will paste his code below:

public interface ILogger
{
    void Log(LogEntry entry);
}

public static class LoggerExtensions
{
    public static void Log(this ILogger logger, string message)
    {
        logger.Log(new LogEntry(LoggingEventType.Information,
            message, null));
    }

    public static void Log(this ILogger logger, Exception exception)
    {
        logger.Log(new LogEntry(LoggingEventType.Error, 
            exception.Message, exception));
    }

    // More methods here.
}

So, my question is what is the proper way to create implementation that proxies to Serilog?

Note: this question is related to this question about log4net but now specific to Serilog.

like image 834
Steven Avatar asked Sep 14 '16 20:09

Steven


People also ask

What is Serilog logging?

Serilog is an easy-to-set-up logging library for . NET with a clear API. In the long list of the Serilog's features you can find: Support of structured logging, which allows logs to be treated as data sets rather than text. Compatibility with asynchronous applications and systems.

How do you use Serilog in middleware?

Use Serilog's request logging middleware in ASP.NET Core MVC In other words, you can take advantage of the request logging middleware to get a summary of all of the log messages for each request in your application. To add RequestLoggingMiddleware to the pipeline, you need to call the UseSerilogRequestLogging() method.

Does Serilog use ILogger?

But to my surprise, Serilog is using it's own ILogger interface - bummer!


1 Answers

So, my question is what is the proper way to create implementation that proxies to Serilog?

you should create something like:

public class SerilogAdapter : ILogger
{
    private readonly Serilog.ILogger m_Adaptee;

    public SerilogAdapter(Serilog.ILogger adaptee)
    {
        m_Adaptee = adaptee;
    }

    public void Log(LogEntry entry)
    {
        if (entry.Severity == LoggingEventType.Debug)
            m_Adaptee.Debug(entry.Exception, entry.Message);
        if (entry.Severity == LoggingEventType.Information)
            m_Adaptee.Information(entry.Exception, entry.Message);
        else if (entry.Severity == LoggingEventType.Warning)
            m_Adaptee.Warning(entry.Message, entry.Exception);
        else if (entry.Severity == LoggingEventType.Error)
            m_Adaptee.Error(entry.Message, entry.Exception);
        else
            m_Adaptee.Fatal(entry.Message, entry.Exception);
    }
}

Does that mean that every class that will log sth (so basically every), should have ILogger in its constructor?

As I understand from Stevens answer: Yes, you should do this.

what is the best way to use it later in the code?

If you are using a DI container, then just use the DI container to map ILogger to SerilogAdapter. You also need to register Serilog.ILogger, or just give an instance of Serilog logger to the DI container to inject it to the SerilogAdapter constructor.

If you don't use a DI container, i.e., you use Pure DI, then you do something like this:

Serilog.ILogger log = Serilog.Log.Logger.ForContext("MyClass");

ILogger logging_adapter = new SerilogAdapter(log);

var myobject = new MyClass(other_dependencies_here, logging_adapter);
like image 143
Steven Avatar answered Sep 18 '22 18:09

Steven