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
Related
I am using nlog but on a physical device int the adriod build I have saved the config file as an embeded resource and it pics it up.
But the problem I have is since andriod does not have MyDocuments.
fileName="${specialfolder:folder=MyDocuments}/logs/${shortdate}.log
It will not save their it will go the users data directory am trying to investgate an issue from the customers device but instead it saves it to the data files , I cant root a customer device to get it.
I even tried xamrain essentials and it does exact same thing a folder called files under the app. I want the main folders like downloads so I can attach it to an email for the customer to send to me?
<?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="fileTarget"
fileName="${specialfolder:folder=MyDocuments}/logs/${shortdate}.log"
archiveFileName="${specialfolder:folder=MyDocuments}/logs/archive.{#}.log"
archiveEvery="Day"
archiveNumbering="Rolling"
maxArchiveFiles="7"
concurrentWrites="true"
keepFileOpen="false">
<layout xsi:type="CsvLayout" delimiter="Tab" quoting="Nothing" withHeader="true">
<column name="time" layout="${longdate:universalTime=true}" />
<column name="threadid" layout="${threadid}" />
<column name="level" layout="${level:upperCase=true}" />
<column name="callsite" layout="${callsite:includeSourcePath=true}" />
<column name="message" layout="${message}" />
<column name="stacktrace" layout="${callsite:includeSourcePath=true}" />
<column name="exception" layout="${exception:format=ToString}" />
</layout>
</target>
</targets>
<rules>
<logger name="*" writeTo="fileTarget" />
</rules>
</nlog>
I am accessing my log in the usual manor with in my classes
private static Logger logger = NLog.LogManager.GetCurrentClassLogger();
If I use this out of xarmain essnitials this is the result I get as well which is no good to me either.
string dirValue = FileSystem.AppDataDirectory.ToString();
Result of above gives me
"/data/user/0/com.companyname.appname/files"
I just want to zip the log then call the mail client to have it for the customer to click send to me.
I don't want to have a customer to root their device please help sometimes xamrains annoys me simple things are extra but harder stuff no problem.
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
I want to create a CSV file with multiple columns using NLog. There are not enough layouts for this (more than one message). I want to use event-properties for this.
sendEmailLogger.Log(LogLevel.Info, "01.01.2018");
Logger log = LogManager.GetCurrentClassLogger();
LogEventInfo theEvent = new LogEventInfo(LogLevel.Info, "CSVSendLogger", "custom value");
theEvent.Properties["xxx"] = 1234;
log.Log(theEvent);
NLog config file
<target name="CSVSendLogger" xsi:type="File"
fileName="${logDirectory}/send_log/log_mail.csv">
<layout xsi:type="CSVLayout">
<column name="Column1" layout="${event-properties:item=xxx}" />
<column name="Column2" layout="${message}" />
</layout>
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
We are working with NLog. we need to log messages to console with different JSON formats in different scenarios.
Ex: If exception occurred Below is the format
{
“id”:”5656”,
“uuid”:”xdd895-65454”,
“key”:”somekeyname”,
“message”: “** exception message **”,
“stack_trace”: “”**exception stack trace**”
}
If Normal log message
{
"id":"8898998"
“messge”: “Time taken to retrieve data from database”
“Time”: “1100” (in milli seconds)
}
Like this we have 10 scenarios.
Approach 1:
I tried creating different targets in web.config file in nlog section as follows
<target xsi:type="Console" name="console_exception" >
<layout xsi:type="JsonLayout">
<attribute name="id" layout="${mdlc:itemid}" />
<attribute name="uuid" layout="${mdlc:item=uuid}" />
<attribute name="loglevel" layout="${level}" />
<attribute name="timestamp" layout="${date}" />
<attribute name="message" layout="${message}" />
</layout>
</target>
<target xsi:type="Console" name="console_databaseTimeTaken" >
<layout xsi:type="JsonLayout">
<attribute name="id" layout="${mdlc:item=id}" />
<attribute name ="custommessage" layout="Time taken to retrieve data from database"/>
<attribute name="timestamp" layout="${date}" />
<attribute name="message" layout="${message}" />
</layout>
</target>
<rules>
<logger name="*" minLevel="Trace" writeTo ="console"/>
</rules>
I do not know how to set the target and layout programmatically.
So far I have found conditional based logging but, that is not a good approach.
Approach 2:
When logging the message we manually format the string message as per the need and then calling the log method
string logmessag= string.Format("\"id\":\"{0}\",\"messge\": {1}\"\",\"Time\": \"{2}(in milli seconds)\"", id, message, time);
Technologies used: Webapi2, Nlog 4.0.3
IDE: VS2017
Let us know the best approach to solve this problem
Thanks in advance
You'll need to use filters, either on <logger> elements directly, or a child <filters> config element which allows more complex conditions.
Eg. (assuming you can use the logger's name):
<rules>
<logger name='DB' minLevel="Trace" writeTo="console_databaseTimeTaken" final="true" />
<logger name='Error' minLevel="Trace" writeTo="console_exception" final="true" />
…
</rules>
<filter> elements allow more flexibility, but are still fairly limited. Ultimately you can extend NLog with custom conditions.