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

RaygunMessage Initializer Support #361

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
20 changes: 20 additions & 0 deletions Mindscape.Raygun4Net.Core/IRaygunMessageInitializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Mindscape.Raygun4Net.Messages;

namespace Mindscape.Raygun4Net
{
/// <summary>
/// Represents an initializer for <see cref="RaygunMessage"/> objects.
/// </summary>
/// <remarks>
/// The Raygun Clients use registered <see cref="IRaygunMessageInitializer"/>
/// to automatically add additional properties to <see cref="RaygunMessage"/> objects.
/// </remarks>
public interface IRaygunMessageInitializer
{
/// <summary>
/// Initializes properties of the specified <see cref="RaygunMessage"/> object.
/// </summary>
/// <param name="raygunMessage">The <see cref="RaygunMessage"/> to initialize.</param>
void Initialize(RaygunMessage raygunMessage);
}
}
1 change: 1 addition & 0 deletions Mindscape.Raygun4Net.Core/Mindscape.Raygun4Net.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@
<Link>SimpleJson.cs</Link>
</Compile>
<Compile Include="Builders\RaygunErrorMessageBuilder.cs" />
<Compile Include="IRaygunMessageInitializer.cs" />
<Compile Include="Messages\RaygunErrorMessage.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Model\FakeRaygunWebApiClient.cs" />
<Compile Include="Model\TestRaygunMessageInitializer.cs" />
<Compile Include="Model\WrapperException.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RaygunWebApiClientTests.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Mindscape.Raygun4Net.Messages;
using System;
using System.Collections;
using System.Collections.Generic;

namespace Mindscape.Raygun4Net.WebApi.Tests.Model
Expand All @@ -15,5 +16,10 @@ public IEnumerable<Exception> ExposeStripWrapperExceptions(Exception exception)
{
return base.StripWrapperExceptions(exception);
}

public RaygunMessage ExposeBuildMessage(Exception exception, IList<string> tags, IDictionary userCustomData, DateTime? currentTime = null)
{
return base.BuildMessage(exception, tags, userCustomData, currentTime);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Collections.Generic;
using Mindscape.Raygun4Net.Messages;

namespace Mindscape.Raygun4Net.WebApi.Tests.Model
{
public class TestRaygunMessageInitializer : IRaygunMessageInitializer
{
public void Initialize(RaygunMessage raygunMessage)
{
if (raygunMessage.Details.UserCustomData == null)
{
raygunMessage.Details.UserCustomData = new Dictionary<string, object>();
}
raygunMessage.Details.UserCustomData["initializerTestData"] = "true";
}
}
}
9 changes: 9 additions & 0 deletions Mindscape.Raygun4Net.WebApi.Tests/RaygunWebApiClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -265,5 +265,14 @@ public void StripReflectionTypeLoadException()
Assert.IsTrue(ex1.Data["Type"].ToString().Contains("FakeRaygunWebApiClient"));
Assert.IsTrue(ex2.Data["Type"].ToString().Contains("WrapperException"));
}

[Test]
public void CanUseInitializerToSetData()
{
_client.AddMessageInitializer(new TestRaygunMessageInitializer());
var message = _client.ExposeBuildMessage(_exception, null, null);

Assert.IsTrue(message.Details.UserCustomData.Contains("initializerTestData"));
}
}
}
49 changes: 37 additions & 12 deletions Mindscape.Raygun4Net.WebApi/RaygunWebApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ public class RaygunWebApiClient : RaygunClientBase
private readonly List<Type> _wrapperExceptions = new List<Type>();

private readonly ThreadLocal<HttpRequestMessage> _currentWebRequest = new ThreadLocal<HttpRequestMessage>(() => null);
private readonly ThreadLocal<RaygunRequestMessage> _currentRequestMessage = new ThreadLocal<RaygunRequestMessage>(() => null);

