NLog logger doesn't log to the configured logfile in release build - c#

I have the configuration file set up
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
</configSections>
<nlog autoReload="true">
<targets>
<target name="file" type="File" fileName="${basedir}/log/${shortdate}.log" layout="${date:format=HH\:mm\:ss.fff}|${message}"/>
<target name="file_webs" type="File" fileName="${basedir}/log/${shortdate}_webs.log" layout="${date:format=HH\:mm\:ss.fff}|${message}"/>
</targets>
<rules>
<logger name="WebSocket.*" minlevel="Debug" writeTo="file_webs" final="true"/>
<logger name="*" minlevel="Debug" writeTo="file" />
</rules>
</nlog>
</configuration>
The logger is loaded in each class like this:
private static Logger logger = LogManager.GetCurrentClassLogger();
The logging is directed to the correct file as long as I don't run the build version. Then all logging is done in the default log file.
What could be the cause?

Check the following:
Is the correct config file placed in the output directory of the release. Maybe there is a different version of your config file there or it is missing.
Are there other things running after your build? Like a tool to obfuscate the source code? If so, this might mess up the class name in your build, the config the can not redirect to the right output. In that case, explicitly load the logger for your class this way:
private static Logger logger = LogManager.GetLogger("WebSocket.*");

Related

how to use etw nlog for writing log to custom eventsource

For my console application , I want to write all the logs to custom event source under Application and Services Logs under separate section MyEventSourceName.
I tried to use NLog.Etw, but seems nothing appears. How to do this?
<?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"
throwExceptions="false">
<extensions>
<add assembly="NLog.Etw" />
</extensions>
<targets async="true">
<target xsi:type="EtwEventSource"
name="eetw"
providerName="MyEventSourceName"
taskName="${level}"
layout="${message}">
</target>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="eetw" />
</rules>
class Program
{
private static Logger logger = LogManager.GetCurrentClassLogger();
static void Main(string[] args)
{
logger.Info("New person created with name {0}");
}
}
You could use the eventlog target:
For example:
<target xsi:type="EventLog"
name="eventlog"
source="MyEventSourceName"
log="MyEventSourceLogName"
layout ="${message}${newline}${exception:format=ToString}"/>
See docs
The target supports .NET3.5+ and .NET Standard 2.0. For NetStandard 2.0 use the NLog.WindowsEventLog package.

NLog for ASP.NET website doesn't log

I created simple ASP.NET web-site, added NLog, but it doesn't create any log file, neither throws any exceptions. I tried troubleshoot, but it doesn't help https://github.com/NLog/NLog/wiki/Logging-troubleshooting
my web.config
<configSections>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
</configSections>
<nlog
xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
throwExceptions="true"
internalLogLevel="Off"
internalLogFile="c:\temp\nlog-internal.log">
<targets>
<target name="file" type="File" fileName="C:\log.txt" />
</targets>
<rules>
<logger name="File" minlevel="Trace" writeTo="file" />
<logger name="FileNotFound" minlevel="Trace" writeTo="file-404" />
</rules>
</nlog>
Then I run page below, and nothing happens...
public partial class Test1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
LogManager.ThrowExceptions = true;
Logger logger = LogManager.GetLogger("foo");
Logger log = LogManager.GetCurrentClassLogger();
log.Error("some test");
logger.Error("some test 2");
}
}
What is my fault? Thank you!
The name attriute of the <logger> is a filter (on name)
So you filter now on the loggers with the name "File" and "FileNotFound"
This will write all to the file
<logger name="*" minlevel="Trace" writeTo="file" />
Another option is to use named loggers in C#, so instead of
Logger log = LogManager.GetCurrentClassLogger();
use
Logger log = LogManager.GetLogger("FileNotFound");
Then you could use <logger name="FileNotFound" ..> in your config
Likely that your output directory can't be written to by the IIS user. Try using an output directory relative to the website, like "logs".

ASP.NET Core NLog nlog.config loaded but ignored

I am writing a asp.net core app using NLog.Logging.Extensions to provide logging.
Log Registration:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {
loggerFactory.AddNLog();
loggerFactory.ConfigureNLog("nlog.config");
loggerFactory.AddConsole();
loggerFactory.AddDebug();
app.UseMvc();
}
I am getting log output, however it doesn't match the format of my logging Layout defined in the .config file, and it doesn't show anything below information (but again, it is configured to show trace and above in the config file).
Is anyone able to shed any light as to why this may be occurring?
nlog.config:
<?xml version="1.0" encoding="utf-8"?>
<nlog>
<variable name="Layout" value="${longdate} ${level:upperCase=true} ${message} (${callsite:includSourcePath=true})${newline}${exception:format=ToString}"/>
<targets>
<target name="debugger" type="Debugger" layout="${Layout}" />
<target name="console" type="ColoredConsole" layout="${Layout}" detectConsoleAvailable="False"/>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="debugger,console" />
</rules>
</nlog>
Example Log Output:
Hosting environment: Development
Content root path: /Users/###/dev/###/Services/src/app/###/###
Now listening on: http://localhost:8888 Application started.
Press Ctrl+C to shut down.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET http://localhost:8888/State
info: ###.###.###[0]
Building ### instance.
There are several problems here.
1. You get the log output because you've attached default .NET Core loggers:
loggerFactory.AddConsole();
loggerFactory.AddDebug();
And this is why the output doesn't match the format of your Layout. Do not add the default loggers if you are going to use only NLog. Then, keep these two lines below:
loggerFactory.AddNLog();
loggerFactory.ConfigureNLog("nlog.config");
2. NLog config is broken. <add assembly="NLog.Web.AspNetCore"/> is missing. Moreover, it looks like the Debugger target is breaking something in NLog.
There is a fully-workable nlog.config below:
<?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">
<!-- Load the ASP.NET Core plugin -->
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
<variable name="Layout"
value="${longdate}|${level:uppercase=true}|${logger}|${message}"/>
<targets>
<target name="console"
type="ColoredConsole"
layout="${Layout}"
detectConsoleAvailable="False"/>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="console" />
</rules>
</nlog>
Additional examples: https://github.com/NLog/NLog.Web/wiki/Getting-started-with-ASP.NET-Core-(project.json)

