ASP.NET Core introduces new framework level logging system. Although it is feature-rich it is not complex to use and it provides decent abstractions that fit well with the architecture of most web applications. This blog post shows how to set up and use Serilog file logging using framework-level dependency injection.
Configuring logging
Logging is configured in ConfigureServices() method of Startup class. ASP.NET Core comes with console and debug loggers. For other logging targets like file system, log servers etc third-party loggers must be used. This blog post uses Serilog file logger.
"dependencies": {
// ...
"Serilog.Extensions.Logging.File": "1.0.0"
},
Project has now reference to Serilog file logger. Let’s introduce it to ASP.NET Core logging system. AddFile(string path) is the extension method that adds Serilog file logger to logger factory loggers collection. Notice that there can be multiple loggers active at same time.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
loggerFactory.AddFile("Logs/ts-{Date}.txt");
// ...
}
Serilog will write log files to Logs folder of web application. File names are like ts-20170108.txt.
Injecting logger factory
Loggers are not injected to other classes. It’s possible to inject logger factory and let it create new logger. If it sounds weird for you then just check internal loggers collection of logger factory to see that also other classes that need logger have their own instances. The code below shows how to get logger to controller through framework level dependency injection.
public class DummyController : Controller
{
private ILogger _logger;
public DummyController(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger(typeof(DummyController));
}
// ...
}
Why we have to inject logger factory and not single instance of ILogger? Reason is simple – application may use multiple loggers like shown above. This is the fact we don’t want to know in parts of application where logging is done. It’s external detail that si not related to code that uses logging.
Logging
Logging is done using extension methods for ILogger interface. All classic methods one can expect are there:
- LogDebug()
- LogInformation()
- LogWarning()
- LogError()
- LogCritical()
Now let’s write something to log.
public class DummyController : Controller
{
private ILogger _logger;
public DummyController(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger(typeof(DummyController));
}
public void Index()
{
_logger.LogInformation("Hello from dummy controller!");
}
}
Making request to Dummy controller ends up with log message added to debug window and log file. The following image shows log message in output window.
And here is the same log message in log file.