Skip to content

Commit

Permalink
Merge pull request #53 from MindscapeHQ/dev
Browse files Browse the repository at this point in the history
Release v5.2.0
  • Loading branch information
PanosNB authored Mar 29, 2023
2 parents 598824c + a31a3f9 commit 8b738f7
Show file tree
Hide file tree
Showing 10 changed files with 284 additions and 10 deletions.
39 changes: 36 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# serilog-sinks-raygun

[![Build status](https://ci.appveyor.com/api/projects/status/bol0v48ujapxobym/branch/master?svg=true)](https://ci.appveyor.com/project/serilog/serilog-sinks-raygun/branch/master)

A Serilog sink that writes events to Raygun

## Usage
Expand Down Expand Up @@ -29,7 +27,8 @@ Log.Logger = new LoggerConfiguration()
new[] { "ignoreField1", "ignoreField2" },
"CustomGroupKeyProperty",
"CustomTagsProperty",
"CustomUserInfoProperty")
"CustomUserInfoProperty",
onBeforeSendArguments => { /*OnBeforeSend: Action<onBeforeSendArguments>*/ })
.CreateLogger();
```

Expand Down Expand Up @@ -171,6 +170,40 @@ var userInfo = new RaygunIdentifierMessage("12345")

Log.ForContext("CustomUserInfoProperty", userInfo, true).Error(new Exception("random error"), "other information");
```

### onBeforeSend
`type: Action<OnBeforeSendParameters>`

`default: null`

This action allows you to manipulate the crash report payloads that get sent to Raygun.
By default it is `null`, so you don't need to set it in the constructor. If the action is `null`, nothing happens; if an `Action<OnBeforeSendParameters>` is passed, it gets called just before the crash report payload gets serialized and sent to Raygun.
The arguments to the action are of type `Struct OnBeforeSendArguments`; they are passed to the action when it is called and contain references to the following objects passed by the Raygun client object:
```csharp
// Abstracted away version of the struct to just show the properties
struct OnBeforeSendArguments
{
System.Exception Exception;
Mindscape.Raygun4Net.Messages.RaygunMessage RaygunMessage;
}
```

The provided action can read and/or modify their properties accordingly to produce the desired effect.
For example, one can change the `MachineName` property in the `Details` of the `RaygunMessage` as follows:

```csharp
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Verbose()
.WriteTo.Raygun(
applicationKey: "",
onBeforeSend: arguments => {
arguments.RaygunMessage.Details.MachineName = "MyMachine";
})
.CreateLogger();
);
```


## Enrich with HTTP request and response data

_Note: This is only valid for .NET Standard 2.0 and above projects. In full framework ASP.NET applications the HTTP request and response are available to Raygun4Net through the `HttpContext.Current` accessor.
Expand Down
45 changes: 45 additions & 0 deletions sampleApps/Serilog.Sinks.Raygun.SampleConsoleApp/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using Serilog;
using Serilog.Events;

Console.Out.WriteLine("Please enter your Raygun application key: ");
var raygunApiKey = Console.In.ReadLine();

Log.Logger = new LoggerConfiguration()
.MinimumLevel.Verbose()
.WriteTo.Raygun(raygunApiKey,
null,
"CustomUserNameProperty",
"CustomAppVersionProperty",
LogEventLevel.Information,
null,
new[] { "globalTag1", "globalTag2" },
new[] { "ignoreField1", "ignoreField2" },
"CustomGroupKeyProperty",
"CustomTagsProperty",
"CustomUserInfoProperty",
onBeforeSendArguments =>
{
Console.Out.WriteLine("OnBeforeSend called with the following arguments: " + onBeforeSendArguments);
//Updating machine name
onBeforeSendArguments.RaygunMessage.Details.MachineName = "Serilog.Sinks.Raygun.SampleConsoleApp Machine";

//Testing throwing an exception in Action
throw new Exception("Exception thrown in callback action..");

})
.CreateLogger();

try
{
throw new Exception("Serilog.Sinks.Raygun.SampleConsoleApp");
}
catch (Exception e)
{
Console.Out.WriteLine("Sending message to Raygun");
Log.Error(e, "Logging error");
}

