c#, Nlog and change target - c#

i am running windows service,
and i want when i run in debugto to write to console
and when as service to event viewer.
in powershell i set
New-EventLog –LogName Application –Source "mySource"
I have this nlog.config:
<nlog>
<targets>
<target name="debugger" type="Debugger" layout="${logger}::${message}"/>
<target name="console" type="Console" layout="${logger}::${message}"/>
<target name="file" type="File" layout="${longdate} ${logger}::${message}" fileName="${basedir}/Logs/${shortdate}.log"/>
<target name="eventLog" type="eventlog" layout="${logger}::${message}" source="mySource"/>
</targets>
<rules>
<logger name="" minlevel="Trace" writeTo="debugger"/>
<logger name="" minlevel="Trace" writeTo="console"/>
<logger name="*" minlevel="Trace" writeTo="file"/>
<logger name="*" minlevel="Debug" writeTo="eventLog" />
</rules>
</nlog>
i do init when service start :
public static void InitLogger()
{
NLog.Targets.Target target = null;
target = LogManager.Configuration.FindTargetByName("eventlog");
NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Info);
LogManager.Configuration.Reload();
}
to test this i change it in both cases to write to "eventlog"
even in debug mode. but it is not working correctly when using the event viewer (VS is running in admin mode)
i set in each class
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
what is missing?

This line will load the NLog.config and lookup a named target:
target = LogManager.Configuration.FindTargetByName("eventlog");
This line will discard the original NLog config (with all rules and targets) and create new one with a single target:
NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Info);
This line will not do anything:
LogManager.Configuration.Reload();
I guess you are trying to add an extra target to the existing configuration. This can be done like this (Replacing all the above code):
LogManager.Configuration.AddRule("*", LogLevel.Info, target):
LogManager.ReconfigExistingLoggers();
Btw. if you don't configure the Source-property for the EventLog-target, then it will use AppDomain.FriendlyName

Related

Nlog not loggin to File

my nlog not creating files. I Use the same configuration in another project and everythink is Ok, but in new project nlog not create new files.
Nlog config :
<?xml version="1.0" encoding="utf-8" ?>
autoReload= "true"
internalLogLevel =" Trace"
internalLogFile ="c:\temp\internal-nlog.txt">
<targets>
<target name="file" xsi:type="File"
layout="${longdate} ${logger} ${message}${exception:format=ToString}"
fileName="C:\beka\logs\logfile.txt"
/>
<target name="exceptions" xsi:type="File"
layout="${longdate} ${logger} ${message}${exception:format=ToString}"
fileName="C:\beka\logs\logfileExceptions.txt"
/>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="file" />
<logger name="*" minlevel="Error" writeTo="exceptions" />
</rules>
On the console I can see that the log has been called but its not sent to a file.
I think the problem can be in c:\temp\internal-nlog.txt becouse this file has references to another project. And when i start another project internal-nlog.txt is update but when i start this project internal-nlog-txt doesnt update
Nlog action = content,
Copy to outputDirectory = copy if newer

NLog for asp.net core is not filtering Microsoft logs

