Gaz83
Gaz83

Reputation: 2865

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.

Upvotes: 21

Views: 31505

Answers (3)

user13499502
user13499502

Reputation: 131

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.

Upvotes: 11

live2
live2

Reputation: 4265

I needed a logger in my .net core console application to log into a file. This is my solution...

PM> install-package Serilog.Extensions.Hosting
PM> install-package Serilog.Sinks.File
//Serilog configuration
var serilogLogger = new LoggerConfiguration()
    .MinimumLevel.Verbose()
    .WriteTo.File("log.txt", rollingInterval: RollingInterval.Day)
    .CreateLogger();

//Create a logger factory
var loggerFactory = new LoggerFactory().AddSerilog(serilogLogger);

//Get a logger
var logger = loggerFactory.CreateLogger<MyService>();

Upvotes: 11

Euphoric
Euphoric

Reputation: 12849

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.

Upvotes: 27

Related Questions