//A Thread.Sleep is normally not necessary. Adding it here because the app is too small and there might not be enough time to send the errors to Raygun because of the asynchronous Send method used
Thread.Sleep(1000);

Console.Out.WriteLine("All done! Please check your Raygun App to ensure the two logged exceptions appear");
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Serilog" Version="2.12.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Serilog.Sinks.Raygun\Serilog.Sinks.Raygun.csproj" />
</ItemGroup>

</Project>
6 changes: 6 additions & 0 deletions serilog-sinks-raygun.sln
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Serilog.Sinks.Raygun", "src
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Serilog.Sinks.Raygun.Tests", "test\Serilog.Sinks.Raygun.Tests\Serilog.Sinks.Raygun.Tests.csproj", "{E7D3E0A9-08FE-4B4F-B7D6-56FF8053B532}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Serilog.Sinks.Raygun.SampleConsoleApp", "sampleApps\Serilog.Sinks.Raygun.SampleConsoleApp\Serilog.Sinks.Raygun.SampleConsoleApp.csproj", "{84BCC6CF-66EB-4965-9566-F3F314EDA311}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -21,6 +23,10 @@ Global
{E7D3E0A9-08FE-4B4F-B7D6-56FF8053B532}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E7D3E0A9-08FE-4B4F-B7D6-56FF8053B532}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E7D3E0A9-08FE-4B4F-B7D6-56FF8053B532}.Release|Any CPU.Build.0 = Release|Any CPU
{84BCC6CF-66EB-4965-9566-F3F314EDA311}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{84BCC6CF-66EB-4965-9566-F3F314EDA311}.Debug|Any CPU.Build.0 = Debug|Any CPU
{84BCC6CF-66EB-4965-9566-F3F314EDA311}.Release|Any CPU.ActiveCfg = Release|Any CPU
{84BCC6CF-66EB-4965-9566-F3F314EDA311}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public static class LoggerConfigurationRaygunExtensions
/// <param name="groupKeyProperty">The property containing the custom group key for the Raygun message.</param>
/// <param name="tagsProperty">The property where additional tags are stored when emitting log events.</param>
/// <param name="userInfoProperty">The property containing the RaygunIdentifierMessage structure used to populate user details.</param>
/// <param name="onBeforeSend">The action to be executed right before a logging message is sent to Raygun</param>
/// <returns>Logger configuration, allowing configuration to continue.</returns>
/// <exception cref="ArgumentNullException">A required parameter is null.</exception>
public static LoggerConfiguration Raygun(
Expand All @@ -59,12 +60,13 @@ public static LoggerConfiguration Raygun(
IEnumerable<string> ignoredFormFieldNames = null,
string groupKeyProperty = "GroupKey",
string tagsProperty = "Tags",
string userInfoProperty = null)
string userInfoProperty = null,
Action<OnBeforeSendArguments> onBeforeSend = null)
{
if (loggerConfiguration == null) throw new ArgumentNullException("loggerConfiguration");

return loggerConfiguration.Sink(
new RaygunSink(formatProvider, applicationKey, wrapperExceptions, userNameProperty, applicationVersionProperty, tags, ignoredFormFieldNames, groupKeyProperty, tagsProperty, userInfoProperty),
new RaygunSink(formatProvider, applicationKey, wrapperExceptions, userNameProperty, applicationVersionProperty, tags, ignoredFormFieldNames, groupKeyProperty, tagsProperty, userInfoProperty, onBeforeSend),
restrictedToMinimumLevel);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Serilog.Sinks.Raygun/Serilog.Sinks.Raygun.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<PackageTags>serilog sink raygun</PackageTags>
<Copyright>Copyright © Serilog Contributors 2017-2020</Copyright>
<Description>Serilog event sink that writes to the Raygun service.</Description>
<VersionPrefix>5.1.1</VersionPrefix>
<VersionPrefix>5.2.0</VersionPrefix>
<RootNamespace>Serilog</RootNamespace>
</PropertyGroup>

Expand Down
26 changes: 26 additions & 0 deletions src/Serilog.Sinks.Raygun/Sinks/Raygun/OnBeforeSendArguments.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;
using Mindscape.Raygun4Net;
#if NETSTANDARD2_0
using Mindscape.Raygun4Net.AspNetCore;
#else
using Mindscape.Raygun4Net.Builders;
using Mindscape.Raygun4Net.Messages;
#endif

namespace Serilog.Sinks.Raygun
{
public readonly struct OnBeforeSendArguments
{
private readonly Exception _exception;
private readonly RaygunMessage _raygunMessage;

public Exception Exception => _exception;
public RaygunMessage RaygunMessage => _raygunMessage;

public OnBeforeSendArguments(Exception exception, RaygunMessage raygunMessage)
{
_exception = exception;
_raygunMessage = raygunMessage;
}
}
}
21 changes: 18 additions & 3 deletions src/Serilog.Sinks.Raygun/Sinks/Raygun/RaygunSink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public class RaygunSink : ILogEventSink
private readonly string _tagsProperty;
private readonly string _userInfoProperty;
private readonly RaygunClient _client;
private readonly Action<OnBeforeSendArguments> _onBeforeSend;

/// <summary>
/// Construct a sink that saves errors to the Raygun service. Properties and the log message are being attached as UserCustomData and the level is included as a Tag.
Expand All @@ -60,6 +61,7 @@ public class RaygunSink : ILogEventSink
/// <param name="groupKeyProperty">The property containing the custom group key for the Raygun message.</param>
/// <param name="tagsProperty">The property where additional tags are stored when emitting log events.</param>
/// <param name="userInfoProperty">The property where a RaygunIdentifierMessage with more user information can optionally be provided.</param>
/// <param name="onBeforeSend">The action to be executed right before a logging message is sent to Raygun</param>
public RaygunSink(IFormatProvider formatProvider,
string applicationKey,
IEnumerable<Type> wrapperExceptions = null,
Expand All @@ -69,7 +71,8 @@ public RaygunSink(IFormatProvider formatProvider,
IEnumerable<string> ignoredFormFieldNames = null,
string groupKeyProperty = "GroupKey",
string tagsProperty = "Tags",
string userInfoProperty = null)
string userInfoProperty = null,
Action<OnBeforeSendArguments> onBeforeSend = null)
{
_formatProvider = formatProvider;
_userNameProperty = userNameProperty;
Expand All @@ -78,6 +81,8 @@ public RaygunSink(IFormatProvider formatProvider,
_groupKeyProperty = groupKeyProperty;
_tagsProperty = tagsProperty;
_userInfoProperty = userInfoProperty;
_onBeforeSend = onBeforeSend;


#if NETSTANDARD2_0
_client = new RaygunClient(applicationKey);
Expand Down Expand Up @@ -121,14 +126,17 @@ public void Emit(LogEvent logEvent)
properties.Remove(_tagsProperty);
}

// Decide what exception object to send
var exception = logEvent.Exception ?? new NullException(GetCurrentExecutionStackTrace());

// Submit
if (logEvent.Level == LogEventLevel.Fatal)
{
_client.Send(logEvent.Exception ?? new NullException(GetCurrentExecutionStackTrace()), tags, properties);
_client.Send(exception, tags, properties);
}
else
{
_client.SendInBackground(logEvent.Exception ?? new NullException(GetCurrentExecutionStackTrace()), tags, properties);
_client.SendInBackground(exception, tags, properties);
}
}

Expand Down Expand Up @@ -242,6 +250,13 @@ occurredOnPropertyValue is ScalarValue occurredOnScalar &&
.ToDictionary(a => a.Name, b => b.Value);
}
}

// Call onBeforeSend
if (_onBeforeSend != null)
{
var onBeforeSendArguments = new OnBeforeSendArguments(e?.Exception, e?.Message);
_onBeforeSend(onBeforeSendArguments);
}
}

private static StackTrace GetCurrentExecutionStackTrace()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>

<IsPackable>false</IsPackable>

<TargetFrameworks>netstandard2.0;net46;net461</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
Expand Down
Loading

0 comments on commit 8b738f7

Please sign in to comment.