I'm new to .NET core and didn't have the chance (yet) to dive deep into dependency injection. But I understand the concept and know that it is a good thing and also that I need it for my app. As it may be necessary to enhance or switch the logging functionality at some point.
I have started a console application that uses a class library (.net Standard 2.0) and should log stuff out to the console and also a log file.
Currently I followed some guides and configured logging with Microsoft.Extensions.Logging.Console (nothing for file yet). The output of this logger is, that it writes two lines for each entry, like:
info: SampleWebConsoleApp.Program[0]
This is a test of the emergency broadcast system.
I don't know about you, but I kind of dislike output for logging on two lines. My brain cannot parse this :-) . I like it on one line and with a time stamp at the beginning. As far as I found out it seems that the console logger cannot be changed to be on a single line and have a timestamp in it.
So my journey began. And I found things like Serilog, NLog or my old friend that I used in the past, log4net.
I tried to go with Serilog, because it looked simple and easy, and also it has a logger for files which I also need. So I started to throw the old console logger out and integrate the Serilog console and file logger. But then I found some examples like this:
static void Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.WriteTo.File("consoleapp.log")
.CreateLogger();
...
}
But it seems to contradict my sparse knowledge of dependency injection, because I think it should be configured like this (assumption!):
private static void ConfigureServices(IServiceCollection services)
{
...
services.Configure<UnknownSerilogConfigurationClass>(config => config.FileName = "consoleapp.log");
}
I saw someone mention, that Serilog is itself a logger factory and thus an anti-pattern to DI.
So now I am a bit confused of where to go from here.
What logging framework that supports dependency injection should I use for a rather simple console app? Must have is, that it should me allow, to configure the output so that it includes a timestamp and the output should be on a single line.
Any suggestions?
You can use NLog. Configuration is simple. After configuration all you need to do is inject ILogger<T>
where T
is the class type that uses the logger.
nlog.config file (don´t forget to copy it to output directory)
<?xml version="1.0" encoding="utf-8" ?>
<!-- XSD manual extracted from package NLog.Schema: https://www.nuget.org/packages/NLog.Schema-->
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xsi:schemaLocation="NLog NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true" >
<!-- the targets to write to -->
<targets>
<!-- write logs to file -->
<target xsi:type="File" name="target1" fileName="${basedir}/LogFile.txt"
layout="${date}|${level:uppercase=true}|${message} ${exception}|${logger}|${all-event-properties}" />
<target xsi:type="Console" name="target2"
layout="${date}|${level:uppercase=true}|${message} ${exception}|${logger}|${all-event-properties}" />
</targets>
<!-- rules to map from logger name to target -->
<rules>
<logger name="*" minlevel="Trace" writeTo="target1,target2" />
</rules>
</nlog>
.NET Core 2.2 app
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using System;
namespace ConsoleApp1
{
public class Program
{
static void Main(string[] args)
{
var serviceProvider = new ServiceCollection()
.AddSingleton<IFooService, FooService>()
.AddLogging(builder =>
{
builder.SetMinimumLevel(LogLevel.Trace);
builder.AddNLog(new NLogProviderOptions
{
CaptureMessageTemplates = true,
CaptureMessageProperties = true
});
})
.BuildServiceProvider();
ILogger<Program> logger = serviceProvider.GetService<ILoggerFactory>()
.CreateLogger<Program>();
logger.LogInformation("Starting application...");
var fooService = serviceProvider.GetService<IFooService>();
fooService.DoWork();
Console.ReadLine();
}
}
}
FooService
using Microsoft.Extensions.Logging;
namespace ConsoleApp1
{
public interface IFooService
{
void DoWork();
}
public class FooService : IFooService
{
private readonly ILogger _logger;
public FooService(ILogger<FooService> logger)
{
_logger = logger;
}
public void DoWork()
{
_logger.LogInformation("Doing work.");
}
}
}
App output
2019/03/19 23:03:44.875|INFO|Starting application... |ConsoleApp1.Program|
2019/03/19 23:03:44.920|INFO|Doing work. |ConsoleApp1.FooService|
Or if you don't want to use NLog or any other logging provider you can create your own custom console logger and custom file logger.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With