private static RaygunWebApiExceptionFilter _exceptionFilter;
private static RaygunWebApiActionFilter _actionFilter;
Expand Down Expand Up @@ -354,8 +353,6 @@ public void Send(Exception exception, IList<string> tags, IDictionary userCustom
{
if (CanSend(exception))
{
_currentRequestMessage.Value = BuildRequestMessage();

StripAndSend(exception, tags, userCustomData);
FlagAsSent(exception);
}
Expand Down Expand Up @@ -390,15 +387,9 @@ public void SendInBackground(Exception exception, IList<string> tags, IDictionar
{
if (CanSend(exception))
{
// We need to process the HttpRequestMessage on the current thread,
// otherwise it will be disposed while we are using it on the other thread.
RaygunRequestMessage currentRequestMessage = BuildRequestMessage();
DateTime currentTime = DateTime.UtcNow;

ThreadPool.QueueUserWorkItem(c => {
_currentRequestMessage.Value = currentRequestMessage;
StripAndSend(exception, tags, userCustomData, currentTime);
});

StripAndSendInBackground(exception, tags, userCustomData, currentTime);
FlagAsSent(exception);
}
}
Expand Down Expand Up @@ -439,7 +430,7 @@ protected RaygunMessage BuildMessage(Exception exception, IList<string> tags, ID
protected RaygunMessage BuildMessage(Exception exception, IList<string> tags, IDictionary userCustomData, DateTime? currentTime = null)
{
var message = RaygunWebApiMessageBuilder.New
.SetHttpDetails(_currentRequestMessage.Value)
.SetHttpDetails(BuildRequestMessage())
.SetTimeStamp(currentTime)
.SetEnvironmentDetails()
.SetMachineName(Environment.MachineName)
Expand All @@ -455,6 +446,25 @@ protected RaygunMessage BuildMessage(Exception exception, IList<string> tags, ID
{
message.Details.GroupingKey = customGroupingKey;
}

var initializers = GetRaygunMessageInitializers();
foreach (var initializer in initializers)
{
try
{
initializer.Initialize(message);
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(string.Format("Error Initializing RaygunMessage {0}", ex.Message));

if (RaygunSettings.Settings.ThrowOnError)
{
throw;
}
}
}

return message;
}

Expand All @@ -466,6 +476,21 @@ private void StripAndSend(Exception exception, IList<string> tags, IDictionary u
}
}

private void StripAndSendInBackground(Exception exception, IList<string> tags, IDictionary userCustomData, DateTime? currentTime = null)
{
var messages = new List<RaygunMessage>();
foreach (Exception e in StripWrapperExceptions(exception))
{
messages.Add(BuildMessage(e, tags, userCustomData, currentTime));
}
// Could use SendInBackground here, but like this we queue multiple sends on a single thread
ThreadPool.QueueUserWorkItem(c => {
foreach (var message in messages) {
Send(message);
}
});
}

protected IEnumerable<Exception> StripWrapperExceptions(Exception exception)
{
if (exception != null && _wrapperExceptions.Any(wrapperException => exception.GetType() == wrapperException && (exception.InnerException != null || exception is ReflectionTypeLoadException)))
Expand Down
39 changes: 39 additions & 0 deletions Mindscape.Raygun4Net/RaygunClientBase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Net;
using Mindscape.Raygun4Net.Messages;

Expand Down Expand Up @@ -115,6 +116,44 @@ protected string OnCustomGroupingKey(Exception exception, RaygunMessage message)
return result;
}

/// <summary>
/// List of registered <see cref="IRaygunMessageInitializer"/> objects.
/// </summary>
private List<IRaygunMessageInitializer> RaygunMessageInitializers { get; set; } = new List<IRaygunMessageInitializer>();

/// <summary>
/// Return a copy of the registered <see cref="IRaygunMessageInitializer"/> objects.
/// </summary>
/// <remarks>
/// Ensures that changes made to the collection during processing does not cause problems.
/// </remarks>
protected virtual List<IRaygunMessageInitializer> GetRaygunMessageInitializers()
{
return new List<IRaygunMessageInitializer>(RaygunMessageInitializers);
}

/// <summary>
/// Register a <see cref="IRaygunMessageInitializer"/> to initialize properties on the <see cref="RaygunMessage"/>.
/// </summary>
/// <param name="raygunMessageInitializer">The <see cref="IRaygunMessageInitializer"/> to register.</param>
public virtual void AddMessageInitializer(IRaygunMessageInitializer raygunMessageInitializer)
{
if (RaygunMessageInitializers == null)
{
RaygunMessageInitializers = new List<IRaygunMessageInitializer>();
}
RaygunMessageInitializers.Add(raygunMessageInitializer);
}

/// <summary>
/// Removes a <see cref="IRaygunMessageInitializer"/> from the list of registered <see cref="IRaygunMessageInitializer"/> objects.
/// </summary>
/// <param name="raygunMessageInitializer">The <see cref="IRaygunMessageInitializer"/> to remove.</param>
public virtual bool RemoveMessageInitializer(IRaygunMessageInitializer raygunMessageInitializer)
{
return RaygunMessageInitializers.Remove(raygunMessageInitializer);
}

/// <summary>
/// Transmits an exception to Raygun.io synchronously.
/// </summary>
Expand Down