.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.
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..
Getting the telemetry
Section titled “Getting the telemetry”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):
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.
What Sluicio detects
Section titled “What Sluicio detects”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.
Starter checks
Section titled “Starter checks”| Check | Condition | Severity | Why it matters |
|---|---|---|---|
| Thread-pool queue | process.runtime.dotnet.thread_pool.queue.length > 200 | Warning | Work is arriving faster than threads pick it up — the classic prelude to timeouts, usually blocked threads or thread-pool starvation. |
| Kestrel queued connections | kestrel.queued_connections > 50 | Warning | Connections are waiting to be accepted — the service is saturated at the front door and callers are already feeling the latency. |
| Exceptions | Exception count increasing by > 100 (delta) | Warning | A 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 window | Warning | The service is narrating a problem; a spike above baseline deserves eyes before users report it. |
Tuning notes
Section titled “Tuning notes”- 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 theprocess.runtime.dotnet.*family. If a check never fires, check the service’s metric catalog for which names it actually emits and adjust.