Skip to content
System types · Built-in All levels

.NET service

The built-in .NET service system type — detecting services by their runtime, Kestrel and ASP.NET Core metrics, starter checks for thread-pool queuing, connection queues, exceptions and error-log spikes.

SLSluicio team 4 min read Updated Jul 2026

Not every system type is a broker: this one recognises your own .NET services — anything running on the .NET runtime, typically ASP.NET Core apps served by Kestrel. It’s a service type: instead of watching a piece of infrastructure, it watches the runtime signals that precede a .NET service falling over — the thread pool queuing work, Kestrel queuing connections, exceptions climbing, error logs spiking.

Key: dotnet-service · applied automatically to services emitting metrics prefixed process.runtime.dotnet, kestrel. or aspnetcore..

The metrics come straight from the OpenTelemetry .NET SDK — no Collector receiver involved. Add runtime and ASP.NET Core instrumentation to the service and export OTLP (to your Collector, which forwards to Sluicio):

Program.cs (metrics setup)
builder.Services.AddOpenTelemetry()
.ConfigureResource(r => r.AddService("orders-api"))
.WithMetrics(metrics => metrics
.AddRuntimeInstrumentation() // process.runtime.dotnet.*
.AddAspNetCoreInstrumentation() // aspnetcore.*, kestrel.* meters
.AddOtlpExporter());

The end-to-end setup — packages, traces and logs alongside the metrics, pointing the exporter at your Collector — is in Instrument a service.

Metrics prefixed process.runtime.dotnet (runtime instrumentation: thread pool, GC, exceptions), kestrel. (the web server: connections, queues) or aspnetcore. (the framework: routing, request handling). Any one of the three is enough to take on the type.

CheckConditionSeverityWhy it matters
Thread-pool queueprocess.runtime.dotnet.thread_pool.queue.length > 200WarningWork is arriving faster than threads pick it up — the classic prelude to timeouts, usually blocked threads or thread-pool starvation.
Kestrel queued connectionskestrel.queued_connections > 50WarningConnections are waiting to be accepted — the service is saturated at the front door and callers are already feeling the latency.
ExceptionsException count increasing by > 100 (delta)WarningA burst of thrown exceptions — even handled ones at this rate mean something upstream or downstream changed.
Error logs spiking≥ 25 error-level log records in the windowWarningThe service is narrating a problem; a spike above baseline deserves eyes before users report it.
  • Thresholds scale with traffic. 200 queued work items and 50 queued connections are meaningful on a mid-sized API and background noise on a huge one — set them from the service’s steady-state baseline (normally near zero for both; it’s sustained non-zero queuing that matters).
  • Exceptions counts thrown exceptions, not failed requests. A service that uses exceptions for control flow (or a chatty resilience library retrying) will need a higher floor. If the check is noisy, look at which exceptions before raising it — that’s sometimes the finding.
  • Error-log spike assumes your logs flow to Sluicio with the metrics; the threshold should sit above the service’s normal error chatter — a service that logs zero errors on a good day can run far tighter than 25.
  • Metric names differ across SDK versions — newer OpenTelemetry .NET releases emit dotnet.* runtime names alongside the process.runtime.dotnet.* family. If a check never fires, check the service’s metric catalog for which names it actually emits and adjust.