TraceKit .NET SDK Setup
When To Use
Use this skill when the user asks to:
- Add TraceKit to a .NET application
- Add observability or APM to an ASP.NET Core project
- Instrument a C# service with distributed tracing
- Configure TraceKit API keys in a .NET project
- Debug production .NET services with live breakpoints
- Set up code monitoring in a .NET app
Non-Negotiable Rules
- Never hardcode API keys in code or
appsettings.json. Always useEnvironment.GetEnvironmentVariable("TRACEKIT_API_KEY")or User Secrets. - Always register TraceKit middleware before
MapControllers()--app.UseTraceKit()must be in the pipeline before endpoint routing. - Always include a verification step confirming traces appear in
https://app.tracekit.dev/traces. - Always enable code monitoring (
EnableCodeMonitoring = true) -- it is TraceKit's differentiator. - Use env vars or User Secrets for all secrets -- never commit API keys to source control.
Detection
Before applying this skill, detect the project type:
- Check for
*.csproj-- confirms this is a .NET project. - Check for
*.sln-- confirms a .NET solution. - Confirm ASP.NET Core -- scan
.csprojforMicrosoft.AspNetCoreorMicrosoft.NET.Sdk.WebSDK attribute. - Check .NET version -- requires .NET 8.0 or higher.
- Only ask the user if
.csprojis missing or framework cannot be determined.
Step 1: Environment Setup
Set the TRACEKIT_API_KEY environment variable. This is the only required secret.
Add to your environment:
export TRACEKIT_API_KEY=ctxio_your_api_key_here
Or use .NET User Secrets for local development:
dotnet user-secrets set "TraceKit:ApiKey" "ctxio_your_api_key_here"
Where to get your API key:
- Log in to TraceKit
- Go to API Keys page
- Generate a new key (starts with
ctxio_)
Do not commit real API keys. Use environment variables, User Secrets, Azure Key Vault, or AWS Secrets Manager.
Step 2: Install SDK
For ASP.NET Core (recommended)
dotnet add package TraceKit.AspNetCore
For vanilla .NET (console apps, workers)
dotnet add package TraceKit.Core
Prerequisites:
- .NET 8.0 or higher
- ASP.NET Core 8.0+ (for web applications)
- A TraceKit account (create one free)
Step 3: Configure in Program.cs
Add TraceKit to your ASP.NET Core application's service collection and middleware pipeline:
using TraceKit.AspNetCore;
var builder = WebApplication.CreateBuilder(args);
// Add TraceKit services to the DI container
builder.Services.AddTraceKit(options =>
{
options.ApiKey = Environment.GetEnvironmentVariable("TRACEKIT_API_KEY");
options.ServiceName = "my-dotnet-service";
options.Endpoint = "https://app.tracekit.dev/v1/traces";
options.EnableCodeMonitoring = true;
});
// Add your other services
builder.Services.AddControllers();
var app = builder.Build();
// Add TraceKit middleware -- MUST be before MapControllers
app.UseTraceKit();
app.UseRouting();
app.UseAuthorization();
app.MapControllers();
app.Run();
Key points:
AddTraceKit()registers all required services in the DI containerUseTraceKit()adds the tracing middleware to the HTTP pipelineUseTraceKit()must be called beforeMapControllers()andUseRouting()to capture the full request lifecycle
Step 4: Configuration via appsettings.json
As an alternative to inline configuration, use appsettings.json:
{
"TraceKit": {
"ApiKey": "",
"ServiceName": "my-dotnet-service",
"Endpoint": "https://app.tracekit.dev/v1/traces",
"EnableCodeMonitoring": true,
"Tracing": {
"Requests": true,
"Database": true,
"HttpClient": true,
"Exceptions": true
}
}
}
Then bind in Program.cs:
builder.Services.AddTraceKit(builder.Configuration.GetSection("TraceKit"));
Important: Do not put the actual API key in appsettings.json. Override it with an environment variable:
export TraceKit__ApiKey=ctxio_your_api_key_here
.NET's configuration system automatically merges environment variables with appsettings.json using the __ separator.
Step 5: Error Capture
TraceKit automatically captures unhandled exceptions via the middleware. For explicit error capture:
using TraceKit;
try
{
var result = await SomeRiskyOperationAsync();
}
catch (Exception ex)
{
TracekitSdk.CaptureException(ex);
throw; // Re-throw or handle
}
Step 5b: Snapshot Capture (Code Monitoring)
For programmatic snapshots, use the SnapshotClient directly — do not call through the SDK wrapper. The SDK uses stack inspection internally to identify the call site. Adding extra layers shifts the frame and causes snapshots to report the wrong source location.
Create a Breakpoints static helper:
using TraceKit;
public static class Breakpoints
{
private static ISnapshotClient? _snapshotClient;
public static void Init(TracekitSdk sdk)
{
_snapshotClient = sdk.SnapshotClient();
}
public static void Capture(string name, Dictionary<string, object> data)
{
_snapshotClient?.CheckAndCapture(name, data);
}
}
Initialize after SDK setup in Program.cs:
Breakpoints.Init(app.Services.GetRequiredService<TracekitSdk>());
Use at call sites:
Breakpoints.Capture("payment-failed", new() { ["orderId"] = orderId, ["error"] = ex.Message });
See the tracekit-code-monitoring skill for the full pattern across all languages.
Global exception handler middleware (for custom error responses):
app.UseExceptionHandler(exceptionHandlerApp =>
{
exceptionHandlerApp.Run(async context =>
{
var exception = context.Features.Get<IExceptionHandlerFeature>()?.Error;
if (exception != null)
{
TracekitSdk.CaptureException(exception);
}
context.Response.StatusCode = 500;
await context.Response.WriteAsJsonAsync(new { error = "Internal server error" });
});
});
// Place BEFORE UseTraceKit for proper ordering
app.UseTraceKit();
For adding context to traces, use manual spans:
using TraceKit;
using var span = TracekitSdk.StartSpan("process-order");
span.SetAttribute("order.id", orderId);
span.SetAttribute("user.id", userId);
try
{
var order = await ProcessOrderAsync(orderId);
}
catch (Exception ex)
{
TracekitSdk.CaptureException(ex);
throw;
}
Step 6: Database Tracing
TraceKit automatically traces Entity Framework Core and ADO.NET queries when configured. Add EF Core tracing:
builder.Services.AddDbContext<AppDbContext>(options =>
{
options.UseSqlServer(connectionString);
options.AddTraceKitInterceptor(); // Auto-trace all EF Core queries
});
For raw ADO.NET, wrap your connection:
using TraceKit.Data;
var tracedConnection = new TracekitDbConnection(originalConnection);
Traced queries include:
- SQL statement (parameterized -- no sensitive data)
- Database system and name
- Query duration
- Connection details
Step 7: HttpClient Tracing
Trace outgoing HTTP calls by adding the TraceKit handler to HttpClient:
// Via DI (recommended)
builder.Services.AddHttpClient("external-api")
.AddTraceKitHandler(); // Auto-trace all outgoing requests
// Usage in a controller or service
public class MyService
{
private readonly HttpClient _httpClient;
public MyService(IHttpClientFactory httpClientFactory)
{
_httpClient = httpClientFactory.CreateClient("external-api");
}
public async Task<string> GetDataAsync()
{
// This call is automatically traced
var response = await _httpClient.GetAsync("https://api.example.com/data");
return await response.Content.ReadAsStringAsync();
}
}
Trace context headers are automatically injected into outgoing requests for distributed tracing across services.
Step 8: Minimal API Support
TraceKit works with .NET Minimal APIs:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddTraceKit(options =>
{
options.ApiKey = Environment.GetEnvironmentVariable("TRACEKIT_API_KEY");
options.ServiceName = "my-minimal-api";
options.Endpoint = "https://app.tracekit.dev/v1/traces";
options.EnableCodeMonitoring = true;
});
var app = builder.Build();
app.UseTraceKit();
app.MapGet("/api/users", () =>
{
return Results.Ok(new[] { "alice", "bob" });
});
app.MapPost("/api/orders", (OrderRequest request) =>
{
using var span = TracekitSdk.StartSpan("create-order");
span.SetAttribute("order.item", request.Item);
// Process order...
return Results.Created($"/api/orders/{orderId}", order);
});
app.Run();
Step 9: Verification
After integrating, verify traces are flowing:
- Start your application with
TRACEKIT_API_KEYset:TRACEKIT_API_KEY=ctxio_... dotnet run. - Hit your endpoints 3-5 times -- e.g.,
curl http://localhost:5000/api/users. - Open
https://app.tracekit.dev/traces. - Confirm new spans and your service name appear within 30-60 seconds.
If traces do not appear, see Troubleshooting below.
Troubleshooting
Traces not appearing in dashboard
- Check
TRACEKIT_API_KEY: Ensure the env var is set in the runtime environment. Verify:Console.WriteLine(Environment.GetEnvironmentVariable("TRACEKIT_API_KEY")). - Check outbound access: Your service must reach
https://app.tracekit.dev/v1/traces. Verify with:curl -X POST https://app.tracekit.dev/v1/traces(expect 401 -- means the endpoint is reachable). - Check middleware order:
app.UseTraceKit()must be called beforeapp.MapControllers().
Middleware order wrong
Symptoms: Server starts fine but no traces appear despite traffic.
Fix: Ensure app.UseTraceKit() is called before app.UseRouting() and app.MapControllers():
app.UseTraceKit(); // First
app.UseRouting(); // Second
app.UseAuthorization();
app.MapControllers(); // Last
Missing environment variable
Symptoms: ApiKey is null warning on startup, or traces rejected by backend.
Fix: Ensure TRACEKIT_API_KEY is set. For local development, use User Secrets:
dotnet user-secrets set "TraceKit:ApiKey" "ctxio_your_key"
For production, use your platform's secret management (Azure Key Vault, AWS Secrets Manager, etc.).
Service name collisions
Symptoms: Traces appear under the wrong service in the dashboard.
Fix: Use a unique ServiceName per deployed service. Avoid generic names like "app" or "api".
Entity Framework queries not traced
Symptoms: HTTP requests show traces but database queries do not.
Fix: Ensure .AddTraceKitInterceptor() is called on your DbContextOptions. If using multiple contexts, add it to each one.
Next Steps
Once your .NET application is traced, consider:
- Code Monitoring -- Set live breakpoints and capture snapshots in production without redeploying (already enabled via
EnableCodeMonitoring = true) - Distributed Tracing -- Connect traces across multiple services for full request visibility
- Frontend Observability -- Add
@tracekit/browserto your frontend for end-to-end trace correlation
References
- .NET SDK docs:
https://app.tracekit.dev/docs/languages/dotnet - TraceKit docs root:
https://app.tracekit.dev/docs - Dashboard:
https://app.tracekit.dev - Quick start:
https://app.tracekit.dev/docs/quickstart