I have the following nlog.config file in ASP.NET Core 2.1 project. However, it's logging messages from every logger (including Microsoft logger) to console.
<?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="Error"
internalLogFile="${specialfolder:folder=UserProfile}\nlog\internal-nlog.txt">
<variable name="fullLayout" value="${shortdate} [${uppercase:${level}}] ${logger}: ${message} ${exception:format=tostring} url: ${aspnet-request-url}" />
<!-- enable asp.net core layout renderers -->
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
<!-- the targets to write to -->
<targets>
<!-- write to console -->
<target name="console" xsi:type="ColoredConsole" layout="${fullLayout}" />
<!-- write to file -->
<target xsi:type="File"
name="allfile"
fileName="${defaultDirectory}/test-api-all.log"
archiveEvery="Day"
archiveFileName="${defaultDirectory}/test-api-all-${#}.log"
archiveNumbering="Date"
archiveDateFormat="yyyy-MM-dd"
maxArchiveFiles="5"
layout="${fullLayout}" />
<!-- another file log, only own logs. Uses some ASP.NET core renderers -->
<target xsi:type="File"
name="ownFile-web"
fileName="${defaultDirectory}/test-api-app.log"
archiveEvery="Day"
archiveFileName="${defaultDirectory}/test-api-app-${#}.log"
archiveNumbering="Date"
archiveDateFormat="yyyy-MM-dd"
maxArchiveFiles="5"
layout="${fullLayout}" />
</targets>
<!-- rules to map from logger name to target -->
<rules>
<!--All logs, including from Microsoft-->
<logger name="*" minlevel="Trace" writeTo="console" />
<!--Skip non-critical Microsoft logs and so log only own logs-->
<logger name="Microsoft.*" maxLevel="Info" final="true" />
<logger name="*" minlevel="Trace" writeTo="ownFile-web" />
</rules>
</nlog>
I do not have any logging settings in appsettings.json files. All logger configuration in in nlog.config. In the Program.cs, I'm registering NLog like:
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureLogging(logging => logging.ClearProviders())
.UseNLog()
.Build();
How can I filter out Microsoft logs?
EDIT:
Above configuration started working without a problem the next day without me making any changes :O
Maybe this will work:
<!-- rules to map from logger name to target -->
<rules>
<!--Skip non-critical Microsoft logs and so log only own logs-->
<logger name="Microsoft.*" maxLevel="Info" final="true" />
<logger name="*" minlevel="Trace" writeTo="console" />
<logger name="*" minlevel="Trace" writeTo="ownFile-web" />
</rules>
The order of the logging rules are important, as the rules are matched from the top. See also https://github.com/NLog/NLog/wiki/Configuration-file#rules
The order of your logging rules seems to be correct. I suggest trying to double check if your updated nlog.config file is being copied to the build directory (e.g. \bin\Debug\netcoreapp2.1\nlog.config)
I kind of encountered the same issue, but found out that debugging using Visual Studio, it sometimes doesn't really copy the nlog.config file to your build directory. So the solution is to Clean the project first, then Build, and finally Debug.

Writing NLog messages to a different target

I want to log messages to file based on a condition. For this I am first writing all the log messages to Memory type and checking the condition in my code behind. I am trying to write to file type, those stacked up (memory) logs only if the condition is true. Here is how my log looks.
<targets>
<target name="file" xsi:type="AsyncWrapper" queueLimit="5000" overflowAction="Discard">
<!--auto-archive above 5 MB or daily. Max archives = 3 days
write to <installdir>/logs/DebugLog.log-->
<target xsi:type="File" name="debugFile" fileName="${basedir}/logs/DebugLog.log"
layout="${message}"
archiveFileName="${basedir}/logs/archives/DebugLog-${shortdate}.{#}.txt"
archiveAboveSize="5242880"
archiveEvery="Day"
archiveNumbering = "Rolling"
maxArchiveFiles="3" />
</target>
<target xsi:type="Memory" name="MemoTarget" layout="${longdate} : ${message}"/>
</targets>
<rules>
<!-- turn logging on by setting minLevel="Debug" (no service restart necesary, it detects the setting change automatically) -->
<logger name="*" minlevel="Debug" writeTo="MemoTarget"/>
<logger name="MyFileLogger" minlevel="Debug" writeTo="debugFile"/>
</rules>
Here is the code behind.
if (dTimeRTaken > 7000)
{
StringBuilder stringBuilder = new StringBuilder();
var target = (MemoryTarget)LogManager.Configuration.FindTargetByName("MemoTarget");
var logger = LogManager.GetLogger("MyFileLogger");
foreach (var loggingEvent in target.Logs.ToArray())
{
stringBuilder.AppendLine(loggingEvent);
}
logger.Debug(stringBuilder);
LogManager.Flush();
}
The problem here is flush is not working and memory target messages are being appended. The file contents are like
1
12
123
1234
I want the output as 1 2 3 4
Maybe use a BufferingWrapper around your file-target. Like this:
<targets>
<target name="memoFile" xsi:type="BufferingWrapper" bufferSize="10000" overflowAction="Discard">
<target name="asyncFile" xsi:type="AsyncWrapper" queueLimit="5000" overflowAction="Discard">
<target name="debugFile" xsi:type="File" fileName="${basedir}/logs/DebugLog.log">
</target>
</target>
</target>
</targets>
<rules>
<!-- MyFileLogger writes directly to file without being stalled in buffer -->
<logger name="MyFileLogger" minlevel="Debug" writeTo="asyncFile" final="true" />
<!-- All other loggers writes to memory buffer and waits for flush -->
<logger name="*" minlevel="Debug" writeTo="memoFile" final="true" />
</rules>
But if you want manual control of the logevents without BufferingWrapper, then you should just ensure to configure the logging rules like this:
<rules>
<!-- MyFileLogger writes directly to file without being stalled in buffer -->
<logger name="MyFileLogger" minlevel="Debug" writeTo="asyncFile" final="true" />
<!-- All other loggers writes to memory buffer and waits for flush -->
<logger name="*" minlevel="Debug" writeTo="MemoTarget" final="true" />
</rules>

