Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for RaygunBreadcrumb #6

Merged
merged 1 commit into from
Nov 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ You need to configure NLog.config.
* Tags - Tags you want to send in with every exception.
* IncludeEventProperties - Include properties from NLog LogEvent. Default is ```true```.
* IncludeMdlc - Include properties from NLog Mapped Diagnostic Logical Context (MDLC). Default is ```false```.
* IncludeBreadcrumbMessages - Convert informational LogEvents without Exceptions into Breadcrumbs (NOT available for NET Core). Default is ```false```.
* IsRawDataIgnored - RawData from web requests is ignored. Default is ```false```.
* IgnoreFormFieldNames - Form fields you wish to ignore, eg passwords and credit cards.
* IgnoreCookieNames - Cookies you wish to ignore, eg user tokens.
* IgnoreServerVariableNames - Server variables you wish to ignore, eg sessions.
* IgnoreHeaderNames - HTTP headers to ignore, eg API keys.
* IsRawDataIgnored - RawData from web requests is ignored. Default is ```false```.
* IgnoreHeaderNames - HTTP request headers to ignore, eg API keys.
* IgnoreQueryParameterNames - HTTP request query parameters to ignore.
* IgnoreSensitiveFieldNames - Remove sensitive information from any of the above collections (Fields, Cookies, Headers, QueryParameters, RawData)
* UserIdentityInfo - Explicitly defines lookup of user identity for Raygun events, ie. NLog layout renderer `${windows-identity}`.
* UseExecutingAssemblyVersion - Attempt to get the executing assembly version, or root ASP.Net assembly version for Raygun events. Default is ```false```.
* ApplicationVersion - Explicitly defines an application version for Raygun events. This will be ignored if UseExecutingAssemblyVersion is set to true and returns a value.
Expand All @@ -46,10 +49,12 @@ Your `NLog.config` should look something like this:
ApiKey=""
Tags=""
IncludeEventProperties="true"
IncludeBreadcrumbMessages="false"
IgnoreFormFieldNames=""
IgnoreCookieNames=""
IgnoreServerVariableNames=""
IgnoreHeaderNames=""
IgnoreQueryParameterNames=""
UserIdentityInfo=""
UseExecutingAssemblyVersion="false"
ApplicationVersion=""
Expand Down
78 changes: 77 additions & 1 deletion src/NLog.Raygun/RayGunTarget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,34 @@ public string ApiKey
/// </summary>
public string IgnoreHeaderNames { get; set; }

/// <summary>
/// Adds a list of keys to remove from the <see cref="RaygunRequestMessage.QueryString" /> property of the <see cref="RaygunRequestMessage" />
/// </summary>
public string IgnoreQueryParameterNames { get; set; }

/// <summary>
/// Adds a list of keys to remove from the following sections of the <see cref="RaygunRequestMessage" />
/// <see cref="RaygunRequestMessage.Headers" />
/// <see cref="RaygunRequestMessage.QueryString" />
/// <see cref="RaygunRequestMessage.Cookies" />
/// <see cref="RaygunRequestMessage.Data" />
/// <see cref="RaygunRequestMessage.Form" />
/// <see cref="RaygunRequestMessage.RawData" />
/// </summary>
public string IgnoreSensitiveFieldNames { get; set; }

/// <summary>
/// Specifies whether or not RawData from web requests is ignored when sending reports to Raygun.io.
/// The default is false which means RawData will be sent to Raygun.io.
/// </summary>
public bool IsRawDataIgnored { get { return _isRawDataIgnored ?? false; } set { _isRawDataIgnored = value; } }
private bool? _isRawDataIgnored;

/// <summary>
/// Convert informational LogEvents without Exceptions into Breadcrumbs
/// </summary>
public bool IncludeBreadcrumbMessages { get; set; }

/// <summary>
/// Explicitly defines lookup of user-identity for Raygun events.
/// </summary>
Expand Down Expand Up @@ -120,7 +141,6 @@ protected override void Write(AsyncLogEventInfo logEvent)
_raygunClient = _raygunClient ?? (_raygunClient = CreateRaygunClient());

