Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Log the type used with the generic ILogger<T> via Serilog

Tags:

c#

.net

serilog

I am currently using this output template with Serilog:

"outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] [{MachineName}] {Message:lj}{NewLine}{Exception}"

I would like to add the class that I specify when declaring the Microsoft.Extensions.Logging.ILogger logger that I inject, i.e. if I declare ILogger<MyType> then I would like to output MyType via the template.

I know I can add the whole context but I read that this comes with a performance penalty, so currently I add the class by adding nameof(MyType) to each message - which is a mess.

Is there an enricher or something similar that will make the type available in the template (or just prefix each log message with the type)?

Edit:

There isn't much code really, this is how I configure Serilog with the dotnet-core WebApi:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseStartup<Startup>();
    })
    .UseWindowsService()
    .UseSerilog();

And this is an example of how I use the logger via IOC:

private readonly ILogger<MyType> _logger;

public MyType(ILogger<MyType> logger)
{
    _logger = logger ?? throw new ArgumentNullException(nameof(logger));
}

public void HelloLog()
{
   _logger.LogInformation("hello");
}

// expected log output: "[MyType] hello"

I understand from Andy's comment that I could write a LoggingProvider and pass it in the UseSerilog overload that takes a collection of providers. That is something I will look into if nothing easier turns up.

like image 484
TvdH Avatar asked Aug 31 '20 14:08

TvdH


People also ask

Does Serilog use ILogger?

NET 6 as a logging provider. Let's set up Serilog as Logging Provider in the native logging system in . NET so you can use the Microsoft ILogger interface.

What is Serilog extensions logging?

NET, Serilog provides diagnostic logging to files, the console, and elsewhere. It is easy to set up, has a clean API, and is portable between recent . NET platforms. Unlike other logging libraries, Serilog is built with powerful structured event data in mind.

What is the difference between ILogger and ILogger T?

ILogger<T> is derived from ILogger and adds no new functionality. If you're using dependency injection, an instance of ILogger<T> is usually injected into your type T . So, each time you have a constructor that takes an ILogger<T> , you are defining a “component” for your application.

What is ILogger used for?

ILoggerFactory is a factory interface that we can use to create instances of the ILogger type and register logging providers. It acts as a wrapper for all the logger providers registered to it and a logger it creates can write to all the logger providers at once.


1 Answers

The type name should be added into the SourceContext property of any log events emitted by the ILogger<T>, exactly as if you'd used the ForContext<T>() or ForContext(type) methods on a Serilog.ILogger. Using {SourceContext} somewhere in your message template should allow you to add just the source name, e.g.

"[{Timestamp:HH:mm:ss} {Level:u3}] [{MachineName}] [{SourceContext}] {Message:lj}{NewLine}{Exception}"

Note that this will output the full name of the type, so will include the namespace.

like image 159
rob.earwaker Avatar answered Oct 22 '22 08:10

rob.earwaker