NLog weirdness - extra fields displayed

I use NLog for debugging/tracing in my app. What's happening is that I am seeing some extra stuff in the output. This is C#/VisualStudio on the Mac, targeting iOS.
Here is an example...
I'm using a target of type "Debugger", and my layout line is:
<layout="${time} ${level} ${callsite}:${callsite-linenumber} ${message}"/>
The call to the logger is:
log.Debug("Added New Key. Code = {0}", code);
And the output is:
AppleLibrary.PasswordMgr: 16:04:36.4064 Debug
AppleLibrary.PasswordMgr.SavePassword:55 Added New Key. Code = -34018
Every debug line starts with <logger name>:
Its even worse when I use a target type of "Console" with exactly the same layout. A call like this:
log.Debug("Started Application");
ends up with this:
2017-06-14 16:04:23.673 MyApp.iOS[11942:6245589] 16:04:23.6374 Debug MyApp.iOS.Application.Main:14 Started Application
in this case every line starts with: 2017-06-14 16:04:23.673 MyApp.iOS[11942:6245589], which looks like the long date, logger name and thread/tick information.
Note that this does not happen with my file target, even though it uses exactly the same layout! The above call shows this in the logfile.txt:
16:04:23.6374 Debug MyApp.iOS.Application.Main:14 Started Application
Which is exactly what I want.
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" throwExceptions="true">
<targets>
<target name="logfile"
xsi:type="File"
header="############STARTING RUN ${date} ${time}"
archiveOldFileOnStartup="true"
maxArchiveFiles="5"
fileName="/Users/Paul/Dev/MyApp/MyApp.iOS/logfile.txt"
layout="${time} ${level} ${callsite}:${callsite-linenumber} ${message}"/>
<target name="console" xsi:type="Console"
layout="${time} ${level} ${callsite}:${callsite-linenumber} ${message}"/>
<target name="debugger"
xsi:type="Debugger"
layout="${time} ${level} ${callsite}:${callsite-linenumber} ${message}"/>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="logfile" />
<logger name="CoreLibrary.*" minlevel="Trace" writeTo="debugger" enabled="false" />
<logger name="AppleLibrary.*" minlevel="Debug" writeTo="debugger" />
<logger name="MyApp.iOS.*" minlevel="Debug" writeTo="console" />
</rules>
</nlog>
I'd appreciate any pointers as to what I'm misunderstanding here.
Thanks.
Paul.

NLog not writing from referenced dll

