Last active
October 5, 2017 08:30
-
-
Save oleksabor/aa0fc3b20f7a5e5641ab94c1376f34de to your computer and use it in GitHub Desktop.
sample exception generator to test NLog exception logging
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using NLog; | |
using NLog.LayoutRenderers; | |
using System; | |
using System.Linq; | |
using System.Text; | |
using System.Collections.Concurrent; | |
namespace NLogTest | |
{ | |
/// <summary> | |
/// renders exception starting from new line | |
/// with short type exception name followed by message | |
/// and stacktrace (optionally) | |
/// if exception is logged more than once (catched, logged and re-thrown as inner), stack trace is not written | |
/// </summary> | |
[LayoutRenderer("IndentException")] | |
public class IndentExceptionLayoutRenderer : LayoutRenderer | |
{ | |
/// <summary> | |
/// indent before exception type (default is tab) | |
/// </summary> | |
public string Indent { get; set; } | |
/// <summary> | |
/// indent between each stack trace line (default is two tab characters) | |
/// </summary> | |
public string StackTraceIndent { get; set; } | |
/// <summary> | |
/// is written before exception type name (default [) | |
/// </summary> | |
public string BeforeType { get; set; } | |
/// <summary> | |
/// is written after exception type name (default ]) | |
/// </summary> | |
public string AfterType { get; set; } | |
/// <summary> | |
/// separator between exception type and message | |
/// </summary> | |
public string Separator { get; set; } | |
/// <summary> | |
/// log stack trace or not (for console logger e.g.) | |
/// </summary> | |
public bool LogStack { get; set; } | |
/// <summary> | |
/// holds logged already exceptions just to skip surplus stack logging | |
/// </summary> | |
static ConcurrentQueue<Exception> _loggedErrors = new ConcurrentQueue<Exception>(); | |
public IndentExceptionLayoutRenderer() | |
{ | |
Indent = "\t"; | |
StackTraceIndent = "\t\t"; | |
BeforeType = "["; | |
AfterType = "]"; | |
LogStack = true; | |
Separator = " "; | |
} | |
protected override void Append(StringBuilder builder, LogEventInfo logEvent) | |
{ | |
var e = logEvent.Exception; | |
while (e != null) | |
{ | |
builder.AppendFormat("{1}{2}{0}{3}{4}", e.GetType().Name, Indent, BeforeType, AfterType, Separator); | |
builder.Append(e.Message); | |
if (LogStack) | |
{ | |
var stackTraceWasLogged = _loggedErrors.Contains(e); | |
if (!stackTraceWasLogged) | |
{ | |
builder.AppendLine(); | |
_loggedErrors.Enqueue(e); | |
builder.AppendFormat("{0}", e.StackTrace.Replace(" ", StackTraceIndent)); | |
} | |
if (_loggedErrors.Count > 50) | |
{ | |
_loggedErrors.TryDequeue(out Exception ex1); | |
_loggedErrors.TryDequeue(out Exception ex2); | |
} | |
} | |
e = e.InnerException; | |
if (e != null) | |
builder.AppendLine(); | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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="%temp%\nlog-internal.log"> | |
<!-- optional, add some variables | |
https://github.com/nlog/NLog/wiki/Configuration-file#variables | |
--> | |
<variable name="logfilename" value="NLogTest"/> | |
<targets> | |
<target xsi:type="ColoredConsole" | |
name="console" | |
useDefaultRowHighlightingRules="true" | |
detectConsoleAvailable="true" | |
layout="${message}${onexception:${newline}${exception:maxInnerExceptionLevel=10:format=shortType,message}}" /> | |
<target name="file" xsi:type="File" | |
fileName="${basedir}/${logfilename}.log" | |
keepFileOpen="false" | |
layout="${longdate} ${logger} ${message}${onexception:${newline}${exception:maxInnerExceptionLevel=10:format=shortType,message,stacktrace:separator=*:innerExceptionSeparator=
	}}" /> | |
</targets> | |
<rules> | |
<logger name="*" minlevel="Debug" writeTo="file" /> | |
<logger name="*" minlevel="Trace" writeTo="Console" /> | |
</rules> | |
</nlog> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<target xsi:type="ColoredConsole" | |
name="console" | |
useDefaultRowHighlightingRules="true" | |
detectConsoleAvailable="true" | |
layout="${level} ${message}${onexception:${newline}${IndentException:LogStack=false:separator=	:beforeType=:aftertype=}}" /> | |
<target name="file" xsi:type="File" | |
fileName="${basedir}/${logfilename}.log" | |
keepFileOpen="false" | |
layout="[${threadid}] ${longdate} ${level} ${logger} ${message}${onexception:${newline}${IndentException}}" /> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using NLog; | |
using NLogTest.Classes; | |
using System; | |
using System.Collections.Generic; | |
namespace NLogTest | |
{ | |
class Program | |
{ | |
static ILogger Log = LogManager.GetCurrentClassLogger(); | |
static void Main(string[] args) | |
{ | |
Log.Debug("starting"); | |
try | |
{ | |
new UnitOfWork().tryException(); | |
} | |
catch (Exception e) | |
{ | |
Log.Error(e, "failed to start NLogTest"); | |
Console.ReadKey(); | |
} | |
Log.Debug("the end"); | |
} | |
} | |
} | |
namespace NLogTest.Classes | |
{ | |
class UnitOfWork | |
{ | |
static ILogger Log = LogManager.GetCurrentClassLogger(); | |
public void innerException() | |
{ | |
throw new KeyNotFoundException("innerException"); | |
} | |
public void outerException() | |
{ | |
try | |
{ | |
innerException(); | |
} | |
catch (Exception e) | |
{ | |
throw new ArgumentException("outer exception", e); | |
} | |
} | |
public void tryException() | |
{ | |
try | |
{ | |
outerException(); | |
} | |
catch (Exception e) | |
{ | |
Log.Error(e, "tryException failure"); | |
throw new ArgumentException("bad try", e); | |
} | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I've asked a question about exception layout renderer at SO
However seems that writing custom layout renderer is not so complex
So here i will keep IndentExceptionLayoutRenderer.cs source code
This renderer allows to show exception using readable format (from my point of view) in the log (file or console)
NLog.exceptionIndent.config is a sample configuration that shows how layout can be parameterized for console and file logging