简体   繁体   中英

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.

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.

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>();

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://docs.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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM