Elarion

Telemetry & observability

Elarion emits OpenTelemetry-compatible traces and metrics through System.Diagnostics — the host chooses exporters, the runtime forces no SDK dependency.

Elarion emits OpenTelemetry-compatible signals through System.Diagnostics.ActivitySource and System.Diagnostics.Metrics. The runtime packages do not depend on the OpenTelemetry SDK — the host chooses exporters and registers the sources and meters it wants to collect. This keeps the framework lightweight while making every framework-owned boundary observable.

Registering sources and meters

using Elarion.AspNetCore;
using Elarion.Abstractions.Diagnostics;
using Elarion.Abstractions.Scheduling;
using Elarion.Caching;
using Elarion.Resilience;

builder.Services
    .AddOpenTelemetry()
    .WithTracing(tracing => tracing
        .AddSource(
            JsonRpcTelemetry.ActivitySourceName,
            SchedulerTelemetry.ActivitySourceName,
            HandlerCacheTelemetry.ActivitySourceName,
            ResilienceTelemetry.ActivitySourceName,
            HandlerTelemetry.ActivitySourceName)
        /* add exporters */)
    .WithMetrics(metrics => metrics
        .AddMeter(
            JsonRpcTelemetry.MeterName,
            SchedulerTelemetry.MeterName,
            HandlerCacheTelemetry.MeterName,
            ResilienceTelemetry.MeterName,
            HandlerTelemetry.MeterName)
        /* add exporters */);

First-party surfaces

SurfaceSource / meterCoverage
JSON-RPCJsonRpcTelemetry (JsonRpc)Every request dispatch creates a span: single calls, notifications, batch items, invalid versions, unknown methods, invalid params, application errors, unhandled exceptions, invalid envelopes, parse errors, and batch-level failures. Registered methods use their canonical name; invalid/unregistered ones use bounded sentinels to avoid unbounded metric cardinality. Tags are bounded: method, response/error code, version, and batch index/size.
SchedulerSchedulerTelemetry (Elarion.Scheduling)Schedule/enqueue/cancel operations and job executions create spans. Runtime-scheduled jobs preserve scheduling trace context into the later execution span when possible. Fixed-rate, fixed-delay, cron, skipped, misfired/coalesced, retry, cancellation, and failure outcomes are trace-visible.
Handler cacheHandlerCacheTelemetry (Elarion.Caching)Cache get/create spans expose the precise outcome — miss-factory-executed, miss-non-cacheable, or cached-or-coalesced. Factory execution events, payload policy errors, and invalidation spans are trace-visible. Tags avoid full keys, raw user ids, and request values.
ResilienceResilienceTelemetry (Elarion.Resilience)Named policy execution spans expose final outcome and duration. Retry and timeout callbacks add span events under the default Microsoft/Polly-backed runtime.
HandlerHandlerTelemetry (Elarion.Handlers)Every generated handler is wrapped in a TracingDecorator as the outermost decorator, emitting one Internal span per invocation that parents any cache/resilience/pipeline child spans, plus execution count/duration metrics. Bounded tags only: handler name, request type name, and ok/error/exception outcome — never request or response payloads.

Handler tracing

Handler tracing follows the same "instrument always, collect on demand" model as the other surfaces: the generator wraps every handler in a TracingDecorator unconditionally, but the span is a no-op until a host registers the Elarion.Handlers source. To suppress handler telemetry, omit HandlerTelemetry.ActivitySourceName/MeterName from the OpenTelemetry registration. This mirrors how HttpClient and EF Core ship always-present ActivitySources and leave collection to the host — no opt-in attribute required. The handler span adds the application-operation boundary as the stable parent of the decorator chain, so JSON-RPC, scheduler, cache, and resilience child spans all appear inside it.

Client-side telemetry

The TypeScript JSON-RPC client stays OpenTelemetry-package-free and framework-free. It exposes an optional instrumentation hook (RpcInstrumentation) on createRpcClient/createRpcApi: supply an adapter — over @opentelemetry/api, or a hand-rolled W3C traceparent generator — to start a span per request/batch, inject trace-context headers, and record the outcome. The generated client never imports a tracing SDK, so client-side tracing stays a host decision. See TypeScript client.

On this page