Reputation: 103
I've added NLog to my MVC Core 2.2 project and everything works fine except application startup logging. Logs are written well in controllers but not in Program.cs. Here is my main method, all NLog stuff was taken from NLog documentation :
public static void Main(string[] args)
{
// NLog: setup the logger first to catch all errors
var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
try
{
logger.Info("Starting app");
CreateWebHostBuilder(args).Build().Run();
}
catch (Exception ex)
{
// NLog: catch setup errors
logger.Error(ex, "App failed to start");
throw;
}
finally
{
// Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
NLog.LogManager.Shutdown();
}
}
NLog own logs show the following:
Error Error has been raised. Exception: System.ArgumentException: The path is not of a legal form. at NLog.Targets.FileTarget.Write(LogEventInfo logEvent) at NLog.Targets.Target.Write(AsyncLogEventInfo logEvent)
which is weird because logs are written correctly afterwards in the file path I defined.
Here is my 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"
autoReload="true"
internalLogLevel="Info"
internalLogFile="c:\temp\nlog.log"
throwConfigExceptions="true">
<!-- enable asp.net core layout renderers -->
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
<variable name="logFilePath" value="${configsetting:name=Logging.LogFilePath}"/>
<targets>
<target xsi:type="File"
name="PortailUsagersCore"
fileName="${logFilePath}"
layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|controller: ${aspnet-mvc-controller}|action: ${aspnet-mvc-action}"
maxArchiveFiles="4"
archiveNumbering="Rolling"
archiveAboveSize="2097152" />
</targets>
<rules>
<logger name="*" writeTo="PortailUsagersCore" />
</rules>
</nlog>
LogFilePath is defined in appsettings.json and appsettings.development.json in logging section :
"Logging": {
"LogFilePath": "C:\\Logs\\Portail\\PortailUsagersCore.log",
"IncludeScopes": false,
"LogLevel": {
"Default": "Trace",
"Microsoft": "Information"
}
}
Upvotes: 2
Views: 2383
Reputation: 381
It may not be totally relevant to your specific question but I had an issue where copying the example from the NLOG page wasn't working to provide the initial "init main" call. When I searched, your SO post came up.
After reading the comments on this, I started playing around with where the log statements were being made. Come to find out, logging calls need to occur AFTER the
var app = builder.Build();
call happens for them to work.
In the example provided on the NLOG site, the logging line occurs immediately after the line var logger = NLog.LogManager.Setup().LoadConfigurationFromFile().GetCurrentClassLogger();
. This is occurring before the required app call and so the logging does not work. Move the logging down until after the call and the log messages will start to show.
Upvotes: 0
Reputation: 23
As I just faced the same issue, probably with a newer version, I'd like to give my solution.
When using appsettings for NLog configuration, make sure to use:
var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger(); logger.Debug("init main");
Instead of:
var logger = LogManager.Setup().LoadConfigurationFromFile("appsetting.json").GetCurrentClassLogger(); logger.Debug("init main");
This last one expects an xml file.
Upvotes: 0
Reputation: 103
I managed to make it work, thanks to RolfKristensen suggestions. Appsettings is now read before NLog initialization, so NLog is now able to read the filepath in it. I used NLog.GlobalDiagnosticsContext to set the filePath in NLog.config.
string env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
// Load config file to read LogFilePath
var config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env}.json", optional: true, reloadOnChange: true)
.Build();
// LogFilePath is read in nlog.config
NLog.GlobalDiagnosticsContext.Set("LogFilePath", config["Logging:LogFilePath"]);
// NLog: setup the logger first to catch all errors
var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
And in my NLog.config, I use it this way :
<variable name="logFilePath" value="${gdc:item=LogFilePath}"/>
<targets>
<target xsi:type="File"
name="PortailUsagersCore"
fileName="${logFilePath}"
Upvotes: 2