Recommended: OpenTelemetry SDK
Auto-instrument ASP.NET Core, Entity Framework, HttpClient, and more.1. Install
dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol
dotnet add package OpenTelemetry.Extensions.Hosting
dotnet add package OpenTelemetry.Instrumentation.AspNetCore
dotnet add package OpenTelemetry.Instrumentation.Http
2. Configure
// Program.cs
using OpenTelemetry.Trace;
using OpenTelemetry.Logs;
using OpenTelemetry.Resources;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenTelemetry()
.ConfigureResource(r => r.AddService("my-dotnet-service"))
.WithTracing(t => t
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddOtlpExporter(o =>
{
o.Endpoint = new Uri("https://ingest.squasher.ai");
o.Headers = "x-squasher-key=sq_pk_your_api_key";
}))
.WithLogging(l => l
.AddOtlpExporter(o =>
{
o.Endpoint = new Uri("https://ingest.squasher.ai");
o.Headers = "x-squasher-key=sq_pk_your_api_key";
}));
3. Run
dotnet run
Alternative: Direct HTTP API
using System.Net.Http.Json;
public class SquasherClient
{
private static readonly HttpClient _client = new();
private const string Endpoint = "https://ingest.squasher.ai/v1/ingest/YOUR_PROJECT_ID";
private const string ApiKey = "sq_pk_your_api_key";
public static async Task CaptureErrorAsync(Exception ex, Dictionary<string, string>? tags = null)
{
var payload = new
{
message = ex.Message,
type = ex.GetType().Name,
level = "error",
stack = ex.StackTrace,
environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "production",
tags = tags,
};
var request = new HttpRequestMessage(HttpMethod.Post, Endpoint)
{
Content = JsonContent.Create(payload),
};
request.Headers.Add("x-squasher-key", ApiKey);
await _client.SendAsync(request);
}
}
Usage
try
{
await ProcessOrderAsync(order);
}
catch (Exception ex)
{
await SquasherClient.CaptureErrorAsync(ex, new() { ["orderId"] = order.Id });
throw;
}
Agent handoff
For .NET, prefer OpenTelemetry instrumentation for ASP.NET Core and HttpClient. Keep the Squasher key in configuration, set a service name, verify one exception, and use direct HTTP only when OTel is not practical.