NLog in .NET 4.5 console app: not loading Configuration

I have some console apps I've written at work. I'd like to get NLog into them but I am having trouble.
When I inspect the 'logger' object, I see in it's 'Factory' property, that the configuration had targets=0, loggingrules=0, everything blank or unset.
So, it doesn't do ANYTHING.. doesn't drop an internal log file either... I have tried nLog.config NLog.config and nlog.config... to no avail. Tried ver 3 and 4 of NLog too...
Why would it not pick up the config?
I have:
NLog.config in the root with 'Content' for build action and 'Copy Always' set
Confirmed the NLog.config IS being copied to the bin
Here's the 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"
throwConfigExceptions="true"
throwExceptions="true"
internalLogLevel="Trace"
internalLogFile="c:\temp\NlogInternal.log"
internalLogToConsole="true"
internalLogToConsoleError="true"
internalLogToTrace="true">
<targets>
<target xsi:type="Console" name="debugConsole" layout="${message} "/>
<target xsi:type="File" name="debugFile" createDirs="true" fileName="c:\temp\testlog.log" layout="${longdate} ${uppercase:${level}} ${message}"/>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="debugConsole"/>
<logger name="*" minlevel="Trace" writeTo="debugFile"/>
</rules>
</nlog>
and finally (this doesn't error, but nothing is output since the config is blank):
private static Logger logger = LogManager.GetCurrentClassLogger();
logger.Info("ConsoleApp test log...");
Do your app.config have a NLog configSection?
Something like this:
<configuration>
<configSections>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
</configSections>
<nlog>
</nlog>
</configuration>
If even the internalLogger isn't working, you could debug the issue by setting
the InternalLogger.LogWriter
e.g.
// enable internal logging to a custom TextWriter
InternalLogger.LogWriter = new StringWriter(); //e.g. TextWriter writer = File.CreateText("C:\\perl.txt")
I got the same issue on my end. When you make change your fileName Path "c:\temp\testlog.log" to
"c:/temp/testlog.log" then it will work. Hope the below snipet help you to resolve the issue.
<targets>
<target xsi:type="Console" name="debugConsole" layout="${message} "/>
<target xsi:type="File" name="debugFile" createDirs="true"
fileName="c:/temp/testlog.log" layout="${longdate} ${uppercase:${level}}
${message}"/>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="debugConsole"/>
<logger name="*" minlevel="Trace" writeTo="debugFile"/>
</rules>

Log only to a specific target at runtime

I am using NLog with two targets:
<?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">
<targets async="true">
<target name="logfile" xsi:type="File" fileName="my.log"/>
<target name="console" xsi:type="Console"/>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="logfile"/>
<logger name="*" minlevel="Info" writeTo="console"/>
</rules>
</nlog>
Is it possible to log a message only to the "logfile" target, without having the message written to the "console" target as well?
EDIT
To clarify: I want to direct messages from the same class to different loggers at run time (w/o having to change the XML). Something like:
class Program
{
static Logger _logger = LogManager.GetCurrentClassLogger();
static void Main(string[] args)
{
// Note - _logger.InfoToTarget() does not really exist
_logger.InfoToTarget("logfile", "This is my very detailed message, possibly with object dumps");
_logger.InfoToTarget("console", "Short message");
}
}
I'm aware that this couples my code with the NLlog.config file.
One way to accomplish the functionality you are looking for is to name your logger
_logger = LogManager.GetLogger("MyConsoleLogger")
_logger.Info("This will log to the console...");
_logger = LogManager.GetLogger("MyFileLogger")
_logger.Trace("This will log to a file...");
rather than using
LogManager.GetCurrentClassLogger().
In your config file you could then list in the rules
<rules>
<logger name="MyFileLogger" minlevel="Trace" writeTo="logfile"/>
<logger name="MyConsoleLogger" minlevel="Info" writeTo="console"/>
</rules>
This is by far not the most pretty solution to look at, but it does give you the functionality that you are looking for.
There are a few ways to do this, and the correct method depends on your situation.
Keep in mind that you typically want to avoid having your app know too much about the inner-workings of logging. If possible, it's best to configure nlog to decide where things should get logged.
Is there a specific namespace that should not be logged to console? That's easy to configure. Also, you can use the "When" filter (https://github.com/nlog/nlog/wiki/When-filter) or conditions (https://github.com/nlog/nlog/wiki/Conditions)
It may also be best to have multiple logger instances, so you can call the one that is appropriate for each situation (logger per class) (Why do loggers recommend using a logger per class?).
Absolutely, however I am assuming you mean at release you no longer wish to log to the console. You can do this very easily by removing or commenting out the listener that writes to the console target. Now it will only write to the logfile target.
<?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">
<targets async="true">
<target name="logfile" xsi:type="File" fileName="my.log"/>
<target name="console" xsi:type="Console"/>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="logfile"/>
<!--<logger name="*" minlevel="Info" writeTo="console"/>-->
</rules>
</nlog>
The rule that writes to the console is now deactivated, but the log file is active. If this is during release you probably want to change your rule to not process your trace logging as the min level for the log file since it will slow down your app with excessive IO. I have asked this question in the past and it appears that best practice is to do this via the XML configuration files. (Logging in Release Build of Application (C#))

Categories

Resources