For a simple prototype program, I am using NLog with ColoredConsole and File targets, with simple layouts (see configuration file below).
And I am using # operator to destructure objects :
Logger.Debug("values : {#result}", aRandomObject);
where aRandomObject could be anything.
Unfortunately, for both the Console and File targets, by default the destructured object is rendered in json without any formatting. Pretty convienient for computers, but much harder to read for humans.
Instead, I would like to find a way to print my objects as formatted json (with indentations and line breaks) if it's possible with Nlog.
I don't want to render the whole target as a json (as a "JsonLayout" allows), but only the objects logged with #.
Here's the full NLog configuration :
<?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"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="true"
throwExceptions="true"
internalLogLevel="Off" internalLogFile="c:/temp/nlog-internal.log">
<variable name="baseLogDirectory" value="C:\Logs\Thing"/>
<targets>
<target xsi:type="File" name="file" fileName="${baseLogDirectory}\${cached:cached=true:inner=${date:format=yyyyMMdd_HHmmss}}_${processid}.log"
layout="${longdate} ${uppercase:${level}} ${callsite} ${message} ${exception:format=toString,Data}" />
<target name="console" xsi:type="ColoredConsole" layout="${longdate}|${pad:padding=5:inner=${level:uppercase=true}}|${message}" />
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="file, console" />
</rules>
</nlog>
Thank you
Related
Just started working with NLog and have it running with the following configuration:
<?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"
throwConfigExceptions="true">
<targets async="true">
<target name="logfile"
xsi:type="File"
layout="${longdate} [${level:uppercase=true}] (${threadid}) ${logger}: ${message} ${onexception:${newline}Exception\: ${exception:format=type,message,method,stacktrace:maxInnerExceptionLevel=5:innerFormat=shortType,message,method}}"
fileName="logs/current.log"
archiveFileName="logs/Archive/${ticks}.log"
archiveEvery="Minute"
archiveOldFileOnStartup="true"
keepFileOpen="false"
/>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="logfile" />
</rules>
</nlog>
Everything is working as expected. However, I need to have the rotated file be in the format of ${archive_start_ticks}_${arhive_end_ticks}.log rather than the current format which is ${archive_end_ticks}.log.
I was initially hoping I could name the active log file as ${ticks} and then, on archive, use the active log file's name as a parameter into the archive file to compose some like:
fileName="logs/${ticks}"
archiveFileName="logs/Archive/${fileName}_${ticks}.log"
Of course, there's two issues here:
Using ${ticks} for the active file creates a new file for each log line.
I can't seem to reference the original fileName as an input variable into archiveFileName.
That said, what is the best way to achieve this goal? Is this something NLog can handle natively or with minor extensions?
Updating in case anyone ever cares:
I bailed on using the FileTarget with configurations and wrote my own Target wrapped in a BufferedWrapper. On each flush, I use the first and last LogEvents to determine the timespan which gives me what I need to for the required file format with little custom code to support.
As per tutorials, when some exception is thrown, it will write exceptions in a text file. But in my case, when some exception is thrown, I am not able to detect that file of exception in any of the folder.
I had install Nlog.config from nuget and used
var _logger = LogManager.GetCurrentClassLogger();
//In Controller
_logger.Error(ex, "StringErrorMessage");
and this is my Nlog.config file
<?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"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="true"
throwExceptions="false"
internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">
<variable name="myvar" value="myvalue"/>
<variable name="logDirectory" value="${basedir}/logs/${shortdate}"/>
<targets>
<target name="logfile" xsi:type="File" fileName="${logDirectory}/file.txt" />
</targets>
<rules>
<!-- add your logging rules here -->
<logger name="*" minlevel="Error" writeTo="logfile" />
</rules>
</nlog>
Old question but someone still might look at it.
Does the file c:\temp\nlog-internal.log exist ?
If not, set Copy to Output Directory property of your nlog.config file to Copy always.
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>
I have a problem with NLog.
I have configured the NLog in the file Nlog.config as following:
<?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="true"
internalLogLevel="Trace"
internalLogFile="d:\temp\nlog-internal.log">
<target xsi:type="File" name="log" fileName="${basedir}\logs\${date:format=dd}.log"
layout="${longdate} ${uppercase:${level}} ${message}" />
<rules>
<logger name="*" minlevel="Debug" writeTo="log" />
</rules>
</nlog>
And I get an error that target log is not found. I really don't know what I can do, maybe someone had similar problem.
I'm using .NET 4.5.
The Nlog.config is in the main directory of the project.
I set up the permissions to full access in the directories.
I tried to move the configuration into the web.config file, but the error still appear.
2016-07-26 09:17:25.6353 Warn Skipping unknown node: target
2016-07-26 09:17:25.6353 Trace ParseRulesElement
2016-07-26 09:17:25.6623 Error Error in Parsing Configuration File. Exception: NLog.NLogConfigurationException: Exception occurred when loading configuration from D:\Project\NLog.config ---> NLog.NLogConfigurationException: Target log not found.
w NLog.Config.XmlLoggingConfiguration.ParseLoggerElement(NLogXmlElement loggerElement, IList`1 rulesCollection)
w NLog.Config.XmlLoggingConfiguration.ParseRulesElement(NLogXmlElement rulesElement, IList`1 rulesCollection)
w NLog.Config.XmlLoggingConfiguration.ParseNLogElement(NLogXmlElement nlogElement, String filePath, Boolean autoReloadDefault)
w NLog.Config.XmlLoggingConfiguration.ParseTopLevel(NLogXmlElement content, String filePath, Boolean autoReloadDefault)
w NLog.Config.XmlLoggingConfiguration.Initialize(XmlReader reader, String fileName, Boolean ignoreErrors)
Structure of the project:
Update (after Michel A. answer): I have also properties in NLog.config file
Build Action = Content
Copy to Output Directory = Copy always
Update2: I found the solution. The problem was that I have the backslashes instead of forward slashes
Wrong syntax:
fileName="${basedir}\logs\${date:format=dd}.log"
Correct syntax:
fileName="${basedir}/logs/${date:format=dd}.log"
Update2: I found the solution. The problem was that I have the backslashes instead of forward slashes
I'm pretty sure that wasn't the problem. The paths aren't evaluated on registering the target. Also on Windows the kind of slashes don't matter.
The problem is here that the XML is lacking the <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"
autoReload="true"
throwExceptions="true"
internalLogLevel="Trace"
internalLogFile="d:\temp\nlog-internal.log">
<target xsi:type="File" name="log" fileName="${basedir}\logs\${date:format=dd}.log"
layout="${longdate} ${uppercase:${level}} ${message}" />
<rules>
<logger name="*" minlevel="Debug" writeTo="log" />
</rules>
</nlog>
It should be:
<?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="true"
internalLogLevel="Trace"
internalLogFile="d:\temp\nlog-internal.log">
<targets>
<target xsi:type="File" name="log" fileName="${basedir}\logs\${date:format=dd}.log"
layout="${longdate} ${uppercase:${level}} ${message}" />
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="log" />
</rules>
</nlog>
Hint: You get auto completion and error checking if you install the NLog.Schema package
Is your NLog config file being copied into your bin folder ?
(check property file in Visual Studio)
I try to test NLog performance (latest version) with settings:
<?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">
<variable name="basePath" value="c:\logs\" />
<variable name="msgFormat" value="${message}" />
<targets async="true">
<target name="file"
xsi:type="File"
fileName="${basePath}/${logger}/${date:format=yyyy}/${date:format=MMMM}/log-${date:format=yyMMdd}-${level}.log"
layout="${msgFormat}"
concurrentWrites="true" />
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="file"/>
</rules>
</nlog>
and run this code:
var msg = "this is example string for logging test. it's not very long, but not very short";
var count = 20000;
Parallel.For(0, count, x => nlog.Info(msg));
NLog writes to file, but when file size reaches 1MB it stops writing. I try to use simple for loop, but it doesn't helped me.
And i try to use internal logging, but there is no errors, by the way i see there this strings:
2013-04-01 11:36:18.2458 Trace Opening
c:\logs/NLogTest/2013/April/log-130401-Info.log with
concurrentWrite=False
It's very strange, because concurrentWrites default value is true, furthermore I've set this value in config.
The problem lies in the default value of the AsyncWrappers QueueLimit, which is 10000.
The value determines how big the queue of messages to write are allowed to be, the problem arises because all 20000 messages are queued before anything is written to the file, which causes NLog to discard the last 10000 messages.
Unfortunately this cannot be changed when using the async attribute, you have to define the AsyncWrapper manually to be able to control the QueueLimit, which is done like 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">
<variable name="basePath" value="c:\logs\" />
<variable name="msgFormat" value="${message}" />
<targets async>
<target name="asyncWrapper" xsi:Type="AsyncWrapper" queueLimit="20000">
<target name="file"
xsi:type="File"
fileName="${basePath}/${logger}/${date:format=yyyy}/${date:format=MMMM}/log-${date:format=yyMMdd}-${level}.log"
layout="${msgFormat}"
concurrentWrites="true" />
</target>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="file"/>
</rules>
</nlog>
Where QueueLimit is set to 20000.
You could also changed the OverflowAction if you need to do something other the discard messages not put in the queue, see AsyncWrapper documentation for more information. The options are Block, Discard or Grow.