in Nlog section i have two target of csvlayout
<nlog throwExceptions="false" 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"
internalLogLevel="off" internalLogFile="c:\logs\nlog-internal.log">
<targets async="false">
<target name="MeLog" xsi:type="File" lineEnding="CRLF"
fileName="c:\logs\tempPro-${level}.csv" concurrentWrites="true" archiveFileName="c:\logs\archive\tempPro-${level}-{#####}.csv" archiveAboveSize="5024000" archiveNumbering="Sequence" maxArchiveFiles="10">
<layout type="CSVLayout" quoting="Auto" withHeader="true">
<column name="Logger" layout="${logger}" />
<column name="Date" layout="${date:format=s}" />
<column name="Level" layout="${level}" />
<column name="Message" layout="${message}" />
</layout>
</target>
<target name="ReLog" xsi:type="File" lineEnding="CRLF" fileName="C:\logs\Re-${level}.csv" concurrentWrites="true" archiveFileName="C:\Logs\archive\Re-${level}-{#####}.csv" archiveAboveSize="512000000" archiveNumbering="Sequence" maxArchiveFiles="2">
<layout type="CSVLayout" quoting="Auto" withHeader="true">
<column name="Logger" layout="${logger}"/>
<column name="Date" layout="${date:format=s}"/>
<column name="Level" layout="${level}"/>
<column name="Message" layout="${message}"/>
</layout>
</target>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="MeLog" />
<logger name="*" minlevel="Trace" writeTo="ReLog" />
</rules>
</nlog>
i want to log error dynamically by the file name.
for example on err1 i want log in meLog and for err2 i want tog in relog
public bool testMultiLog()
{
var config = new LoggingConfiguration();
var fileTarget = new FileTarget("ReLog")
{
FileName = "C:\\logs\\Re-${level}.csv"//,
Layout = "${longdate} ${level} ${message} ${exception}"
};
config.AddTarget(fileTarget);
config.AddRuleForOneLevel(LogLevel.Error, fileTarget);
LogManager.Configuration = config;
Logger logger = LogManager.GetLogger("Example");
logger.Trace("trace log message");
logger.Debug("debug log message");
logger.Info("info log message");
logger.Warn("warn log message");
logger.Error("error log message");
logger.Fatal("fatal log message");
return true;
}
But it is generating same error in both file
Use different logger names and then different log instances so you will be able to pick a desired log instance
<logger name="FirstLog" minlevel="Trace" writeTo="MeLog" />
<logger name="SecondLog" minlevel="Trace" writeTo="ReLog" />
<logger name="*" minlevel="Trace" writeTo="Log" />
Creating different logs:
Logger firstLogger = LogManager.GetLogger("FirstLog");
Logger secondLogger = LogManager.GetLogger("SecondLog");
Now firstLogger will log into MeLog and Log, secondLogger into ReLog and Log targets
But don't forget to define Log target
Related
I want to configure Nlog.config to log into InfluxDB the same as logging to Seq. I couldn't find any InfluxDB extension for NLog. Do I need just to implement my own NLog.Targets.Targetor there is already something that works with InfluxDB?
Have you tried NLog.Targets.InfluxDB ?
<nlog>
<extensions>
<add assembly="NLog.Targets.InfluxDB"/>
</extensions>
<targets>
<target type="InfluxDB"
name="influx"
Host="https://yourinfluxhost.com"
Bucket="MyBucket"
Token="inFluXApi=K3y"
Org="Organisation">
<field name="data1" value="${event-properties:data1:format=#}" />
<tag name="data2" value="${event-properties:data2:format=#}" />
</target>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="influx" />
</rules>
</nlog>
Ex.
log.Info("This field {#data1} and tag {#data2} are sent to InfluxDB", data1, data2);
See also: https://github.com/tomcheney/nlog-influx-target
The code
LogEventInfo theEvent = new LogEventInfo();
Logger offsetLogger = LogManager.GetLogger("ProdDataLog");
theEvent.Properties["Range"] = calc.Range;
offsetLogger.Log(theEvent);
Below is the target
<target name="ProdDataFile" xsi:type = "File"
fileName="${prodDataDir}ProdFile.csv"
archiveFileName="${prodDataDir}Archive/ProdFile.{#}.csv"
archiveNumbering="DateAndSequence"
archiveAboveSize="500000" archiveEvery="Day" maxArchiveFiles="30"
archiveDateFormat="yyyyMMdd">
<layout xsi:type="CsvLayout" delimiter="Comma" withHeader="true" quoting="Nothing">
<column name="Date" layout="${date:format=yyyy-MM-dd}" />
<column name="Time" layout="${time:HH:mm:ss.ffff}" />
<column name="Range" layout="${event-properties:Range}" />
</layout>
</target>
And the rule
<logger name="ProdDataLog" writeTo="ProdDataFile" final="true" />
The problem is the function
offsetLogger.Log(theEvent);
can take up to 200-300 ms.
Normal logs dont have the delay....but trying to create a csv log.
Any ideas?
I tried adding 'async' to the targets but then the csv wasn't written to at all.
NLog FileTarget uses KeepFileOpen=false by default, as it works across platforms and works with most file-viewers/monitors. But the performance is bad.
Try adding KeepFileOpen="true" like this:
<target name="ProdDataFile" xsi:type = "File"
keepFileOpen="true"
fileName="${prodDataDir}ProdFile.csv"
archiveFileName="${prodDataDir}Archive/ProdFile.{#}.csv"
archiveNumbering="DateAndSequence"
archiveAboveSize="500000" archiveEvery="Day" maxArchiveFiles="30"
archiveDateFormat="yyyyMMdd">
<layout xsi:type="CsvLayout" delimiter="Comma" withHeader="true" quoting="Nothing">
<column name="Date" layout="${date:format=yyyy-MM-dd}" />
<column name="Time" layout="${time:HH:mm:ss.ffff}" />
<column name="Range" layout="${event-properties:Range}" />
</layout>
</target>
Alternative you can use <targets async="true"> (Recommended if having many threads writing to the same File-Target). See also: https://github.com/NLog/NLog/wiki/Performance#file-logging-performance and Remember to Flush
Hello I am using for my console application NLog for logging.
With that being said I would like to log everything that happens in the console using NLog to set that up I am using the NLOG.config:
<target name="FullCSVFile" xsi:type="File" fileName="logs\internal_${date:format=yyyyMMdd_HHmmss}.log" keepFileOpen="true">
<layout xsi:type="CsvLayout">
<column name="Console" layout="${message}" />
<column name="Error" layout="${exception:format=ToString}" />
</layout>
</target>
<logger minlevel="Debug" name="*" writeTo="FullCSVFile" />
But this way the tool makes a new file every second passed in the console, but I want to make one file when the tool starts with that timestamp and write everything in this one. How would I do that?
The trick is to use the ambient property cached=true like this:
<target name="FullCSVFile" xsi:type="File" fileName="logs\internal_${date:format=yyyyMMdd_HHmmss:cached=true}.log" keepFileOpen="true">
<layout xsi:type="CsvLayout">
<column name="Console" layout="${message}" />
<column name="Error" layout="${exception:format=ToString}" />
</layout>
</target>
It will make layout render once, and then just return the same cached value.
See also: https://github.com/nlog/NLog/wiki/Cached-Layout-Renderer
To make it "perfect" then you could use ${processinfo:StartTime:format=yyyyMMdd_HHmmss:cached=true} then the timestamp would be stable even after reloading NLog-config.
Something like this could work, but I have not tested it:
<variable name="started" value="${date:format=yyyyMMdd_HHmmss}"/>
<target name="FullCSVFile" xsi:type="File" fileName="logs\internal_${started}.log" keepFileOpen="true">
<layout xsi:type="CsvLayout">
<column name="Console" layout="${message}" />
<column name="Error" layout="${exception:format=ToString}" />
</layout>
</target>
The idea is similar to the example from the documentation: https://github.com/nlog/nlog/wiki/Configuration-file#variables
My C# program has below 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"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="true"
throwExceptions="false"
internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">
<targets>
<target xsi:type="File" name="file1" fileName="file1.log" layout="${message}" />
<target xsi:type="File" name="file2" fileName="file2.log" layout="${message}" />
<target xsi:type="File" name="file3" fileName="file3.log" layout="${message}" />
<target xsi:type="File" name="file4" fileName="file4.log" layout="${message}" />
<target xsi:type="File" name="file5" fileName="file5.log" layout="${message}" />
<target xsi:type="File" name="file6" fileName="file6.log" layout="${message}" />
</targets>
<rules>
<logger name="logger1" minlevel="Debug" writeTo="file1" />
</rules>
</nlog>
My program needs to log messages to different sets of log files according user config, for example, sometimes write to "file1,file2" and sometimes write to "file2,file3,file4".
So, is it possible to customize the "writeTo" attribute in "logger1" during runtime according to the user configures?
Thanks a lot.
If you want to write to multiple files you can simply use a comma separated string for the "writeTo" attribute in Rule as "file1,file2,file3". There are 6 targets and rule says write to 3 files therefore file1,file2 and file 3 will be considered for logging.
But what you require is to do it at the run time. Below is the C# code.
Console.Out.WriteLine("Logget started");
Console.Out.WriteLine("");
Logger logger = LogManager.GetCurrentClassLogger();
var config = new LoggingConfiguration();
//Define targets
var fileTarget = new FileTarget();
config.AddTarget("file7", fileTarget);
var fileTarget2 = new FileTarget();
config.AddTarget("file8", fileTarget);
// Set target properties
fileTarget.FileName = "file7.log";
fileTarget.Layout = "${message}";
fileTarget2.FileName = "file8.log";
fileTarget2.Layout = "${message}";
// Define rules
var rule1 = new LoggingRule("*", LogLevel.Debug, fileTarget);
config.LoggingRules.Add(rule1);
var rule2 = new LoggingRule("*", LogLevel.Debug, fileTarget2);
config.LoggingRules.Add(rule2);
LogManager.Configuration = config;
logger.Trace("trace log message");
logger.Debug("debug log message");
logger.Info("info log message");
logger.Warn("warn log message");
logger.Error("error log message");
logger.Fatal("fatal log message");
logger.Log(LogLevel.Info, "Sample informational message");
Console.ReadKey();
}
As the code comments explained it defines new targets and rules. NLog.config will be redefined at the runtime.
Below is my NLog.config targets and rules
<targets>
<target xsi:type="File" name="file1" fileName="file1.log" layout="${message}" />
<target xsi:type="File" name="file2" fileName="file2.log" layout="${message}" />
<target xsi:type="File" name="file3" fileName="file3.log" layout="${message}" />
<target xsi:type="File" name="file4" fileName="file4.log" layout="${message}" />
<target xsi:type="File" name="file5" fileName="file5.log" layout="${message}" />
<target xsi:type="File" name="file6" fileName="file6.log" layout="${message}" />
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="file1,file2,file3" />
</rules>
These targets and rules will be redefined at the run time by our C# code and only file7.log and file8.log will be considered for logging.
This sounds trivial, but I somehow cannot manage to do it. I have the below 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" throwExceptions="true">
<variable name="logDirectory" value="${basedir}/App_Data/logs"/>
<targets>
<target name="file" xsi:type="AsyncWrapper">
<target xsi:type="File" name="f1" fileName="${logDirectory}\log1.txt" layout="${longdate} ${callsite} ${level} ${message} (File 1)"/>
</target>
<target xsi:type="File" name="fileGeneral" fileName="${logDirectory}\log_${shortdate}.txt" >
<layout xsi:type="Log4JXmlEventLayout"/>
</target>
<target xsi:type="File" name="fileRaven" fileName="${logDirectory}\raven_${shortdate}.txt" >
<layout xsi:type="Log4JXmlEventLayout"/>
</target>
</targets>
<rules>
<logger name="Raven.*" minlevel="Trace" writeTo="fileRaven"></logger>
<logger name="*" minlevel="Trace" writeTo="fileGeneral"></logger>
</rules>
</nlog>
This is ending up with Raven + ALL logs to 'log_[date].txt', and another copy of just RavenDB logs in 'raven_[date].txt'. How should this be done?
<logger name="Raven.*" minlevel="Trace" writeTo="fileRaven" final="true"></logger>
Where final="true" means that no more rules for Raven.* will be executed will do what you are asking (if I understood you correctly).
Unfortunately this is not possible.
The reason is that the loggers are evaluated from top to bottom, the first one matching will be used, and does below will not be evaluated.
In you case this means that when logging anything Raven related the first logger will be used and stops the flow.