I have a dll that I created for sending email. I have NLog included in that project that logs to c:\logs{logfilename.log} <--This is either an error or event log.
When working with the project locally it works just fine and writes out to the file during testing.
When I reference the emailing dll from another project that also has NLog it is not outputting to the log files. The config from the email dll is in the bin directory of the new project that is referencing it. I can create logs from the new project using a trace but it didn't print the email dll entries. Is there something special I need to do in my new project to get the email dll to write the logs? I've searched for an answer to this but the keywords do not produce the results I would need. I'm new to NLog, please be gentle.
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">
<targets>
<target xsi:type="File"
name="default"
layout="${longdate} - ${level:uppercase=true}: ${message}${onexception:${newline}EXCEPTION\: ${exception:format=ToString}}"
fileName="C:\logs\default.log"
keepFileOpen="false"
archiveFileName="C:\logs\NTC_Utility\default.{##}.log"
archiveNumbering="Sequence"
archiveEvery="Day"
maxArchiveFiles="30"
/>
<target xsi:type="File"
name="error"
layout="${longdate} - ${level:uppercase=true}: ${message}${onexception:${newline}EXCEPTION\: ${exception:format=ToString}}"
fileName="C:\logs\error.log"
keepFileOpen="false"
archiveFileName="C:\logs\NTC_Utility\error.{##}.log"
archiveNumbering="Sequence"
archiveEvery="Day"
maxArchiveFiles="90"
/>
<target xsi:type="File"
name="emailLog"
layout="-------------------- ${message} (${longdate}) --------------------${newline}
From: ${event-context:item=From}${newline}
To: ${event-context:item=To}${newline}
BCC: ${event-context:item=Bcc}${newline}
CC: ${event-context:item=CC}${newline}
Subject: ${event-context:item=Subject}${newline}
Body: ${event-context:item=Body}${newline}
Attachments: ${event- context:item=Attachments}${newline}--------------------------------------------------------------------${newline}"
fileName="C:\logs\EmailLog.log"
keepFileOpen="false"
archiveFileName="C:\logs\NTC_Utility\EmailLog_.{##}.log"
archiveNumbering="Sequence"
archiveEvery="Day"
maxArchiveFiles="90"
/>
</targets>
<rules>
<logger name="*" writeTo="error" level="Error" final="true" />
<logger name="*" writeTo="emailLog" level="Info" final="true" />
<logger name="*" writeTo="default" minLevel="Debug" />
</rules>
</nlog>
This is my Log.cs from the compiled utility dll
using NLog;
namespace NTC.Utility
{
internal static class Log
{
public static Logger Instance { get; private set;}
static Log()
{
LogManager.ReconfigExistingLoggers();
Instance = LogManager.GetCurrentClassLogger();
}
}
}
This line calls my Logging Method after the email is sent.
LogEmailSent(imperEmail);
Which calls this method...
private void LogEmailSent(EmailMessage email)
{
Logger logger = LogManager.GetCurrentClassLogger();
LogEventInfo thisEvent = new LogEventInfo(LogLevel.Info, "default","Email Sent");
thisEvent.Properties["From"] = email.From;
thisEvent.Properties["To"] = EmailCollectionToCsv(email.ToRecipients);
thisEvent.Properties["Bcc"] = EmailCollectionToCsv(email.BccRecipients);
thisEvent.Properties["CC"] = EmailCollectionToCsv(email.CcRecipients);
thisEvent.Properties["Subject"] = email.Subject;
thisEvent.Properties["Body"] = email.Body;
thisEvent.Properties["Attachments"] = AttachmentCollectionToCsv(email.Attachments);
logger.Log(thisEvent);
}
Ok, so I finally figured out what was going on after logging the trace... I noticed that it was only showing the error rule as loaded.... so I moved the "emaillog" rule above the "error" rule and all worked perfectly.
check your nlog.config
if not. are there any posibilities some configurations are injected within the code..
http://www.codeproject.com/Articles/10631/Introduction-to-NLog

Categories

Resources