Opinionated service defaults for ASP.NET Core applications, inspired by .NET Aspire. The Web SDK (ANcpLua.NET.Sdk.Web) automatically configures these when you use WebApplication.CreateBuilder().
Features
| Feature | Description |
|---|
| OpenTelemetry | Logging, metrics (ASP.NET Core, HTTP, Runtime), tracing with OTLP export |
| Auto-Instrumentation | Zero-config OTel spans for GenAI and database calls |
| Health Checks | /health (readiness) and /alive (liveness) endpoints |
| Service Discovery | Microsoft.Extensions.ServiceDiscovery enabled |
| HTTP Resilience | Standard resilience handlers with retries and circuit breakers |
| JSON Configuration | CamelCase naming, enum converters, nullable annotations |
| Security | Forwarded headers, HTTPS redirect, HSTS, antiforgery |
| Static Assets | Static file serving with proper caching |
| OpenAPI | Optional OpenAPI/Swagger documentation |
| DevLogs | Frontend console log bridge for unified debugging (Development only) |
Auto-Instrumentation
Preview Feature — Auto-instrumentation is implemented but pending
end-to-end validation. Report issues at
ANcpLua.NET.Sdk.
The SDK automatically instruments GenAI and database calls with OpenTelemetry spans via C# interceptors. No manual instrumentation code required.
GenAI Providers
Supported AI SDK calls are automatically wrapped with spans:
| Provider | Package | Instrumented Methods |
|---|
| OpenAI | OpenAI | CompleteChat*, GenerateEmbeddings* |
| Anthropic | Anthropic.SDK | CreateMessage, CreateMessageAsync |
| Azure OpenAI | Azure.AI.OpenAI | GetChatCompletions*, GetEmbeddings* |
| Ollama | OllamaSharp | ChatAsync, GenerateEmbeddingsAsync |
Emitted span attributes:
gen_ai.system — Provider name (openai, anthropic, etc.)
gen_ai.operation.name — Operation type (chat, embeddings)
gen_ai.request.model — Model name
gen_ai.usage.input_tokens — Input token count
gen_ai.usage.output_tokens — Output token count
Database Providers
ADO.NET DbCommand.Execute* calls are automatically instrumented:
| Provider | Package |
|---|
| DuckDB | DuckDB.NET.Data |
| SQLite | Microsoft.Data.Sqlite |
| PostgreSQL | Npgsql |
| MySQL | MySqlConnector |
| SQL Server | Microsoft.Data.SqlClient |
| Oracle | Oracle.ManagedDataAccess |
| Firebird | FirebirdSql.Data.FirebirdClient |
Emitted span attributes:
db.system.name — Database system (postgresql, mysql, etc.)
db.operation.name — Operation type (ExecuteReader, ExecuteNonQuery)
db.query.text — SQL command text
db.namespace — Database name
ActivitySources
The instrumentation uses these ActivitySource names:
| Source | Description |
|---|
ANcpSdk.GenAi | GenAI SDK instrumentation |
ANcpSdk.Db | Database instrumentation |
Subscribe to custom sources via configuration:
builder.UseANcpSdkConventions(options =>
{
options.OpenTelemetry.ConfigureTracing = tracing =>
tracing.AddSource("ANcpSdk.*", "MyApp");
});
[OTel] Attribute
Mark record properties for automatic Activity.SetTag() generation:
using ANcpSdk.AspNetCore.ServiceDefaults.Instrumentation;
public record ChatRequest(
[OTel("gen_ai.request.model")] string Model,
[OTel("gen_ai.request.max_tokens")] int? MaxTokens,
[OTel("gen_ai.request.temperature", SkipIfNull = false)] double? Temperature);
The source generator creates extension methods:
// Generated - call this to set all tags at once
activity.SetTagsFromChatRequest(request);
| Property | Type | Default | Description |
|---|
Name | string | — | OTel semantic convention tag |
SkipIfNull | bool | true | Skip tag if value is null |
Usage
var builder = WebApplication.CreateBuilder(args);
builder.UseANcpSdkConventions();
var app = builder.Build();
app.MapANcpSdkDefaultEndpoints();
app.Run();
When using ANcpLua.NET.Sdk.Web, the source generator automatically
intercepts WebApplication.CreateBuilder() calls, so explicit registration is
optional.
Configuration
Customize behavior through the options callback:
builder.UseANcpSdkConventions(options =>
{
options.Https.Enabled = true;
options.OpenApi.Enabled = true;
options.AntiForgery.Enabled = false;
options.DevLogs.Enabled = true;
options.OpenTelemetry.ConfigureTracing = tracing => tracing.AddSource("MyApp");
});
Configuration Options
Https
HTTPS and HSTS settings
| Property | Type | Default | Description |
|---|
Enabled | bool | true | Enable/disable this feature |
HstsEnabled | bool | true | Enable HTTP Strict Transport Security |
OpenApi
OpenAPI/Swagger settings
| Property | Type | Default | Description |
|---|
Enabled | bool | true | Enable/disable this feature |
ConfigureOpenApi | Action<OpenApiOptions>? | null | Custom OpenAPI options callback |
OpenTelemetry
Telemetry configuration
| Property | Type | Default | Description |
|---|
ConfigureLogging | Action<OpenTelemetryLoggerOptions>? | null | Custom logging configuration callback |
ConfigureMetrics | Action<MeterProviderBuilder>? | null | Custom metrics configuration callback |
ConfigureTracing | Action<TracerProviderBuilder>? | null | Custom tracing configuration callback |
AntiForgery
Anti-forgery token settings
| Property | Type | Default | Description |
|---|
Enabled | bool | true | Enable/disable this feature |
StaticAssets
Static file serving
| Property | Type | Default | Description |
|---|
Enabled | bool | true | Enable/disable this feature |
DevLogs
Browser console bridge
| Property | Type | Default | Description |
|---|
Enabled | bool | true | Enable/disable this feature |
RoutePattern | string | "/api/dev-logs" | URL route pattern for the endpoint |
EnableInProduction | bool | - | Allow in production (security risk) |
DevLogs - Frontend Console Bridge
Captures browser console.log/warn/error and sends to server logs. Enabled by default in Development.
Add to your HTML (only served in Development):
<script src="/dev-logs.js"></script>
All frontend logs appear in server output with [BROWSER] prefix:
info: DevLogEntry[0] [BROWSER] User clicked button
warn: DevLogEntry[0] [BROWSER] Deprecated API called
error: DevLogEntry[0] [BROWSER] Failed to fetch data
Opt-out
To disable auto-registration and configure services manually:
<PropertyGroup>
<AutoRegisterServiceDefaults>false</AutoRegisterServiceDefaults>
</PropertyGroup>