Skip to content

Commit

Permalink
Implementation of mslogger and sample projects
Browse files Browse the repository at this point in the history
  • Loading branch information
phillip-haydon committed Dec 8, 2024
1 parent f2902b6 commit a02ca90
Show file tree
Hide file tree
Showing 20 changed files with 484 additions and 87 deletions.
13 changes: 12 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
[*]
indent_style = space
indent_size = 2
indent_size = 2

[*.cs]
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0290
csharp_style_prefer_primary_constructors = false
dotnet_diagnostic.IDE0290.severity = none

# https://www.jetbrains.com/help/rider/ConvertToPrimaryConstructor.html
resharper_convert_to_primary_constructor_highlighting = none

# Ensure if statements always use braces
csharp_prefer_braces = true:error
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using Mindscape.Raygun4Net.AspNetCore.Builders;

namespace Mindscape.Raygun4Net.AspNetCore;

Expand Down Expand Up @@ -51,7 +52,7 @@ public static IServiceCollection AddRaygun(this IServiceCollection services, ICo
options?.Invoke(settings);

services.TryAddSingleton(settings);
services.TryAddSingleton(s => new RaygunClient(s.GetService<RaygunSettings>()!, s.GetService<IRaygunUserProvider>()!));
services.TryAddSingleton(s => new RaygunClient(s.GetRequiredService<RaygunSettings>(), s.GetRequiredService<IRaygunUserProvider>(), s.GetServices<IMessageBuilder>()));
services.TryAddSingleton<RaygunClientBase>(provider => provider.GetRequiredService<RaygunClient>());
services.AddHttpContextAccessor();

Expand All @@ -69,8 +70,9 @@ public static IServiceCollection AddRaygun(this IServiceCollection services, Act
// Override settings with user-provided settings
options?.Invoke(settings);

services.TryAddSingleton<IMessageBuilder, RequestDataBuilder>();
services.TryAddSingleton(settings);
services.TryAddSingleton(s => new RaygunClient(s.GetService<RaygunSettings>()!, s.GetService<IRaygunUserProvider>()!));
services.TryAddSingleton(s => new RaygunClient(s.GetRequiredService<RaygunSettings>(), s.GetRequiredService<IRaygunUserProvider>(), s.GetServices<IMessageBuilder>()));
services.TryAddSingleton<RaygunClientBase>(provider => provider.GetRequiredService<RaygunClient>());
services.AddHttpContextAccessor();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#nullable enable

using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;

Expand All @@ -8,19 +9,19 @@ namespace Mindscape.Raygun4Net.AspNetCore.Builders
// ReSharper disable once ClassNeverInstantiated.Global
public class RaygunAspNetCoreResponseMessageBuilder
{
public static RaygunResponseMessage Build(HttpContext? context)
public static Task<RaygunResponseMessage> Build(HttpContext? context, RaygunSettings _)
{
if (context == null)
{
return new RaygunResponseMessage();
return Task.FromResult(new RaygunResponseMessage());
}

var httpResponseFeature = context.Features.Get<IHttpResponseFeature>();
return new RaygunResponseMessage
return Task.FromResult(new RaygunResponseMessage
{
StatusCode = context.Response.StatusCode,
StatusDescription = httpResponseFeature?.ReasonPhrase
};
});
}
}
}
27 changes: 27 additions & 0 deletions Mindscape.Raygun4Net.AspNetCore/Builders/RequestDataBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;

namespace Mindscape.Raygun4Net.AspNetCore.Builders;

public class RequestDataBuilder : IMessageBuilder
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly RaygunSettings _settings;

public RequestDataBuilder(IHttpContextAccessor httpContextAccessor, RaygunSettings settings)
{
_httpContextAccessor = httpContextAccessor;
_settings = settings;
}

public async Task<RaygunMessage> Apply(RaygunMessage message, Exception exception)
{
var ctx = _httpContextAccessor.HttpContext;

message.Details.Request = await RaygunAspNetCoreRequestMessageBuilder.Build(ctx, _settings);
message.Details.Response = await RaygunAspNetCoreResponseMessageBuilder.Build(ctx, _settings);

return message;
}
}
7 changes: 4 additions & 3 deletions Mindscape.Raygun4Net.AspNetCore/RaygunClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ public RaygunClient(RaygunSettings settings, HttpClient httpClient) : base(setti
{
}

public RaygunClient(RaygunSettings settings, IRaygunUserProvider userProvider) : base(settings, userProvider)
public RaygunClient(RaygunSettings settings, IRaygunUserProvider userProvider, IEnumerable<IMessageBuilder> messageBuilders) : base(settings, userProvider, messageBuilders)
{
}

public RaygunClient(RaygunSettings settings, HttpClient httpClient, IRaygunUserProvider userProvider) : base(settings, httpClient, userProvider)
public RaygunClient(RaygunSettings settings, HttpClient httpClient, IRaygunUserProvider userProvider) : base(settings, httpClient, userProvider, [])
{
}
// ReSharper restore MemberCanBeProtected.Global
Expand All @@ -58,6 +58,7 @@ protected override bool CanSend(RaygunMessage? message)

return !settings.ExcludedStatusCodes.Contains(message.Details.Response.StatusCode);
}

