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.
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With