Getting Logger Name into Excel file with NLog - c#

Thanks to Rolf's comment in this question:
NLog in C# with severity AND categories
I am able to record to a text file the category of log message (such as "Thermal" or "Database" or "Mechanical". I'm doing this simply by passing a name to the "GetLogger" method.
public MainWindow()
{
InitializeComponent();
var logger = NLog.LogManager.GetCurrentClassLogger();
logger.Info("Hello World");
(NLog.LogManager.GetLogger("Database")).Info("Here is a DB message");
(NLog.LogManager.GetLogger("Thermal")).Info("Here is a Thermal message");
}
The text file looks like this:
2018-05-13 17:40:47.7442|INFO|NLogExperiments.MainWindow|Hello World
2018-05-13 17:40:50.3404|INFO|Database|Here is a DB message
2018-05-13 17:40:50.3404|INFO|Thermal|Here is a Thermal message
which is pretty good. I might ask in a seperate question how to reformat it.
Now I would like to get these messages into a CSV (Excel) file. I'm using:
<target name="excelfile" xsi:type="File" fileName="nLog.csv" archiveAboveSize="50000000" archiveNumbering="Sequence" maxArchiveFiles="3">
<layout xsi:type="CsvLayout">
<!-- Layout Options -->
<column name="time" layout="${longdate}" />
<column name="level" layout="${level}"/>
<column name="name" layout="${name}"/>
<column name="message" layout="${message}" />
<column name="codeLine" layout="${event-context:item=codeLine}" />
</layout>
</target>
but the output is only:
time,level,name,message,codeLine
2018-05-13 17:40:47.7442,Info,,Hello World,
2018-05-13 17:40:50.3404,Info,,Here is a DB message,
2018-05-13 17:40:50.3404,Info,,Here is a Thermal message,
This isn't surprising. I used "name" as a guess.
What is the field in GetLogger called?
More generally, how do I know all the options I can put in the CSV layout?
Finally, is there a good tutorial on using NLog with CSV? I haven't found one.
Thanks,
Dave

What is the field in GetLogger called?
You're looking for ${logger} - see ${logger} docs
More generally, how do I know all the options I can put in the CSV layout?
You could use all layout renderers, see the list with all layout renderers
For options for the CSV formating, see CsvLayout docs

Related

Xamarin Forms Nlog not saving correctly to documents or download folder when using specialfolder:folder=MyDocuments

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.

Extra quotes when logging objects with NLog

I have a code that outputs interpolated string to the log with NLog.
Here is an example
_logger.LogDebug($"REQUEST {webRequest.RequestUri}", Id)
WebResponse webResponse = await _httpService.SendRequestAsync(webRequest);
var response = ParseResponse(webResponse);
_logger.LogDebug($"RESPONSE {(int)response.StatusCode} {JsonConvert.SerializeObject(response.Body)}", Id);
In this example, in a first case of calling the function _logger.LogDebug, I get the expected result as a result:
2019-04-15 09:27:24.5027 DEBUG e1701b07-d228-4543-a320-3cb1b7f2e4b0 REQUEST http://url/
But in the second case, the expected result is wrapped in additional quotes.
2019-04-15 09:27:57.2907 DEBUG "e1701b07-d228-4543-a320-3cb1b7f2e4b0 RESPONSE 200 [{...},{...}]"
Here is the _logger.LogDebug method
using NLog;
private static readonly ILogger Logger = LogManager.GetCurrentClassLogger();
public void LogDebug(string message, Guid id)
{
Logger.Debug($"{id.ToString()} {message}");
}
The result of the JsonConvert.SerializeObject(response.Body) is a string representation of array of json eg: [{"key":"value","key":"value"},{"key":"value","key":"value"}]
Here is a part of my Nlog.config
<targets>
<target name="csv" xsi:type="File" fileName="${shortdate}-${level}-services.log">
<layout xsi:type="CSVLayout" delimiter="Tab" withHeader="false">
<column name="time" layout="${longdate}" />
<column name="level" layout="${uppercase:${level}}"/>
<column name="message" layout="${message}" />
</layout>
</target>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="csv" />
</rules>
Why do I get additional quotes in the second case and how can I avoid it?
As per the docs,
CSV Options quoting - Default Quoting mode for columns.
Default: Auto
Possible values:
Auto - Quote only whose values contain the quote symbol, the separator or newlines (Slow)
All - Quote all column. Useful for data known to be multiline such as Exception-ToString
(Fast) Nothing - Quote nothing (Very Fast)
The default is Auto - which means it is quoting your string since it contains a quote, a tab (the separator) or a new line.
It is important it does this, so that the file is a valid CSV file (otherwise Excel etc don't know where the column data begins and ends.

Why can't I write with the event-properties in NLog?

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>

NLog how to log messages to console with different JSON layout formats in different scenarios

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.

NLog - how logging custom data to XML

Hi I need log temperature to XML file. I would like have XMl in this format
<logs>
<log>
<dateTime></dateTime/>
<value>x</dateTime/>
<log>
<log>
<dateTime></dateTime/>
<value>x</dateTime/>
<log>
<log>
<dateTime></dateTime/>
<value>x</dateTime/>
<log>
</logs>
First I tried log data to txt file with this configuration:
<targets>
<target name="logfile" xsi:type="File" fileName="users.log" layout="${date:format=yyyyMMddHHmmss} ${message}" />
<target name ="xmlFile" xsi:type="File" fileName="log.xml"/>
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="logFile" />
</rules>
Problems is that level Info log all data I need log only custom data. I dont know which type of level I must use when I want log only some string for example.
Second problem is how create XML layout?
That's not the intended purpose of nlog. It's purpose is to help you debugging your application by writing information to one or more log sources.
What you need to use is some sort of XML serializer which will write the tempature changes to a file.
Log "custom data": Use log.Trace(...), log.Debug(...), log.Info(...) to achieve different levels of logging.
XML Layout: Look into NLog.Layouts and NLog.LayoutRenderers. Note: this isn't a relatively easy task, and considering you couldn't figure out how to achieve different levels of logging, you may want to delay this task and work on your actual project.
Edit: Are you sure you can't just output the logged data to a normal text file in simple format, and when logging is complete, parse the data and write to an XML file?

Categories