diff --git a/README.md b/README.md index c797f67..56c4666 100644 --- a/README.md +++ b/README.md @@ -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. @@ -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="" diff --git a/src/NLog.Raygun/RayGunTarget.cs b/src/NLog.Raygun/RayGunTarget.cs index 40104b6..79ee14f 100644 --- a/src/NLog.Raygun/RayGunTarget.cs +++ b/src/NLog.Raygun/RayGunTarget.cs @@ -52,6 +52,22 @@ public string ApiKey /// public string IgnoreHeaderNames { get; set; } + /// + /// Adds a list of keys to remove from the property of the + /// + public string IgnoreQueryParameterNames { get; set; } + + /// + /// Adds a list of keys to remove from the following sections of the + /// + /// + /// + /// + /// + /// + /// + public string IgnoreSensitiveFieldNames { get; set; } + /// /// 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. @@ -59,6 +75,11 @@ public string ApiKey public bool IsRawDataIgnored { get { return _isRawDataIgnored ?? false; } set { _isRawDataIgnored = value; } } private bool? _isRawDataIgnored; + /// + /// Convert informational LogEvents without Exceptions into Breadcrumbs + /// + public bool IncludeBreadcrumbMessages { get; set; } + /// /// Explicitly defines lookup of user-identity for Raygun events. /// @@ -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"); @@ -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); @@ -149,6 +179,46 @@ protected override void Write(AsyncLogEventInfo logEvent) } } +#if NET45 + private void RecordBreadcrumb(LogEventInfo logEvent, string layoutMessage, IDictionary 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) @@ -249,6 +319,8 @@ private RaygunClient CreateRaygunClient() } } + if (IgnoreSensitiveFieldNames != null) + client.IgnoreSensitiveFieldNames(SplitValues(IgnoreSensitiveFieldNames)); if (IgnoreFormFieldNames != null) client.IgnoreFormFieldNames(SplitValues(IgnoreFormFieldNames)); if (IgnoreCookieNames != null) @@ -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; }