|
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); |
|
} |
|
} |
|
} |
|
} |