15

All the examples I can find about using Serilog in an ASP .NET Core Web Application use Microsoft's ILogger<T> interface instead of using Serilog's ILogger interface.

How do I make it so that Serilog's ILogger can be injected via constructor, instead?

using Serilog;

public class HomeController : Controller
{
    ILogger logger;

    public HomeController(ILogger logger)
    {
        this.logger = logger;
    }

    public IActionResult Index()
    {
        this.logger.Information("Index was called");
        return View();
    }
}
Lindsey1986
  • 381
  • 1
  • 3
  • 15
  • 4
    You need to conficure ASP.NET Core to use Serilog as a provider, not inject Serilog's logger. If you google for `Serilog ASP.NET Core` the first result is the [Serilog ASP.NET Core](https://github.com/serilog/serilog-aspnetcore) package that does just that – Panagiotis Kanavos Jul 30 '19 at 13:19
  • 1
    Seconding that, the idea is that you don't want to be come coupled to Serilog. If you inject Microsoft.Extensions.Logging.ILogger, there are adapters from that to all sorts of loggers. But if you inject Serilog everywhere and then you want something else it's more work. – Scott Hannen Jul 30 '19 at 13:36
  • Thanks @PanagiotisKanavos. I know how to configure Serilog as a provider. I'm asking how I can inject Serilog's ILogger interface instead of Microsoft's one – Lindsey1986 Jul 30 '19 at 13:59
  • 1
    Thanks @ScottHannen. Are you sure about that though? I mean, Serilog has Sinks to all kinds of loggers... I don't see any difference of being coupled to Serilog, or coupled to Microsoft's logger, other than personal preference - what am I missing? – Lindsey1986 Jul 30 '19 at 14:01
  • 2
    You're right. It really is preference. I would tend to go as "generic" as possible. – Scott Hannen Jul 30 '19 at 14:06
  • @Lindsey1986 why do you want to inject Serilog's ILogger in the first place? Why not integrate it and have all log events go through Serilog? All the sinks are specified during configuration. Serilog's ILogger knows nothing about them – Panagiotis Kanavos Jul 30 '19 at 14:18
  • @PanagiotisKanavos I'm migrating a codebase from ASP .NET MVC to ASP .NET Core, and our team is used to (and prefers) Serilog's method names. e.g. `log.Information(...)` instead of Microsoft's `log.LogInformation(...)` – Lindsey1986 Jul 30 '19 at 14:21
  • ASP.NET Core's logging infrastructure is *not* a separate logger. It's a logging abstraction that eventually calls the configured logging providers like Serilog. There's a huge difference between using it and injecting Serilog everywhere - you'd still have to use and configure the Microsoft.Extensions.Logging middleware because all components and third-party extensions expect it to be there. You'd end up with two separate log files, two separate emailers etc. – Panagiotis Kanavos Jul 30 '19 at 14:21
  • @Lindsey1986 that's the *smallest* of the differences they'll have to deal with and frankly, not really worth wasting time on. Using configuration and DI correctly for example, is a lot more important - ASP.NET MVC had nothing similar. If you need the old names create a couple of extension methods with the same signature eg `Information(this ILogger logger,...)=>logger.LogInformation(...)`. Again though, everyone else will be using the `ILogger` methods, leading to confusion – Panagiotis Kanavos Jul 30 '19 at 14:22
  • 1
    Another viewpoint, maybe biased - in our apps, we use Serilog's logging interfaces exclusively (and the static `Log` class to avoid polluting constructors with irrelevant details); we hook up Serilog to MEL, but only third-party components/the framework use it, so we never see the MEL interfaces. Works nicely for us. – Nicholas Blumhardt Jul 30 '19 at 21:05

2 Answers2

14

If you prefer ILogger instead of ILogger<HomeController>, you could try to register ILogger.

Here are two options to use Serialog.Information.

  1. Use Log.Logger

    Log.Logger.Information("Information Log from Log.Logger");
    
  2. Register ILogger

    //Startup.cs
    services.AddSingleton(Log.Logger);
    
    //Use
    public class HomeController : Controller
    {
        private readonly ILogger _logger;
        public HomeController(ILogger logger)
        {
            _logger = logger;
        }
        public IActionResult Index()
        {
            _logger.Information("Inform ILog from ILogger");
            return View();
        }        
    }
    
Edward
  • 28,296
  • 11
  • 76
  • 121
7

You can install Serilog as the logger under the Microsoft logging framework by including the Serilog.Extensions.Logging package and including the following in your app startup:-

public void ConfigureServices(IServiceCollection services)
{
    services.AddLogging(x =>
    {
        x.ClearProviders();
        x.AddSerilog(dispose: true);
    });

    ...

Or, as an alternative to injecting, if you just want a reference to the Serilog logger, Serilog.Log has a static method Log to create a logger...

...
using Serilog;
...

namespace Test.Controllers
{
    public class TestController : Controller
    {
        private readonly static ILogger log = Log.ForContext(typeof(TestController));

        public TestController()
        {
            log.Debug("Test");
        }
Aleks
  • 1,629
  • 14
  • 19
  • 2
    upvoting the first part -- don't couple yourself to serilog in the controller. – burton Nov 17 '20 at 16:43
  • The first part helped me. I didn't realize that needed to be done. I'm using the standard `public HomeController(ILogger logger){_logger = logger;}` to keep knowledge of the specific log library (Serilog) out of the controllers. – Don Rolling Dec 02 '22 at 17:02