11

I'm creating a console logger using:

_log = new LoggerFactory().AddConsole().CreateLogger(this.GetType().Name); 

Now I'm getting the following warning:

controllers\DummyController.cs(31,20): warning CS0618: 'ConsoleLoggerExtensions.AddConsole(ILoggerFactory)' is obsolete: 'This method is obsolete and will be removed in a future version. The recommended alternative is AddConsole(this ILoggingBuilder builder).' 

I'm not in the context of a dependency injection container.

UPDATE: I also tried using DI like this:

var serviceProvider = new ServiceCollection() .AddLogging() .BuildServiceProvider(); var log = serviceProvider.GetService<ILogger>(); log.LogInformation("testing _log"); 

But I get the following error:

Error Message: System.ArgumentNullException : Value cannot be null. Parameter name: logger Stack Trace: at Microsoft.Extensions.Logging.LoggerExtensions.Log(ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, String message, Object[] args) at Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(ILogger logger, String message, Object[] args) 

It seems I can't get the logger from the container

2
  • 2
    You can probably do it via reflection or something else. It might be overkill, but what I've done in certain scenarios where performance is not a major concern is to just create my ServiceCollection and ServiceProvider and just use the extension methods provided. Commented Jan 25, 2019 at 21:58
  • Thanks, I also tried with DI but it seems like there's something missing. I updated my question Commented Jan 25, 2019 at 22:10

2 Answers 2

16

The interface has changed, so that you use a static Create() factory method on LoggerFactory, with a delegate that is passed in a configuration object that you configure the provider on. The factory can then be used to create loggers as before:

 ILogger<Program> logger = LoggerFactory .Create(logging => logging.AddConsole()) .CreateLogger<Program>(); logger.LogInformation("Hello World!"); 

While an application should usually use a host builder, this can be very useful in unit testing, as you can pass in a real logger that writes to the console (instead of a mock), and see the output in your test results.

This is taken from the simple walkthough example at: https://github.com/sgryphon/essential-logging/tree/master/examples/GettingStarted

There is also further examples that show how to configure via a host builder, and how to use the Microsoft high performance logging pattern.

Sign up to request clarification or add additional context in comments.

Comments

10

If you're creating a Dependency Injection container, you can use the following code to instantiate a logger instance from the logger factory.

var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>(); var logger = loggerFactory.Create("mylogger"); logger.LogInformation("Hello {0}", "world"); 

Or, you can create it via the typed interface

var logger = serviceProvider.GetRequiredService<ILogger<MyType>>(); logger.LogInformation("Hello {0}", "world"); 

However, you are not able to do the following:

var logger = serviceProvider.GetRequiredService<ILogger>(); 

As the non-generic interface is not registered in the Dependency Injection container, the reasoning for this is that the logging libraries infer the logger name from the generic type, and when you use ILogger only, there's nothing to derive a name from, versus MyProject.MyNamespace.MyType.

Slightly off topic, but using the extension method GetRequiredService<T> instead of GetService<T> would at least help you avoid a possible NullReferenceException, and have the application fail earlier.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.