.NET
Collect .NET runtime and HTTP metrics from your services and get curated dashboards and alerts for them with a single import.
.NET apps instrumented with OpenTelemetry export their metrics over OTLP to
your LeanSignal agent gateway (one per cluster or environment) — never to a
remote or third-party endpoint. The gateway keeps full fidelity locally and
forwards only the demanded subset to your central dataplane. This integration covers
the CLR runtime (GC, JIT, thread pool, memory, exceptions) plus ASP.NET Core HTTP
server and HttpClient request metrics.
Metric names follow the standard OTLP → Prometheus normalization (dots become
underscores, unit/_total suffixes are added), so http.server.request.duration
becomes http_server_request_duration_seconds and dotnet.gc.collections
becomes dotnet_gc_collections_total. The demands below are built against those
names.
Prerequisites
Section titled “Prerequisites”- A LeanSignal agent gateway deployed and connected — one per cluster or
environment. If you haven’t deployed it yet, follow
Install the agent (source:
LeanSignal/leansignal-agent). It should show as Connected under Agents in the LeanSignal app. - Network reachability to the gateway’s OTLP port —
4317(gRPC) or4318(HTTP). See Agent configuration. - Your .NET app instrumented with the OpenTelemetry SDK, exporting metrics over OTLP to the gateway — configured in Setup.
- Editor or admin role in the LeanSignal app (importing a demand creates dashboards and alert rules).
Point your app’s OTLP exporter at your LeanSignal agent gateway (OTLP gRPC
:4317 / HTTP :4318) — not a SaaS endpoint.
Option A — manual SDK (recommended for ASP.NET Core apps). Add the instrumentation packages:
dotnet add package OpenTelemetry.Extensions.Hostingdotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocoldotnet add package OpenTelemetry.Instrumentation.AspNetCoredotnet add package OpenTelemetry.Instrumentation.Httpdotnet add package OpenTelemetry.Instrumentation.Runtimebuilder.Services.AddOpenTelemetry() .ConfigureResource(r => r.AddService("checkout-api")) .WithMetrics(m => m .AddAspNetCoreInstrumentation() // http.server.* (native on .NET 8+) .AddHttpClientInstrumentation() // http.client.* .AddRuntimeInstrumentation() // dotnet.* runtime metrics .AddOtlpExporter());export OTEL_SERVICE_NAME=checkout-apiexport OTEL_EXPORTER_OTLP_ENDPOINT=http://<gateway-host>:4317export OTEL_EXPORTER_OTLP_PROTOCOL=grpc # http/protobuf + :4318 for OTLP/HTTPOption B — zero-code auto-instrumentation (no code changes; metrics on by default):
curl -sSfL https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/latest/download/otel-dotnet-auto-install.sh -Osh ./otel-dotnet-auto-install.sh. $HOME/.otel-dotnet-auto/instrument.shexport OTEL_SERVICE_NAME=checkout-apiexport OTEL_EXPORTER_OTLP_ENDPOINT=http://<gateway-host>:4317export OTEL_METRICS_EXPORTER=otlp./MyAppLogs and traces
Section titled “Logs and traces”The .NET automatic instrumentation from Setup exports all three
signals by default: with OTEL_EXPORTER_OTLP_ENDPOINT set, traces and
ILogger log records flow to the gateway alongside metrics. To turn a signal
off, set OTEL_DOTNET_AUTO_TRACES_INSTRUMENTATION_ENABLED=false (or the
LOGS twin). If you wire the SDK manually instead, add the OpenTelemetry
logging provider and a TracerProvider with the same OTLP exporter. See the
.NET zero-code instrumentation docs.
Demands
Section titled “Demands”.NET ships as a ready-made demand in three variants. You don’t copy any JSON — in the LeanSignal app go to Demands, press the ˅ arrow on the Add Demand button (the arrow opens the import menu), choose Import from catalog…, and pick the variant. Each variant below lists the slug that identifies its published bundle. See Integrations for the full import flow.
The variants are nested — Standard is a superset of Essential, Extended a superset of Standard. Pick whichever is closest to what you need and treat it as a starting point: after import everything is a normal, editable copy, so retune thresholds, add or drop panels, and adjust queries for your environment — your edits reshape the demand automatically. Start small and re-import a larger variant later if you outgrow it.
The golden signals. 1 dashboard · 3 panels · 3 alerts — request rate, errors, and latency at a glance, plus a thread-pool starvation alert.
Import this variant from the catalog. Its demand slug:
dotnet-otel-demand-essentialDashboard — HTTP request rate, HTTP 5xx error rate, and HTTP request duration p95.
Alerts (3)
| Alert | Severity | Fires when |
|---|---|---|
| High HTTP 5xx error rate | critical | 5xx ratio > 5% for 5m |
| High HTTP p95 latency | warning | p95 latency > 1s for 5m |
| Thread pool queue backlog | warning | avg queue > 100 items for 10m |
Well-rounded runtime coverage. 1 dashboard · 7 panels · 5 alerts — adds memory, GC, and thread-pool health. The recommended default.
Import this variant from the catalog. Its demand slug:
dotnet-otel-demand-standardDashboard — everything in Essential, plus Working set memory, GC collections by generation, Time paused in GC, and Thread pool threads.
Alerts (5)
| Alert | Severity | Fires when |
|---|---|---|
| High HTTP 5xx error rate | critical | 5xx ratio > 5% for 5m |
| High HTTP p95 latency | warning | p95 latency > 1s for 5m |
| Thread pool queue backlog | warning | avg queue > 100 items for 10m |
| Excessive time in GC | warning | GC pause fraction > 10% for 10m |
| Elevated exception rate | warning | > 10 exceptions/s for 10m |
Deep CLR visibility. 1 dashboard · 14 panels · 9 alerts — CPU, allocations, lock contention, and outbound HTTP for services you need to diagnose, not just watch.
Import this variant from the catalog. Its demand slug:
dotnet-otel-demand-extendedDashboard — everything in Standard, plus HTTP client duration p95, CPU utilization, Exception rate, GC heap size by generation, GC heap allocation rate, Monitor lock contentions, and Thread pool queue length.
Alerts (9)
| Alert | Severity | Fires when |
|---|---|---|
| High HTTP 5xx error rate | critical | 5xx ratio > 5% for 5m |
| High HTTP p95 latency | warning | p95 latency > 1s for 5m |
| Thread pool queue backlog | warning | avg queue > 100 items for 10m |
| Excessive time in GC | warning | GC pause fraction > 10% for 10m |
| Elevated exception rate | warning | > 10 exceptions/s for 10m |
| Very high HTTP p99 latency | critical | p99 latency > 2.5s for 5m |
| Frequent gen2 garbage collections | warning | > 1 gen2 GC/s for 10m |
| High monitor lock contention | warning | > 50 contentions/s for 5m |
| High outbound HTTP error rate | warning | outbound 5xx > 10% for 5m |
Dashboards
Section titled “Dashboards”Each variant imports one .NET dashboard, its panels grouped into
collapsible sections. Every dashboard carries an Instance filter (on the
instance label), so one import covers the whole fleet — view every instance
at once, or focus on one. Legends are sortable tables showing last/mean/max per
series, so the outlier instance stands out. Dashboards are demand-driven:
importing one tells your agents to forward exactly the timeseries its panels
query, and nothing else. Panels are ordinary Perses panels — edit queries, add
panels, or retune them after import, and your changes reshape the demand
automatically.
Alerts
Section titled “Alerts”Thresholds are conservative starting points — tune them to your workload.
Next steps
Section titled “Next steps”- Demand-driven observability — why importing a demand also shapes what your agents collect.
- Agent configuration — the full agent config surface.
Thanks for your feedback!
Report sent — thank you!