Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correctly Injecting Serilog into .net core classes as Microsoft.Extentions.Logging.ILogger - Not ASP .Net Core

So I have a .Net Core Console application and a bunch of .Net core Libraries.

Most of the classes in the libraries have constructors like this.

public class ReportingManager
{
   private ILogger _logger;
   Public ReportingManager(ILogger logger)
   {
      _logger = logger;
   }
}

with ILogger being of type Microsoft.Extentions.Logging.ILogger

In my Console app I have this.

class Program
{
    static void Main(string[] args)
    {           
            var serilog = new LoggerConfiguration()
                .MinimumLevel.Debug()
                .MinimumLevel.Override("Microsoft", Serilog.Events.LogEventLevel.Warning)
                .Enrich.FromLogContext()
                .WriteTo.Console(theme: AnsiConsoleTheme.Code)
                .CreateLogger();

            ReportingManager manager = new ReportingManager(serilog);

    }
}

I have an intellisense error at 'ReportingManager manager = new ReportingManager(serilog);'

cannot convert from 'Serilog.Core.Logger' to 'Microsoft.Extensions.Logging.ILogger'

So my question is, how do I pass in Serilog correctly?

Had a look online and here but most talk about ASP.Net Core.

like image 647
Gaz83 Avatar asked Sep 13 '25 15:09

Gaz83


2 Answers

You need to wrap the Serilog logger into Microsoft.Extensions.Logging.LoggerFactory. This is exactly what happens when same is used in DI in ASP.NET.

Like this :

Serilog.Core.Logger serilog = ...;

var loggerFactory = new LoggerFactory()
    .AddSerilog(serilog);

Microsoft.Extensions.Logging.ILogger logger = loggerFactory.CreateLogger("Logger");

This needs Serilog.Extensions.Logging NuGet package.

like image 118
Euphoric Avatar answered Sep 15 '25 05:09

Euphoric


To provide more of a complete and up-to-date answer on this using DI, this is how to use the .Net ILogger interface with with Serilog. This is for a WPF/Console application

.Net 6 ILogger Update - As stated by Microsoft

Starting with .NET 6, logging services no longer register the ILogger type. When using a logger, specify the generic-type alternative ILogger or register the ILogger with dependency injection (DI).

You must now use ILogger for logging to work, T being category name. https://learn.microsoft.com/en-us/dotnet/core/extensions/logging?tabs=command-line

Packages

These following packages are required to work with Serilog and .Net 6 Logging (The configuration are optional, if you plan to use Code Configuration, for this I use appsettings.json as configuration)

Install-Package Serilog
Install-Package Serilog.Sinks.File
Install-Package Serilog.Extensions.Logging
Install-Package Serilog.Settings.Configuration 
Install-Package Microsoft.Extensions.Logging
Install-Package Microsoft.Extensions.Logging.Configuration

Optional Packages (For Formatting to JSON)

Install-Package Serilog.Formatting.Compact

In App.cs Add Configuration

  var builder = new ConfigurationBuilder();
    builder.SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json");

    Configuration = builder.Build();

add an appsettings.json file to root of application (Ensure copy to output directory)

{
  "Serilog": {
    "WriteTo": [
      {
        "Name": "File",
        "Args": {
          "path": "log.json",
          "rollingInterval": "Day",
          "MinimumLevel": "Information",
          "formatter": "Serilog.Formatting.Compact.CompactJsonFormatter, Serilog.Formatting.Compact"
        }
      }
    ]
  }
}

For the path Serilog supports windows environment variables, so you can do %localappdata%\log\ to store in use application data etc, more information on that is here: https://github.com/serilog/serilog-settings-appsettings

The formatter is optional, it can be removed and you can log as text only, "rollingInterval" can be day, month, year. There are lots of other configurations which are acceptable, more on these are available here:

https://github.com/serilog/serilog-settings-appsettings

Add the logger

   var seriLog = new LoggerConfiguration()
                      .ReadFrom.Configuration(Configuration)                  
                      .CreateLogger();
    
                ILoggerFactory logger = LoggerFactory.Create(logging =>
                {
                    logging.AddSerilog(seriLog);
    
                });
 ILogger<T> myLogger = logger.CreateLogger<T>();

If you're using DI you need to register this logger like so

 services.AddSingleton(myLogger);  

You can now use the Microsoft ILogger interface in your application classes (passing ILogger as parameter constructor, if constructor injection) and Serilog will be the underlying logging provider.

like image 40
user13499502 Avatar answered Sep 15 '25 07:09

user13499502