There seems to be a lot of information and documentation on how to log extra information when an exception is present, but I am having trouble trying to work out how to create a target that is essentially a honeypot for exceptions. Rather than sifting through various log files trying to see if any exceptions were logged, I'd just like a copy of all exceptions to go to a specific target that writes to an exceptions.log file.
How do I do this?
The following types can be configured: Targets - the destinations of a logevent, e.g. file, database, console. Layout - the layout e.g. json, csv, plain-text (default) Layout renderers - the template markers, e.g. ${message}, ${exception}, ${date}
NLog supports the following levels: Trace - Very detailed log messages, potentially of a high frequency and volume. Debug -Less detailed and/or less frequent debugging messages. Info - Informational messages.
I can't say that I have actually tried this, but you might be able to use a when filter and a condition to achieve what you want.
Here is an example from the condition
page:
<rules>
<logger name="*" writeTo="file">
<filters>
<when condition="length(message) > 100" action="Ignore" />
<when condition="equals('${logger}','MyApps.SomeClass')" action="Ignore" />
<when condition="(level >= LogLevel.Debug and contains(message,'PleaseDontLogThis')) or level==LogLevel.Warn" action="Ignore" />
<when condition="not starts-with('${message}','PleaseLogThis')" action="Ignore" />
</filters>
</logger>
</rules>
To achieve your goal, you might make a filter
like this:
<rules>
<logger name="*" writeTo="file">
<filters>
<when condition="length('${exception}') > 0" action="Log" />
</filters>
</logger>
</rules>
The idea being that you only want to log the message if the length of the exception string is > 0. Some of the when condition
examples used the NLog LayoutRenderer syntax (e.g. ${message}
) and some didn't (e.g. message
). I'm not sure which is correct or which syntax to use in which situation. The example I posted directly above might cause messages to be logged ONLY if there is an exception present. You should also be able to configure such that your messages to one target are logged "normally" and messages to your "ExceptionHoneypotTarget" are logged only if an exception is present.
Maybe something like this:
<rules>
<logger name="*" writeTo="ExceptionHoneypot">
<filters>
<when condition="length('${exception}') > 0" action="Log" />
</filters>
</logger>
<logger name="*" writeTo="file">
</logger>
</rules>
As I mentioned early on, I haven't actually tried any of this, but it seems like you should be able to do it, hopefully similar to what showed above.
Alternatively, you could use a FilteringWrapper around your HoneypotTarget. The configuration might look something like this:
<?xml version="1.0" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="Honeypot" xsi:type="FilteringWrapper"
condition="length('${exception}')>0">
<target xsi:type="File" fileName="${basedir}/Honeypot.txt" />
</target>
<target name="normal" xsi:type="File" fileName="${basedir}/Log.txt" />
</target>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="Honeypot,normal" />
</rules>
</nlog>
I based the FilteringWrapper
example on an example from from here. The way it should work, if my configuration is correct, is that all messages will be logged to "Log.txt" and messages with a non-null exception will be logged to "Honeypot.txt".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With