Ignoring NLog Configuration referenced in other assembly - c#

I have a unique problem with the NLog. I have a third-party assembly we use into our project. They have used the NLog into their project and referenced NLog configuration into their configuration which I don't have access to.
I initially had a problem even adding the NLog to a project since both version of dlls were different. I had to download the source code of NLog and change the assembly name since alias was not working for me (OR I didn't know how to use it.)
After giving my own assembly name, NLog started wotrking but.. It started logging third-party log information too with it. Looks like they were not careful enough when defining the logger and they just defined (*). Now my question is, how do I avoid their stuff from logging in to my file? I have also tried setting it to final = true.
Here is how my very simple configuration file looks like.
<?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">
<!--
See https://github.com/nlog/nlog/wiki/Configuration-file
for information on customizing logging rules and outputs.
-->
<targets>
<!-- add your targets here -->
<!--
<target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
layout="${longdate} ${uppercase:${level}} ${message}" />
-->
<target name="errorLog" xsi:type="File"
fileName="${basedir}/logs/error/${shortdate}.log"
layout="${longdate} ${uppercase:${level}} ${message}${onexception:${newline}EXCEPTION\: ${exception:format=ToString}}"
/>
<target name="generalLog" xsi:type="File"
fileName="C:/logs/${date:format=yyyy-MM-dd}.log"
layout="${longdate} ${uppercase:${level}} ${message}"/>
</targets>
<rules>
<!-- add your logging rules here -->
<logger name="Errors" writeTo="errorLog" minlevel="Warn"/>
<logger name="EBusiness.Model.*" writeTo="generalLog" levels="Trace,Debug,Info" final="true"/>
<!--
<logger name="*" minlevel="Trace" writeTo="f" />
-->
</rules>
</nlog>

If they are writing to the root logger, you should configure the root logger to not log to anywhere you care (maybe point it at a console logger) and your application can log to a specific logger which does write to your files.
Ugly, but should work.
For example:
Add this target:
<target name="console" xsi:type="Console" />
And Change the * rule to be:
<logger name="*" minlevel="Fatal " writeTo="console" />
Then, Add your own logger rule, say something like:
<logger name="MyNameSpace.*" minlevel="Trace" writeTo="logfile" final="true" />
Assuming you have a logfile target defined pointing at your file.

Related

Nlog logs location overwritten by code still logging happening at config location

NLog version - 4.4.3
Platform - .Net 4.5.2
Current NLog config -
<nlog autoReload="true" xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<variable name="layout" value="${longdate}|${level:uppercase=true}|${threadid}|${logger}|${message}" />
<variable name="logLocation" value="logs" />
<targets async="true">
<target name="debugger" xsi:type="Debugger" layout="${layout}" />
<target name="console" xsi:type="Console" layout="${layout}" />
<target name="logfile"
xsi:type="File"
fileName="${logLocation}\${processname}.log"
archiveFileName="${logLocation}\\${processname}.{###}.log"
archiveEvery="Day"
archiveAboveSize="2048000"
archiveNumbering="Rolling"
maxArchiveFiles="10"
concurrentWrites="false"
keepFileOpen="false"
layout="${layout}" />
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="logfile" />
<logger name="*" minlevel="Debug" writeTo="debugger" />
<logger name="*" minlevel="Info" writeTo="console" />
</rules>
</nlog>
Code to override location
LogManager.ReconfigExistingLoggers();
var target = (FileTarget)LogManager.Configuration.FindTargetByName<AsyncTargetWrapper>("logfile").WrappedTarget;
target.FileName = $#"..\..\..\..\logs\Foobar.log";
What is the current result?
When application/service starts it writes to overwritten location, but sometimes (not sure of scenario - maybe rollover) it start writing to config location.
What is the expected result?
Logs should always be written to overwritten location.
Did you checked the Internal log?
No
Please post full exception details (message, stacktrace, inner exceptions)
No Exception
Are there any workarounds? yes/no
Restart service/application.
Is there a version in which it did work?
No idea. This is the version we started with and sticking to.
Can you help us by writing an unit test?
Unit tests won't help as it is an intermittent scenario.
You have auto reload (<nlog autoReload="true”) enabled, so if it needs to reload (after sleep or change in config), you will lose the changes made in code.
The solution it so disable autoreload, or set the change after reload again. See code example:
static void Main(string[] args)
{
UpdateNLogConfig();
LogManager.ConfigurationReloaded += LogManager_ConfigurationReloaded;
log.Info("Entering Application.");
Console.WriteLine("Press any key to exit ...");
Console.Read();
}
private static void LogManager_ConfigurationReloaded(object sender, LoggingConfigurationReloadedEventArgs e)
{
UpdateNLogConfig();
}
private static void UpdateNLogConfig()
{
//note: don't set LogManager.Configuration because that will overwrite the nlog.config settings
var target = (FileTarget)LogManager.Configuration.FindTargetByName<AsyncTargetWrapper>("logfile").WrappedTarget;
target.FileName = $#"..\..\..\..\logs\Foobar.log";
LogManager.ReconfigExistingLoggers();
}
See also Combine XML config with C# config · NLog/NLog Wiki
Instead of doing target lookup, and modifying target properties directly. Then I suggest making use of the NLog Layout Logic.
<nlog autoReload="true" 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="${gdc:item=logFile:whenEmpty=log/${processname}.log}" />
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="logfile" />
</rules>
</nlog>
And then just assign the logLocation:
NLog.GlobalDiagnosticsContext.Set("logFile", $#"..\..\..\..\logs\Foobar.log");
Using GDC will also works very well with autoReload=true and no need to call LogManager.ReconfigExistingLoggers().

NLog config inside web.config or app.config ignored in version 4.5.11

Recently, we've updated some web and console application, to use a newer version of NLog, the latest 4.5.11.
Before, we've used a 4.4 version.
With this 4.4 version, we were able to set the NLog config inside the web.config or app.config file.
According to the documentation, this is still possible. However, with the newer version this does not work.
I only get some logging, if I copy/paste the same rules, into an nlog.config file.
Of course, I could do this for all my applications, but there is a chance we miss something.
What is the cause it isn't read from the web/app.config file anymore?
I also tried to set the throwExceptions="true" attribute, but it gave me no exceptions.
Also if I set the internal log file, on the attribute inside my web.config, it's still not working. The internal log, is also empty.
Tested with internalLogLevel="Info" and internalLogLevel="Trace"
If I set it in the Application_Start, I only have
2019-02-27 10:23:33.1899 Info Shutting down logging...
2019-02-27 10:23:33.1899 Info Logger has been shut down.
This is my Web.Config (partly)
<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"
internalLogFile="c:\temp\internal-nlog.txt" internalLogLevel="Info">
<targets>
<target name="logfile" xsi:type="File" fileName="${basedir}/Log/${shortdate}.log" layout="${date:format=dd-MM-yyyy HH\:mm\:ss.fff} [${level}] ${callsite} ${message}${onexception:${newline}EXCEPTION OCCURRED\:${exception:format=tostring}}" />
<target name="warnfile" xsi:type="File" fileName="${basedir}/Log/warn/${shortdate}.log" layout="${date:format=dd-MM-yyyy HH\:mm\:ss.fff} [${level}] ${callsite} ${message}${onexception:${newline}EXCEPTION OCCURRED\:${exception:format=tostring}}" />
</targets>
<rules>
<logger name="*" minlevel="Error" writeTo="logfile">
<filters>
<when condition="contains('${message}', 'ThreadAbortException')" action="Ignore" />
</filters>
</logger>
<logger name="*" level="Debug" writeTo="warnfile">
<filters>
<when condition="contains('${message}', 'ThreadAbortException')" action="Ignore" />
</filters>
</logger>
</rules>
</nlog>

Nlog with a class Library

I have a class library and configuration file in a separate place I want to use it
so I do the following
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(configurationFile , true);
LogManager.ReconfigExistingLoggers();
The configuration of NLog is part of a remote app.config looks like
<configuration>
<!-- ... -->
<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">
<targets>
<!--
Log in a separate thread, possibly queueing up to
5000 messages. When the queue overflows, discard any
extra messages
-->
<target name="file" xsi:type="AsyncWrapper" queueLimit="5000" overflowAction="Discard"
layout="${machinename} - ${level} - ${longdate} - ${callsite} - ${threadid} - ${message} ${exception:format=tostring}">
<target xsi:type="File" fileName="C:\logs/${level}.txt" />
</target>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="file" />
</rules>
</nlog>
</configuration>
the configuration object LogManager.Configuration always has the default values , any idea how to fix this.
When creating the first NLog Logger-object, then NLog will attempt to load the NLog.config (or app.config) automatically. Searching multiple locations:
https://github.com/nlog/NLog/wiki/Configuration-file#configuration-file-locations
You should try and activate the NLog internal logger and see why it doesn't find the "remote app.config" without doing manually loading (Can be enabled by code):
https://github.com/NLog/NLog/wiki/Internal-Logging
It is NOT recommended that the class library itself tries to modify the global NLog-configuration, as it might surprise the main-application. If wanting to have an isolated NLog configuration for your class-library, then you should consider creating an isolated NLog LogFactory:
https://github.com/NLog/NLog/wiki/Configure-component-logging
If you want to load an NLog.config from a non-standard path (not app.config). Then you can also do this:
https://github.com/NLog/NLog/wiki/Explicit-NLog-configuration-loading

nlog settings for ASP .NET Core 2.1 site

I'm trying to setup nlog to log into 3 separate log files. I want Entity Framework stuff to go to one log file (db.log). I want application-related logging only to go to another log file (own.log). And finally I want everything else (Microsoft stuff) to go to yet another file (all.log)
This is what I have below, but I can't get logging to work based on my requirements. What am I doing wrong?
Thanks in advance!
<?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"
internalLogFile="internal.log"
internalLogLevel="info" >
<!-- enable asp.net core layout renderers -->
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
<!-- the targets to write to -->
<targets>
<!-- write logs to file -->
<target xsi:type="File" name="allfile"
fileName="all-${shortdate}.log"
layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}" />
<!-- another file log, only own logs. Uses some ASP.NET core renderers -->
<target xsi:type="File" name="ownFile-web"
fileName="own-${shortdate}.log"
layout="${longdate}|${activityid}|${level:uppercase=true}|${message} ${exception:format=ToString}|${logger}|${all-event-properties}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" />
<target xsi:type="File" name="sqllogfile"
fileName="db-${shortdate}.log"
layout="${date}|${activityid}|${level:uppercase=true}|${message} ${exception}|${logger}|${all-event-properties}" />
</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.EntityFrameworkCore.*" minlevel="Trace" writeTo="sqllogfile" final="true" />
<logger name="Microsoft.*" maxlevel="Info" final="true" />
<!-- Our log -->
<logger name="*" minlevel="Trace" writeTo="ownFile-web" />
</rules>
</nlog>
Moving database log was the key. Also, after moving catch-all log to the bottom, I now get correct logging results.

Generic Logging and Specific Logging (using NLOG), Duplication of Logging

I am trying to create 2 loggers (using NLog)
First logger logs all the desired item to log in the solution
The other one traces specific items (I do it to keep things clean and focused, and only run trace here)
Below is the 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"
layout="${longdate} ${level} ${threadid} ${callsite} ${message}"
fileName="${basedir}\Logs\GatewayApplicationDebugAndErrorLog.txt"
archiveNumbering="Rolling"
maxArchiveFiles="10"
archiveAboveSize="10000000"/>
<target name="J1939Trace"
xsi:type="File"
layout="${longdate} ${level} ${threadid} ${callsite} ${message}"
fileName="${basedir}\Logs\J1939Trace.txt"
archiveNumbering="Rolling"
maxArchiveFiles="10"
archiveAboveSize="10000000"/>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="logfile" />
<logger name="J1939Trace" maxlevel="Trace" writeTo="J1939Trace" final="true" />
</rules>
and usage is shown below
private readonly Logger logger = LogManager.GetCurrentClassLogger(); // Generic Logger
private readonly Logger j1939Logger = LogManager.GetLogger("J1939Trace"); // Specific Logger.
What I observe is that the specific logger item is also logged in generic log item and I don't want that duplication. Any ideas what am I doing wrong?
Will this work?
From: NLog: How to exclude specific loggers from a specific rule?
Adding final="true" means that no more rules will be executed for the events produced by "SpammyLogger", but it applies only to the specified levels.(see https://github.com/nlog/nlog/wiki/Configuration-file#rules)
Make sure to read through all the comments in the answer.

Categories