NLOG creating debug.txt file when minlevel = "Info" - nlog

I am not very familiar with NLOG, so I am hoping someone can point me in the right direction to solving this problem. I don't want NLOG to create a debug.txt file. I thought simple updating the minlevel to "Info", would solve it, but it does not.
Here are the settings in my app.config file that point NLOG:
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true">
<variable name="applicationName" value="TheNameOfMyApplication" />
<include file="\\<PathToNlogConfig>\NLog.config" />
</nlog>
And in my NLog.config file in the rules section:
<logger name="Name.Space.Apps.*" minlevel="Info" writeTo="consoleapps" final="true" />
<logger name="*" minlevel="Info" writeTo="fileOut" />
What else do I need to configure to stop this debug.txt file from being created?
Thanks

Solved it. Turns out we were using a library to log to NLOG, and NLOG was grabbing the namespace from that library, and hence hitting a different rule.

Related

NLog logs Error twice in same file

I am trying to figure out why NLog logs my error twice.
here is my config file:
<nlog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="debug" xsi:type="File" FileName="DebugTestFile.log" layout="${message} ${exception:format=tostring}" />
</targets>
<rules>
<logger name="*" level="Debug" writeTo="debug" />
</rules>
</nlog>
Now when I call NLog.Debug(myException); the output is my exception gets printed twice.
If I call NLog.Debug(myException, "My Test Message String"); then the error gets printed out once along with my test message.
What exactly am I doing wrong? According to https://github.com/NLog/NLog/wiki/How-to-Log-Exceptions my configuration is correct.
I tried changing my layout to the following: layout="${message} and when I ran NLog.Debug(myException); it only printed the error once.
However now when I ran NLog.Debug(myException, "My Test Message String"); it only printed my message without the error that comes from exception.
Could this be a bug with NLog?
Updated Answer
NLog.Web.AspNetCore v4.8.6 changes registration of NLog Logging Provider, so one is now allowed to call both AddNLog and UseNLog without experiencing double logging.
NLog 5.0 implements validation of incorrect duplicate target configuration, so one will not experience double logging when using incorrect NLog configuration.
Original Answer
If you are using NLog in AspNetCore, then the problem can be caused by calling UseNLog together with AddNLog or ConfigureNLog.
You should only use UseNLog together with NLog.Web.LogBuilder.ConfigureNLog (Stop using AddNLog):
https://github.com/NLog/NLog/wiki/Getting-started-with-ASP.NET-Core-2#4-update-programcs
This is seems to be because of rule in config file, just change writeTo for each logger, in my case I was able to reolve this issue by following same steps:
Example:
Earlier config file which was having issue:
<rules>
<logger name="*" minlevel="Info" writeTo="console" />
<logger name="*" minlevel="Error" writeTo="console" />
</rules>
Corrected config file:
<rules>
<logger name="*" minlevel="Info" writeTo="console" />
<logger name="*" minlevel="Error" writeTo="console1" />
</rules>

NLog 4.0 ignores final attribute on a rule

My application is using NLog configured with NLog.config shown below. It also uses RavenDB database which by default uses active NLog settings for logging.
It produces a lot of DEBUG and INFO messages that pollute the log. I do want to log ERROR and WARN messages. All of the records created by RavenDB come from namespaces that start with Raven.
I created the rules as shown below. Basically there is a final rule that prevents INFO/DEBUG messages that come from Raven.* namespace to get written into the log file. Everything was working well until I upgraded the NuGet packages to NLog 4.0. Now all the RavenDB messages are written into the log file.
Is this a bug or there is some configuration change happened across the NLog versions?
<?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>
<target name="file" xsi:type="AsyncWrapper" queueLimit="1000" overflowAction="Discard">
<target
name="file"
xsi:type="File"
layout="${longdate} - ${level:upperCase=true} - ${identity} - ${logger} - ${message}${onexception:inner=${newline}${exception:format=tostring}${newline}}"
fileName="D:/Logs/AppName/${shortdate}.log" />
</target>
</targets>
<rules>
<logger name="Raven.*" writeTo="file" minlevel="Warn" final="true" />
<logger name="*" writeTo="file" minlevel="Debug" />
</rules>
</nlog>
Apparently there was a logic change in NLog 4. It does not mark messages from Raven namespace with level below the Warn final any longer.
http://nlog-project.org/2015/06/09/nlog-4-has-been-released.html
So the rule would have to change to send messages in the Raven.* namespace with maxlevel="INFO" into a null target.

NLog - Only log while debugging

