Skip to content

Instantly share code, notes, and snippets.

@j5alive
Last active June 7, 2017 08:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save j5alive/2d24b40fa3e0b101b5f6d91b4af4aa5d to your computer and use it in GitHub Desktop.
Save j5alive/2d24b40fa3e0b101b5f6d91b4af4aa5d to your computer and use it in GitHub Desktop.
Raygun4Net automatic Breadcrumb logging with NLog
<?xml version="1.0"?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<extensions>
<add assembly="Raygun.Examples"/>
</extensions>
<targets>
<target name="breadcrumb" xsi:type="RaygunBreadcrumb" includeMethodInfo="false" />
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="breadcrumb" />
</rules>
</nlog>
using System.Diagnostics;
using System.Reflection;
using Mindscape.Raygun4Net;
using Mindscape.Raygun4Net.Breadcrumbs;
using NLog;
using NLog.Targets;
namespace Raygun.Examples
{
[Target("RaygunBreadcrumb")]
public class RaygunBreadcrumbTarget : TargetWithLayout
{
private static readonly Assembly SystemAssembly = typeof(Trace).Assembly;
private static readonly Assembly NLogAssembly = typeof(NLogTraceListener).Assembly;
public bool IncludeMethodInfo { get; set; }
protected override void Write(LogEventInfo logEvent)
{
var crumb = new RaygunBreadcrumb();
if (IncludeMethodInfo)
{
SetStackTrace(logEvent);
if (logEvent.UserStackFrame != null)
{
var method = logEvent.UserStackFrame.GetMethod();
crumb.ClassName = method.DeclaringType?.FullName;
crumb.MethodName = method.Name;
crumb.LineNumber = logEvent.UserStackFrame.GetFileLineNumber();
}
}
crumb.Message = logEvent.FormattedMessage;
if (logEvent.Properties != null)
{
foreach (var property in logEvent.Properties)
{
crumb.CustomData.Add(property.Key.ToString(), property.Value);
}
}
switch (logEvent.Level.Name)
{
case "Debug":
case "Trace":
crumb.Level = RaygunBreadcrumbLevel.Debug;
break;
case "Info":
crumb.Level = RaygunBreadcrumbLevel.Info;
break;
case "Warn":
crumb.Level = RaygunBreadcrumbLevel.Warning;
break;
case "Fatal":
case "Error":
crumb.Level = RaygunBreadcrumbLevel.Error;
break;
}
RaygunClient.RecordBreadcrumb(crumb);
}
private void SetStackTrace(LogEventInfo logEvent)
{
var stack = new StackTrace();
int userFrameIndex = -1;
for (int i = 0; i < stack.FrameCount; ++i)
{
var frame = stack.GetFrame(i);
var method = frame.GetMethod();
if (method.DeclaringType == GetType())
{
// skip all methods of this type
continue;
}
if (method.DeclaringType?.Assembly == SystemAssembly)
{
// skip all methods from System.dll
continue;
}
if (method.DeclaringType?.Assembly == NLogAssembly)
{
// skip all methods from NLog
continue;
}
userFrameIndex = i;
break;
}
if (userFrameIndex >= 0)
{
logEvent.SetStackTrace(stack, userFrameIndex);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment