I created a consumer/job that I will have running as a process on Linux written in C#.
The process will:
All the documentation on NLog about .NET Core are on ASP.NET Core. When I try to get an ILogger
implementation, it returns null.
Here is an except of wiring and usage:
static void ConfigureServices()
{
string environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var builder = new ConfigurationBuilder()
.SetBasePath(Path.Combine(AppContext.BaseDirectory))
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{environment}.json", optional: true);
var services = new ServiceCollection();
Configuration = builder.Build();
[...]
services.AddLogging();
ServiceProvider = services.BuildServiceProvider();
var loggerFactory = ServiceProvider.GetService<ILoggerFactory>();
loggerFactory.AddNLog();
}
static void Main(string[] args)
{
ConfigureServices();
var logger = ServiceProvider.GetService<NLog.ILogger>();
logger.Debug("Logging");
[...]
}
Do not be confused with the environment variable ASPNETCORE_ENVIRONMENT
; it is used solely to determine which appsettings.json
to use.
I've based my code on this issue report.
Finally, these are the packages I currently have installed.
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="1.1.2" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="1.1.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="1.1.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="1.1.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.1.2" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="1.1.2" />
<PackageReference Include="NLog" Version="5.0.0-beta09" />
<PackageReference Include="NLog.Extensions.Logging" Version="1.0.0-rtm-beta5" />
<PackageReference Include="Npgsql" Version="3.2.4.1" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="1.1.0" />
</ItemGroup>
nuget.org/packages/NLog/… NLog 4.7 has been released! See news post: nlog-project.org/2020/03/28/nlo… While older versions of NLog works well on ASP.NET Core 3, we have optimized the NLog.
Alternatively, you can install NLog using the NuGet Package Manager. To do this, all you need to do is create a project in Visual Studio, right-click on the project in the Solution Explorer window, and then select the “Manage NuGet Packages...” option. Next, you can select NLog.
A complete minimalistic example of NLog in a .NET Core 1 console app (based on NLog.Extensions.Logging repository):
var services = new ServiceCollection();
services.AddLogging();
var provider = services.BuildServiceProvider();
var factory = provider.GetService<ILoggerFactory>();
factory.AddNLog();
factory.ConfigureNLog("nlog.config");
var logger = provider.GetService<ILogger<Program>>();
logger.LogCritical("hello nlog");
References:
<ItemGroup>
<PackageReference Include="NLog.Extensions.Logging" Version="1.0.0-rtm-beta5" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="1.1.2" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="1.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="1.1.2" />
</ItemGroup>
nlog.config:
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
internalLogFile="internal-nlog.txt">
<variable name="Layout"
value="${longdate}|${level:uppercase=true}|${logger}|${message}"/>
<!-- the targets to write to -->
<targets>
<!-- write logs to file -->
<target xsi:type="File"
name="allfile"
fileName="nlog-all-${shortdate}.log"
layout="${Layout}" />
<!-- write to the void aka just remove -->
<target xsi:type="Null" name="blackhole" />
</targets>
<!-- rules to map from logger name to target -->
<rules>
<!--All logs, including from Microsoft-->
<logger name="*" minlevel="Trace" writeTo="allfile" />
<!--Skip Microsoft logs and so log only own logs-->
<logger name="Microsoft.*" minlevel="Trace" writeTo="blackhole" final="true" />
</rules>
</nlog>
In DotNet Core 2 you can use the start up class now and clean up the code a bit to look more like the web one.
And as a bonus a way to start your app inside the DI container using ConsoleApp
Program.cs
static void Main(string[] args)
{
IServiceCollection services = new ServiceCollection();
Startup startup = new Startup();
startup.ConfigureServices(services);
IServiceProvider serviceProvider = services.BuildServiceProvider();
// entry to run app
serviceProvider.GetService<ConsoleApp>().Run();
}
Startup.cs
public class Startup
{
IConfigurationRoot Configuration { get; }
public Startup()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
Configuration = builder.Build();
}
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IConfigurationRoot>(Configuration);
services.AddSingleton<IMyConfiguration, MyConfiguration>();
services.AddLogging(loggingBuilder => {
loggingBuilder.AddNLog("nlog.config");
});
services.AddTransient<ConsoleApp>();
}
}
ConsoleApp.cs
public class ConsoleApp
{
private readonly ILogger<ConsoleApp> _logger;
private readonly IMyConfiguration _config;
public ConsoleApp(IMyConfiguration configurationRoot, ILogger<ConsoleApp> logger)
{
_logger = logger;
_config = configurationRoot;
}
public void Run()
{
var test = _config.YourItem;
_logger.LogCritical(test);
System.Console.ReadKey();
}
}
Configuration.cs
public class MyConfiguration : IMyConfiguration
{
IConfigurationRoot _configurationRoot;
public MyConfiguration(IConfigurationRoot configurationRoot)
{
_configurationRoot = configurationRoot;
}
public string YourItem => _configurationRoot["YourItem"];
}
public interface IMyConfiguration
{
string YourItem { get; }
}
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