Take this simple NLog example configuration:
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="logfile" xsi:type="File" fileName="file.txt" />
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="logfile" />
</rules>
</nlog>
How can this be set up to only log while debugging, and not when run in production?
EDIT:
To make things a bit more challenging: My NLog configuration files are centralized, shared over all applications/services/sites. So I would like to avoid altering every single project and just modify the config files.
A simple solution would be to have a NLog.config file (whose contents will be overriden - you'll see later), plus one NLog config file per solution configuration/environment (let's say, NLog.debug.config and NLog.release.config). For example:
Then you configure a Pre-build event command line to copy the config file corresponding to the current active configuration:
The complete command you should paste there:
del "$(ProjectDir)NLog.config"
if "$(ConfigurationName)"=="Debug" (
copy "$(ProjectDir)NLog.debug.config" "$(ProjectDir)NLog.config"
) else (
copy "$(ProjectDir)NLog.release.config" "$(ProjectDir)NLog.config"
)
This will copy NLog.debug.config to NLog.config (effectively overriding it) if DEBUG is the current active configuration/environment, otherwise it will copy NLog.release.config.
A shorter version would look like this (note the file naming diference though):
del "$(ProjectDir)NLog.config"
copy "$(ProjectDir)NLog.$(ConfigurationName).config" "$(ProjectDir)NLog.config"
Another thing to note is that during compilation the compiler will throw various warnings about duplicate declarations related to NLog. The reason is that the compiler will find 2 (or more) distinct configuration files for NLog and their declarations will collide. In order to fix that you have to change the Properties of each of your extra NLog configuration files to make the build action not copy them. For example:
Do not repeat yourself
Lastly, you may not want to duplicate common/shared targets|rules|whatnot to avoid having to change them in multiple files. To achieve that, you can move these common/shared parts to another file and use <include />.
I see three solutions here.
1) Using config file and its transformations. For the moment the transformations are supported for web applications (Im talking about VS2012). For desktop app you need to install additional extension.
2) Use two targets, one for development (I assume debugging=development in your case) and the second for production. At runtime you need to leave actual one by removing the other.
UPDATE
3) If you don't want to alter the projects it is possible to apply custom conditions to the logger depending on custom Layout Renderer (see example of how to make a custom layout renderer). In your case the layout renderer should return current Build Configuration (Debug or Release) of executing assembly. As a result the condition will look like this:
<rules>
<logger name="*" writeTo="logfile">
<filters>
<when condition="equals('${buildConfiguration}','Release')" action="Ignore" />
</filters>
</logger>
</rules>
where ${buildConfiguration} is your custom layout renderer.
PS And dont forget to put this
<extensions>
<add assembly="NameOfMyAssemblyThatContainsMyLayoutRenderer" />
</extensions>
to the nlog.config so NLog knows about the layout renderer.
I have based my answer on #neleus answer above but it still took me hours to get something working. Here is the completed guide incl. how to set up the LayoutRenderer. For the NLog.config you need:
<extensions>
<add assembly="AssemblyName" />
</extensions>
<target xsi:type="AsyncWrapper" name="asyncProd">
<target xsi:type="File" name="logfileProc" fileName="${basedir}/logs/${buildConfiguration}.log"/>
</target>
<logger name="*" minlevel="Info" writeTo="asyncProd">
<filters>
<when condition="equals('${buildConfiguration}','Debug')" action="Ignore" />
</filters>
</logger>
The target above is only for newbees to NLog so they have something running more quickly. Using the custom LayoutRenderer in the filename helps with debugging as you can see it's output in the file that is produced.
Then create a class called BuildConfigLayoutRenderer which I adapted from neleus' link
[LayoutRenderer("buildConfiguration")]
[ThreadAgnostic]
public class BuildConfigLayoutRenderer : LayoutRenderer {
private String buildconfig;
private String GetBuildConfig() {
if (buildconfig != null) {
return buildconfig;
}
#if DEBUG
buildconfig = "Debug";
#else
buildconfig = "Release";
#endif
return buildconfig;
}
protected override void Append(StringBuilder builder, LogEventInfo logEvent) {
builder.Append(GetBuildConfig());
}
}
Important is the string passed into the LayoutRendererAttribute. They need to match with what you register (needs to happen as early as possible in your code; main()) and the NLog.config.
LayoutRenderer.Register<BuildConfigLayoutRenderer>("buildConfiguration");
Now ${buildConfiguration} will work.
You can also use this for even more build configurations but you need to remember to add the filter that ignores that rule. I also tried the opposite, meaning to have action="Log" in the rule to reduce the number of filters needed. Later I realised that is non-sense because the default is to use the logger... so you have to ignore it.
This answer nLog forum worked for us.
Reprinted below incase it ever gets lost.
What you can do is have two NLog.config files:
NLog.config
and NLog.Debug.config
In your code, somewhere close to the main method you can do:
#if DEBUG
LogManager.Configuration = new
XmlLoggingConfiguration("NLog.Debug.config");
#endif
Now if most of the configuration is the same you can perhaps use
include files - put everything htat is common (targets, etc.) into
NLog.common.config and reference it with
NLog.debug.config:
<include file="NLog.common.config" />
<logger name="*" minLevel="Trace" writeTo="debug" />
<logger name="*" minLevel="Info" writeTo="viewer" final="true" />
NLog.release.config:
<include file="NLog.common.config" />
<!-- Release rules -->
<logger name="*" minlevel="Info" writeTo="file" />
<logger name="*" minLevel="Error" writeTo="event" />
Let me know if it helps.
Jarek
If a little code is allowed at runtime then one can do this:
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<variable name="myLogLevel" value="Off" />
<targets>
<target name="logfile" xsi:type="File" fileName="file.txt" />
</targets>
<rules>
<logger name="*" minlevel="${var:myLogLevel}" writeTo="logfile" />
</rules>
</nlog>
And then at startup do this:
#if DEBUG
if (IsDebugMode)
{
LogManager.Configuration.Variables["myLogLevel"] = "Debug";
LogManager.ReconfigExistingLoggers();
}
#endif
See also: https://github.com/nlog/NLog/wiki/Filtering-log-messages#semi-dynamic-routing-rules