/// <summary>
/// Asynchronously transmits an exception to Raygun with optional Http Request data.
/// </summary>
Expand All @@ -72,7 +73,7 @@ public async Task SendInBackground(Exception exception, IList<string> tags, Http
// otherwise it will be disposed while we are using it on the other thread.
// BuildRequestMessage relies on ReadFormAsync, so we need to await it to ensure it's processed before continuing.
var currentRequestMessage = await RaygunAspNetCoreRequestMessageBuilder.Build(context, Settings.Value);
var currentResponseMessage = RaygunAspNetCoreResponseMessageBuilder.Build(context);
var currentResponseMessage = await RaygunAspNetCoreResponseMessageBuilder.Build(context, Settings.Value);

var exceptions = StripWrapperExceptions(exception);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1;net6.0;net7.0;net8.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net6.0;net7.0;net8.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
Expand All @@ -25,10 +25,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
97 changes: 83 additions & 14 deletions Mindscape.Raygun4Net.Extensions.Logging/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,98 @@ where they can be viewed and managed in the Raygun dashboard.

Install the **Mindscape.Raygun4Net.Extensions.Logging** NuGet package into your project. You can either use the below dotnet CLI command, or the NuGet management GUI in the IDE you use.

```
```csharp
dotnet add package Mindscape.Raygun4Net.Extensions.Logging
```

You will need to install the **Mindscape.Raygun4Net** package as well, if you haven't already.

```csharp
// If you're using it in an ASP.NET Core application:
dotnet add package Mindscape.Raygun4Net.AspNetCore

// If you're using it in a .NET Core service application:
dotnet add package Mindscape.Raygun4Net.NetCore
```

## Usage

Add the Raygun provider to the logging configuration in your `Program.cs` or `Startup.cs` file.

### ASP.NET Core Application

```csharp
using Microsoft.Extensions.Logging;
using Mindscape.Raygun4Net.AspNetCore;
using Mindscape.Raygun4Net.Extensions.Logging;

public class Program
var builder = WebApplication.CreateBuilder(args);

// Registers the Raygun Client for AspNetCore
builder.Services.AddRaygun(settings =>
{
settings.ApiKey = "*your api key*";
});

// (Optional) Registers the Raygun User Provider
builder.Services.AddRaygunUserProvider();

// Registers the Raygun Logger for use in MS Logger
builder.Logging.AddRaygunLogger();

var app = builder.Build();
```

### .NET Core Service Application

```csharp
using Mindscape.Raygun4Net.Extensions.Logging;
using Mindscape.Raygun4Net.NetCore;

var builder = Host.CreateApplicationBuilder(args);

// Registers the Raygun Client for NetCore
builder.Services.AddRaygun(options =>
{
public static void Main(string[] args)
{
var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddRaygun("paste_your_api_key_here");
});

var logger = loggerFactory.CreateLogger<Program>();
logger.LogInformation("Hello, Raygun!");
}
options.ApiKey = "*your api key*";
});

// Registers the Raygun Logger for use in MS Logger
builder.Logging.AddRaygunLogger();

var host = builder.Build();
```

## Configuration

When registering the Raygun provider, you can configure it with the following options:

* MinimumLogLevel: The minimum log level for messages to be sent to Raygun. Defaults to `LogLevel.Error`.
* OnlyLogExceptions: If false, logs without exceptions will be sent to Raygun. Defaults to `true`.

These can be set in code:

```csharp
builder.Logging.AddRaygunLogger(options: options =>
{
options.MinimumLogLevel = LogLevel.Information;
options.OnlyLogExceptions = false;
});
```

Or in the `appsettings.json` file:

```json
{
"RaygunSettings": {
"MinimumLogLevel": "Information",
"OnlyLogExceptions": false
}
}
```
```

## Notes

The category/contextSource set as a tag in Raygun.

When logs are sent without an exception, a Custom Data property is added to the Raygun message with the
key `NullException` with the value `Logged without exception` to identify Raygun Logs that have no exception.
Loading

0 comments on commit a02ca90

Please sign in to comment.