Exception exception = ExtractException(logEvent.LogEvent);
var tags = ExtractTags(logEvent.LogEvent, exception);
var contextProperties = GetAllProperties(logEvent.LogEvent);
contextProperties.Remove("Tags");
contextProperties.Remove("tags");
Expand All @@ -129,9 +149,19 @@ protected override void Write(AsyncLogEventInfo logEvent)
if (exception == null)
{
string layoutLogMessage = RenderLogEvent(Layout, logEvent.LogEvent);

#if NET45
if (IncludeBreadcrumbMessages && logEvent.LogEvent.Level < LogLevel.Error)
{
RecordBreadcrumb(logEvent.LogEvent, layoutLogMessage, userCustomData);
return;
}
#endif

exception = new RaygunException(layoutLogMessage);
}

var tags = ExtractTags(logEvent.LogEvent, exception);
string userIdentityInfo = RenderLogEvent(UserIdentityInfo, logEvent.LogEvent);
#if NET45
var userIdentity = string.IsNullOrEmpty(userIdentityInfo) ? null : new Mindscape.Raygun4Net.Messages.RaygunIdentifierMessage(userIdentityInfo);
Expand All @@ -149,6 +179,46 @@ protected override void Write(AsyncLogEventInfo logEvent)
}
}

#if NET45
private void RecordBreadcrumb(LogEventInfo logEvent, string layoutMessage, IDictionary<string, object> userCustomData)
{
var breadcrumbLevel = Mindscape.Raygun4Net.Breadcrumbs.RaygunBreadcrumbLevel.Debug;
if (logEvent.Level == LogLevel.Info)
breadcrumbLevel = Mindscape.Raygun4Net.Breadcrumbs.RaygunBreadcrumbLevel.Info;
else if (logEvent.Level == LogLevel.Warn)
breadcrumbLevel = Mindscape.Raygun4Net.Breadcrumbs.RaygunBreadcrumbLevel.Warning;
else if (logEvent.Level == LogLevel.Error || logEvent.Level == LogLevel.Fatal)
breadcrumbLevel = Mindscape.Raygun4Net.Breadcrumbs.RaygunBreadcrumbLevel.Error;

if (breadcrumbLevel >= RaygunSettings.Settings.BreadcrumbsLevel)
{
var crumb = new RaygunBreadcrumb();
crumb.Level = breadcrumbLevel;
crumb.Message = layoutMessage;
crumb.Category = logEvent.LoggerName;

if (userCustomData.Count > 0)
{
crumb.CustomData = userCustomData;
}

if (!string.IsNullOrEmpty(logEvent.CallerClassName))
{
crumb.ClassName = logEvent.CallerClassName;
}

if (!string.IsNullOrEmpty(logEvent.CallerMemberName))
{
crumb.MethodName = logEvent.CallerMemberName;
if (logEvent.CallerLineNumber > 0)
crumb.LineNumber = logEvent.CallerLineNumber;
}

RaygunClient.RecordBreadcrumb(crumb);
}
}
#endif

private static void SendCompleted(Exception taskException, AsyncContinuation continuation)
{
if (taskException != null)
Expand Down Expand Up @@ -249,6 +319,8 @@ private RaygunClient CreateRaygunClient()
}
}

if (IgnoreSensitiveFieldNames != null)
client.IgnoreSensitiveFieldNames(SplitValues(IgnoreSensitiveFieldNames));
if (IgnoreFormFieldNames != null)
client.IgnoreFormFieldNames(SplitValues(IgnoreFormFieldNames));
if (IgnoreCookieNames != null)
Expand All @@ -257,8 +329,12 @@ private RaygunClient CreateRaygunClient()
client.IgnoreHeaderNames(SplitValues(IgnoreHeaderNames));
if (IgnoreServerVariableNames != null)
client.IgnoreServerVariableNames(SplitValues(IgnoreServerVariableNames));
if (IgnoreQueryParameterNames != null)
client.IgnoreQueryParameterNames(SplitValues(IgnoreQueryParameterNames));

if (_isRawDataIgnored.HasValue)
client.IsRawDataIgnored = _isRawDataIgnored.Value;

return client;
}

Expand Down