Reputation: 137
I am trying to add NLog to a .NET 5 console app.
I understand I will want to not hard code some of these settings, and link a appsettings file soon, but I jsut want to get everything logging first, with the bare minimum.
So far I have:
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
var config = new LoggingConfiguration();
var fileTarget = new FileTarget("fileTarget")
{
FileName = @"c:\AppLogs\TestApp\mylog-${shortdate}.log",
Layout = "${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}"
};
if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development")
{
fileTarget = new FileTarget("fileTarget")
{
FileName = @"c:\AppLogs\TestApp_UAT\mylog-${shortdate}.log",
Layout = "${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}"
};
}
config.AddTarget(fileTarget);
// rules
config.AddRuleForOneLevel(NLog.LogLevel.Warn, fileTarget);
config.AddRuleForOneLevel(NLog.LogLevel.Error, fileTarget);
config.AddRuleForOneLevel(NLog.LogLevel.Fatal, fileTarget);
LogManager.Configuration = config;
var host = Host.CreateDefaultBuilder()
.ConfigureServices((context, services) =>
{
services.AddTransient<TestService>();
}).ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
logging.AddNLog();
}).Build();
var svc = ActivatorUtilities.CreateInstance<TestService>(host.Services);
svc.Run();
}
I then try to log something in TestService:
public class TestService
{
public TestService(ILogger<TestService> logger)
{
Logger = logger;
}
public ILogger<TestService> Logger { get; }
public void Run()
{
Console.WriteLine("my first log");
Logger.LogInformation("my first log");
}
}
I don't get any errors, but I don't get any logs created (file or contents) created either. The console outputs, so TestServices runs correctly.
According to the docs, I was expecting to see a method called "BuildServiceProvider()" to chain after "ConfigureLogging()", but I only have 'Build()". Is this something to do with it, or have I missed something?
Upvotes: 1
Views: 7298
Reputation: 19867
You are doing LogInformation
but you have only enabled Warn
+ Error
+ Fatal
using AddRuleForOneLevel
. Maybe replace with AddRule(NLog.LogLevel.Info, NLog.LogLevel.Fatal, fileTarget)
instead ?
You can also try specifying RemoveLoggerFactoryFilter
(To avoid Microsoft ILogger-filtering problems):
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddNLog(new NLogProviderOptions { RemoveLoggerFactoryFilter = true );
})
Upvotes: 1
Reputation: 27852
Here is my complete and encapsulated NLog (for Console/CommandLine/DotNetCore) applications.
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NLog;
using NLog.Extensions.Logging;
using LogLevel = Microsoft.Extensions.Logging.LogLevel;
namespace Me.Configuration.DependencyInjection
{
[ExcludeFromCodeCoverage]
public static class NlogSharedConfiguration
{
public const string NlogPerEnvironmentNameTemplate = "nlog.{0}.config";
public const string NlogDefaultFileName = "nlog.config";
public static IServiceCollection ConfigureSharedNlog(
this IServiceCollection services,
IConfiguration configuration,
IHostEnvironment hostEnvironmentProxy)
{
NLogProviderOptions nlpopts = new NLogProviderOptions
{
IgnoreEmptyEventId = true,
CaptureMessageTemplates = true,
CaptureMessageProperties = true,
ParseMessageTemplates = true,
IncludeScopes = true,
ShutdownOnDispose = true
};
/* Note, appsettings.json (or appsettings.ENVIRONMENT.json) control what gets sent to NLog. So the .json files must have the same (or more) detailed LogLevel set (compared to the Nlog setting)
* See https://stackoverflow.com/questions/47058036/nlog-not-logging-on-all-levels/47074246#47074246 */
services.AddLogging(
builder =>
{
builder.AddConsole().SetMinimumLevel(LogLevel.Trace);
builder.SetMinimumLevel(LogLevel.Trace);
builder.AddNLog(nlpopts);
});
string nlogPerEnvironmentName = string.Format(
NlogPerEnvironmentNameTemplate,
hostEnvironmentProxy.EnvironmentName);
string nlogConfigName = File.Exists(nlogPerEnvironmentName) ? nlogPerEnvironmentName : NlogDefaultFileName;
Console.WriteLine(string.Format("Nlog Configuration File. (FileName='{0}')", nlogConfigName));
if (!File.Exists(nlogConfigName))
{
throw new ArgumentOutOfRangeException(
string.Format("Nlog Configuration File NOT FOUND. (FileName='{0}')", nlogConfigName));
}
LogManager.LoadConfiguration(nlogConfigName);
NLogLoggerProvider nlogProv = new NLogLoggerProvider(nlpopts);
ILoggerProvider castLoggerProvider = nlogProv as ILoggerProvider;
services.AddSingleton<ILoggerProvider>(castLoggerProvider);
return services;
}
}
}
I have (in my rootfolder of my .exe.) the following files:
nlog.config
nlog.Development.config
NLog.xsd
nlog.Development.config is OPTIONAL, but this is how I have slightly different settings for a local developer vs everything else. You can see my "if file exists" code above.
IHostEnvironment comes from here :
Upvotes: 2