Transform that preserve namespace prefixes

I'm trying to insert an NLog custom config section into my Web.config using this XDT section:
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" throwExceptions="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xdt:Transform="InsertIfMissing" >
<targets>
<target xsi:type="File" name="logfile" fileName="H:\testLog.txt" layout="${longdate} ${uppercase:${level}} ${message}" />
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="logfile" />
</rules>
</nlog>
When I run the XDT transform, my Web.Debug.config contains:
<nlog throwExceptions="true" xmlns="http://www.nlog-project.org/schemas/NLog.xsd">
<targets>
<target d4p1:type="File" name="logfile" fileName="H:\testLog.txt" layout="${longdate} ${uppercase:${level}} ${message}" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance" />
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="logfile" />
</rules>
</nlog>
Typically, a namespace prefix is arbitrary, so transforming xsi to d4p1 would cause no issues.
However, I get a runtime exception in my application from NLog when I use d4p1. Manually changing the instances of d4p1 to xsi fixes the issue, but it subverts the utility of config transformation for me if the user needs to manually alter the file afterward.
Is there a way to preserve namespace prefixes using XDT?
We had exactly the same issue. I'm not sure why it suddenly started happening with a particular project, but the solution for us was to add the xsi namespace to the top level of the original configuration file (ie the base file the transformations work on). So...
<configuration>
... would become...
<configuration xmlns:xsi="http://www.nlog-project.org/schemas/NLog.xsd">
This did the trick.
An alternative approach that also worked was to apply the transforms on child elements of the nlog element.
Hope that helps someone.
I started to see this problem when I moved my xdt:Transform attribute from the target and rule tags to nlog. Moving them back to the original tags like this solved it:
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" throwExceptions="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets xdt:Transform="InsertIfMissing">
<target xsi:type="File" name="logfile" fileName="H:\testLog.txt" layout="${longdate} ${uppercase:${level}} ${message}" />
</targets>
<rules xdt:Transform="InsertIfMissing">
<logger name="*" minlevel="Trace" writeTo="logfile" />
</rules>
</nlog>

NLog Not Writing

I have added NLog to my project and in the development environment, it works fine.
I created a Setup file to deploy my application. The NLog.config file did not show up as a dependency in the Setup project. So, I added it as a file and it is present in the same directory as the exe file and App.config when deployed.
It does not do any logging. I don't know why. Here is the config file:
<?xml version="1.0" encoding="utf-8" ?>
<?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">
<variable name="day" value="${date:format=dd}" />
<variable name="month" value="${date:format=MM}" />
<variable name="year" value="${date:format=yyyy}" />
<variable name="verbose" value="${longdate} | ${level} | ${message} | ${exception:format=tostring,message,method:maxInnerExceptionLevel=5:innerFormat=shortType,message,method}}" />
<targets>
<target name="logfile" xsi:type="File" fileName="${basedir}/Logs/${year}${month}${day}.log" layout="${verbose}" />
</targets>
<rules>
<logger name="*" minlevel="Error" writeTo="logfile" />
</rules>
</nlog>
Any help would be great. Cheers!
Does NLog.config have the property "Copy to Output Directory" set as "Copy always"? https://stackoverflow.com/a/8881521/438760
Put your NLog configuration within the yourapp.exe.config file. Like so:
<configuration>
<configSections>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
</configSections>
<nlog>
<variable name="day" value="${date:format=dd}" />
...
<targets>
<target name="logfile" xsi:type="File" .../>
</targets>
<rules>
<logger name="*" minlevel="Error" writeTo="logfile" />
</rules>
</nlog>
</configuration>
I'm guessing the double xml version statements (line 1 and 2) was a copy / paste issue....
Probably a dumb question, but you have the minLevel set to Error. Are you actually encountering errors that would be logged, or have you tried lowering this to info or debug?
For me, the reason my NLog stopped logging was different to the above suggestions.
During updating the packages, something must have automatically added an nlog section to the bottom of my Web.config. It may have been ApplicationInsights. Obviously this took preference and, this caused it to stop checking my Nlog.config file.
Once I removed the section from my web.config it started magically reading from my nlog.config file again. I took care to take the extentions, targets and rules from web.config and ensure they were placed neatly in my nlog.config file instead.

Resources