My ASP.NET Core 3.1 application used to log to the console only. Now I've added systemd integration. Next I'm using a third-party package to enhance the logging to the journal. The problem is, the application must work both in systemd and in the Windows console for development. If I add both providers, I get duplicate log entries in Linux/systemd.
How can I conditionally select the log provider if systemd was found?
private static IHostBuilder CreateHostBuilder(string[] args)
{
return Host.CreateDefaultBuilder(args)
.UseSystemd()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.ConfigureLogging((hostingContext, logging) =>
{
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
if (__isSystemd__)
{
logging.AddJournal(options =>
{
options.SyslogIdentifier = "myapp";
});
}
else
{
logging.AddConsole();
}
});
webBuilder.UseStartup<Startup>();
});
}
I found out that UseSystemd
adds a service that I could test for. But I can't get hold of something that would tell me about already registered services.
Okay, after a lot of digging around, I found one solution, and then a better one. These go where my question says if (__isSystemd__)
.
#1:
if (logging.Services.Any(s => s.ImplementationType == typeof(SystemdLifetime)))
{
// add journal logging
}
#2:
if (SystemdHelpers.IsSystemdService())
{
// add journal logging
}
The SystemdHelpers
class comes from the Microsoft.Extensions.Hosting.Systemd package that also provides UseSystemd
. It caches its decision in a static variable so it's probably the quickest option. It also uses this very information to determine whether to do all the systemd stuff (like registering the SystemdLifetime
service that cares about notification).