Skip to content

Commit d18ff66

Browse files
committed
PR feedback
1 parent 5c7d5b2 commit d18ff66

File tree

11 files changed

+141
-95
lines changed

11 files changed

+141
-95
lines changed

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Exceptionless .NET Clients
22

3-
[![Build Windows](https://github.com/exceptionless/Exceptionless.Net/workflows/Build%20Windows/badge.svg?branch=master)](https://github.com/Exceptionless/Exceptionless.Net/actions)
4-
[![Build OSX](https://github.com/exceptionless/Exceptionless.Net/workflows/Build%20OSX/badge.svg)](https://github.com/Exceptionless/Exceptionless.Net/actions)
5-
[![Build Linux](https://github.com/exceptionless/Exceptionless.Net/workflows/Build%20Linux/badge.svg)](https://github.com/Exceptionless/Exceptionless.Net/actions)
3+
[![Build Windows](https://github.com/Exceptionless/Exceptionless.Net/actions/workflows/build-windows.yml/badge.svg?branch=main)](https://github.com/Exceptionless/Exceptionless.Net/actions/workflows/build-windows.yml)
4+
[![Build OSX](https://github.com/Exceptionless/Exceptionless.Net/actions/workflows/build-osx.yml/badge.svg?branch=main)](https://github.com/Exceptionless/Exceptionless.Net/actions/workflows/build-osx.yml)
5+
[![Build Linux](https://github.com/Exceptionless/Exceptionless.Net/actions/workflows/build-linux.yml/badge.svg?branch=main)](https://github.com/Exceptionless/Exceptionless.Net/actions/workflows/build-linux.yml)
66
[![NuGet Version](http://img.shields.io/nuget/v/Exceptionless.svg?style=flat)](https://www.nuget.org/packages/Exceptionless/)
77
[![Discord](https://img.shields.io/discord/715744504891703319)](https://discord.gg/6HxgFCx)
88

@@ -29,8 +29,8 @@ editor design surfaces are available.
2929

3030
1. You will need to install:
3131
1. [Visual Studio 2022](https://visualstudio.microsoft.com/vs/community/)
32-
2. [.NET Core 6.x & 8.x SDK with VS Tooling](https://dotnet.microsoft.com/download)
33-
3. [.NET Framework 4.6.2 Developer Pack](https://dotnet.microsoft.com/download/dotnet-framework/net462)
32+
2. [.NET 10 SDK with Visual Studio tooling](https://dotnet.microsoft.com/download)
33+
3. [.NET Framework 4.7.2 Developer Pack](https://dotnet.microsoft.com/download/dotnet-framework/net472)
3434
2. Open the `Exceptionless.Net.slnx` Visual Studio solution file.
3535
3. Select `Exceptionless.SampleConsole` as the startup project.
3636
4. Run the project by pressing `F5` to start the console.
@@ -43,7 +43,7 @@ build windows specific packages.
4343

4444
1. You will need to install:
4545
1. [Visual Studio Code](https://code.visualstudio.com)
46-
2. [.NET Core 6.x & 8.x SDK with VS Tooling](https://dotnet.microsoft.com/download)
46+
2. [.NET 10 SDK](https://dotnet.microsoft.com/download)
4747
2. Open the cloned Exceptionless.Net folder.
4848
3. Run the `Exceptionless.SampleConsole` project by pressing `F5` to start the console.
4949

samples/Exceptionless.SampleAspNetCore/Controllers/ValuesController.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public class ValuesController : Controller {
1010
private readonly ILogger _logger;
1111

1212
public ValuesController(ExceptionlessClient exceptionlessClient, ILogger<ValuesController> logger) {
13-
// ExceptionlessClient instance from DI that was registered with the AddExceptionless call in Startup.ConfigureServices
13+
// ExceptionlessClient instance from DI that was registered with the builder.AddExceptionless call in Program.cs.
1414
_exceptionlessClient = exceptionlessClient;
1515
_logger = logger;
1616
}
@@ -21,7 +21,7 @@ public Dictionary<string, string> Get() {
2121
// Submit a feature usage event directly using the client instance that is injected from the DI container.
2222
_exceptionlessClient.SubmitFeatureUsage("ValuesController_Get");
2323

24-
// This log message will get sent to Exceptionless since Exceptionless has be added to the logging system in Program.cs.
24+
// This log message will get sent to Exceptionless since Exceptionless has been added to the logging system in Program.cs.
2525
_logger.LogWarning("Test warning message");
2626

2727
try {
@@ -42,7 +42,8 @@ public Dictionary<string, string> Get() {
4242
handledException.ToExceptionless().Submit();
4343
}
4444

45-
// Unhandled exceptions will get reported since called UseExceptionless in the Startup.cs which registers a listener for unhandled exceptions.
45+
// Unhandled exceptions will get reported because Program.cs enables the built-in exception handler pipeline
46+
// and wires Exceptionless into both ASP.NET Core diagnostics and middleware hooks.
4647
throw new Exception($"Unhandled Exception: {Guid.NewGuid()}");
4748
}
4849
}
Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,37 @@
1-
using Microsoft.AspNetCore.Hosting;
2-
using Microsoft.Extensions.Hosting;
3-
4-
namespace Exceptionless.SampleAspNetCore {
5-
public class Program {
6-
public static void Main(string[] args) {
7-
CreateHostBuilder(args).Build().Run();
8-
}
9-
10-
public static IHostBuilder CreateHostBuilder(string[] args) =>
11-
Host.CreateDefaultBuilder(args)
12-
.ConfigureLogging(b => {
13-
// By default sends warning and error log messages to Exceptionless.
14-
// Log levels can be controlled remotely per log source from the Exceptionless app in near real-time.
15-
b.AddExceptionless();
16-
})
17-
.ConfigureWebHostDefaults(webBuilder => {
18-
webBuilder.UseStartup<Startup>();
19-
});
20-
}
21-
}
1+
using Exceptionless;
2+
using Microsoft.AspNetCore.Builder;
3+
using Microsoft.Extensions.DependencyInjection;
4+
using Microsoft.Extensions.Logging;
5+
6+
var builder = WebApplication.CreateBuilder(args);
7+
8+
// By default sends warning and error log messages to Exceptionless.
9+
// Log levels can be controlled remotely per log source from the Exceptionless app in near real-time.
10+
builder.Logging.AddExceptionless();
11+
12+
// Reads settings from IConfiguration then adds additional configuration from this lambda.
13+
// This also configures ExceptionlessClient.Default and host shutdown queue flushing.
14+
builder.AddExceptionless(c => c.DefaultData["Startup"] = "heyyy");
15+
// OR
16+
// builder.AddExceptionless();
17+
// OR
18+
// builder.AddExceptionless("API_KEY_HERE");
19+
20+
// Adds ASP.NET Core request/unhandled exception hooks and standard exception handling services.
21+
builder.Services.AddExceptionless();
22+
builder.Services.AddProblemDetails();
23+
24+
// This is normal ASP.NET Core code.
25+
builder.Services.AddControllers();
26+
27+
var app = builder.Build();
28+
29+
// Uses the built-in exception handler pipeline, with Exceptionless capturing via IExceptionHandler.
30+
app.UseExceptionHandler();
31+
32+
// Adds Exceptionless middleware for diagnostics, 404 tracking, and queue processing.
33+
app.UseExceptionless();
34+
35+
app.MapControllers();
36+
37+
app.Run();

samples/Exceptionless.SampleAspNetCore/Startup.cs

Lines changed: 0 additions & 41 deletions
This file was deleted.

samples/Exceptionless.SampleHosting/Program.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ public static IHostBuilder CreateHostBuilder(string[] args) =>
6464
handledException.ToExceptionless().Submit();
6565
}
6666

67-
// Unhandled exceptions will get reported because host-level Exceptionless integration is enabled in Program.cs.
67+
// This simulates an unhandled exception. Host-level Exceptionless integration reports
68+
// host/AppDomain-level unhandled exceptions; ASP.NET Core request-pipeline exceptions
69+
// require the ASP.NET Core integration and UseExceptionHandler.
6870
throw new Exception($"Unhandled Exception: {Guid.NewGuid()}");
6971
});
7072
});

src/Platforms/Exceptionless.AspNetCore/ExceptionlessDiagnosticListener.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ public sealed class ExceptionlessDiagnosticListener : IObserver<KeyValuePair<str
99
private const string HandledExceptionEvent = "Microsoft.AspNetCore.Diagnostics.HandledException";
1010
private const string DiagnosticsUnhandledExceptionEvent = "Microsoft.AspNetCore.Diagnostics.UnhandledException";
1111
private const string HostingUnhandledExceptionEvent = "Microsoft.AspNetCore.Hosting.UnhandledException";
12+
private const string HostingDiagnosticsUnhandledExceptionEvent = "Microsoft.AspNetCore.Hosting.Diagnostics.UnhandledException";
1213
private const string MiddlewareExceptionEvent = "Microsoft.AspNetCore.MiddlewareAnalysis.MiddlewareException";
1314
private readonly ExceptionlessClient _client;
1415

@@ -20,24 +21,36 @@ public void OnCompleted() { }
2021

2122
public void OnError(Exception error) { }
2223

24+
internal static bool IsRelevantEvent(string eventName) {
25+
return String.Equals(eventName, HandledExceptionEvent, StringComparison.Ordinal) ||
26+
String.Equals(eventName, DiagnosticsUnhandledExceptionEvent, StringComparison.Ordinal) ||
27+
String.Equals(eventName, HostingUnhandledExceptionEvent, StringComparison.Ordinal) ||
28+
String.Equals(eventName, HostingDiagnosticsUnhandledExceptionEvent, StringComparison.Ordinal) ||
29+
String.Equals(eventName, MiddlewareExceptionEvent, StringComparison.Ordinal);
30+
}
31+
2332
public void OnNext(KeyValuePair<string, object> diagnosticEvent) {
2433
switch (diagnosticEvent.Key) {
2534
case HandledExceptionEvent:
2635
SubmitException(diagnosticEvent.Value, diagnosticEvent.Key, false);
2736
break;
2837
case DiagnosticsUnhandledExceptionEvent:
2938
case HostingUnhandledExceptionEvent:
39+
case HostingDiagnosticsUnhandledExceptionEvent:
3040
SubmitException(diagnosticEvent.Value, diagnosticEvent.Key, true);
3141
break;
3242
case MiddlewareExceptionEvent:
43+
if (diagnosticEvent.Value is null)
44+
break;
45+
3346
string middlewareName = GetPropertyValue(diagnosticEvent.Value, "name") as string;
3447
SubmitException(diagnosticEvent.Value, middlewareName ?? diagnosticEvent.Key, true);
3548
break;
3649
}
3750
}
3851

3952
private void SubmitException(object payload, string submissionMethod, bool isUnhandledError) {
40-
if (payload == null)
53+
if (payload is null)
4154
return;
4255

4356
var httpContext = GetPropertyValue(payload, "httpContext") as HttpContext;
@@ -54,6 +67,9 @@ private void SubmitException(object payload, string submissionMethod, bool isUnh
5467
}
5568

5669
private static object GetPropertyValue(object payload, string propertyName) {
70+
if (payload is null)
71+
return null;
72+
5773
return payload.GetType()
5874
.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.IgnoreCase)?
5975
.GetValue(payload);

src/Platforms/Exceptionless.AspNetCore/ExceptionlessExtensions.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,17 @@
99
using Exceptionless.Plugins.Default;
1010
using Microsoft.AspNetCore.Diagnostics;
1111
using Microsoft.Extensions.DependencyInjection;
12-
using Microsoft.Extensions.DependencyInjection.Extensions;
1312
using Microsoft.Extensions.Hosting;
1413

1514
namespace Exceptionless {
1615
public static class ExceptionlessExtensions {
1716
/// <summary>
18-
/// Registers the Exceptionless <see cref="IExceptionHandler"/> for capturing unhandled exceptions.
19-
/// Call this in your service configuration alongside <c>app.UseExceptionHandler()</c>.
17+
/// Registers the Exceptionless <see cref="IExceptionHandler"/> and required ASP.NET Core services
18+
/// for capturing unhandled exceptions. Call this in your service configuration alongside <c>app.UseExceptionHandler()</c>.
2019
/// </summary>
21-
public static IServiceCollection AddExceptionlessAspNetCore(this IServiceCollection services) {
20+
public static IServiceCollection AddExceptionless(this IServiceCollection services) {
2221
services.AddHttpContextAccessor();
23-
services.TryAddEnumerable(ServiceDescriptor.Singleton<IExceptionHandler, ExceptionlessExceptionHandler>());
22+
services.AddExceptionHandler<ExceptionlessExceptionHandler>();
2423
return services;
2524
}
2625

@@ -42,7 +41,9 @@ public static IApplicationBuilder UseExceptionless(this IApplicationBuilder app,
4241
//client.Configuration.Resolver.Register<ILastReferenceIdManager, WebLastReferenceIdManager>();
4342

4443
var diagnosticListener = app.ApplicationServices.GetRequiredService<DiagnosticListener>();
45-
diagnosticListener?.Subscribe(new ExceptionlessDiagnosticListener(client));
44+
diagnosticListener?.Subscribe(
45+
new ExceptionlessDiagnosticListener(client),
46+
eventName => ExceptionlessDiagnosticListener.IsRelevantEvent(eventName));
4647

4748
var lifetime = app.ApplicationServices.GetRequiredService<IHostApplicationLifetime>();
4849
lifetime.ApplicationStopping.Register(() => client.ProcessQueueAsync().ConfigureAwait(false).GetAwaiter().GetResult());

src/Platforms/Exceptionless.AspNetCore/readme.txt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
-------------------------------------
1+
-------------------------------------
22
Exceptionless Readme
33
-------------------------------------
44
Exceptionless provides real-time error reporting for your apps. It organizes the
@@ -31,15 +31,18 @@ You must import the "Exceptionless" namespace and add the following code to regi
3131
using Exceptionless;
3232

3333
var builder = WebApplication.CreateBuilder(args);
34-
builder.Services.AddExceptionless("API_KEY_HERE");
34+
builder.AddExceptionless(c => c.ApiKey = "API_KEY_HERE");
35+
builder.Services.AddExceptionless();
36+
builder.Services.AddProblemDetails();
3537

3638
In order to start gathering unhandled exceptions, you will need to register the Exceptionless middleware in your application
3739
like this after building your application:
3840

3941
var app = builder.Build();
42+
app.UseExceptionHandler();
4043
app.UseExceptionless();
4144

42-
Alternatively, you can use different overloads of the AddExceptionless method for other configuration options.
45+
Alternatively, you can use different overloads of the host builder AddExceptionless method for other configuration options.
4346
Please visit the documentation at https://exceptionless.com/docs/clients/dotnet/sending-events/ for additional examples
4447
and guidance on sending events to Exceptionless.
4548

src/Platforms/Exceptionless.Extensions.Hosting/readme.txt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,22 @@ Please visit the documentation https://exceptionless.com/docs/clients/dotnet/pri
2424
for detailed information on how to configure the client to meet your requirements.
2525

2626
-------------------------------------
27-
Microsoft.Extensions.Logging Integration
27+
Microsoft.Extensions.Hosting Integration
2828
-------------------------------------
29-
You must import the "Exceptionless" namespace and call the following line
30-
of code to start reporting log messages.
29+
You must import the "Exceptionless" namespace and register Exceptionless on the
30+
host builder.
3131

32-
loggerFactory.AddExceptionless("API_KEY_HERE");
32+
var builder = Host.CreateApplicationBuilder(args);
33+
builder.AddExceptionless(c => c.ApiKey = "API_KEY_HERE");
34+
builder.UseExceptionless();
3335

34-
Alternatively, you can also use the different overloads of the AddExceptionless method
35-
for different configuration options.
36+
`AddExceptionless(...)` configures the client, and `UseExceptionless()` ensures
37+
the pending queue is flushed during host shutdown.
3638

3739
Please visit the documentation https://exceptionless.com/docs/clients/dotnet/sending-events/
3840
for examples on sending events to Exceptionless.
3941

4042
-------------------------------------
4143
Documentation and Support
4244
-------------------------------------
43-
Please visit http://exceptionless.io for documentation and support.
45+
Please visit http://exceptionless.io for documentation and support.

src/Platforms/Exceptionless.Extensions.Logging/readme.txt

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,21 @@ for detailed information on how to configure the client to meet your requirement
2626
-------------------------------------
2727
Microsoft.Extensions.Logging Integration
2828
-------------------------------------
29-
You must import the "Exceptionless" namespace and call the following line
30-
of code to start reporting log messages.
29+
You must import the "Exceptionless" namespace and add Exceptionless to the
30+
logging builder.
3131

32-
loggerFactory.AddExceptionless("API_KEY_HERE");
32+
var builder = Host.CreateApplicationBuilder(args);
33+
builder.Logging.AddExceptionless();
3334

34-
Alternatively, you can also use the different overloads of the AddExceptionless method
35-
for different configuration options.
35+
If you want to configure the client in the same app, pair this with one of the
36+
Exceptionless hosting registration overloads such as:
37+
38+
builder.AddExceptionless(c => c.ApiKey = "API_KEY_HERE");
3639

3740
Please visit the documentation https://exceptionless.com/docs/clients/dotnet/sending-events/
3841
for examples on sending events to Exceptionless.
3942

4043
-------------------------------------
4144
Documentation and Support
4245
-------------------------------------
43-
Please visit http://exceptionless.io for documentation and support.
46+
Please visit http://exceptionless.io for documentation and support.

0 commit comments

Comments
 (0)