obsi_instrumentation_shelf 1.0.1 copy "obsi_instrumentation_shelf: ^1.0.1" to clipboard
obsi_instrumentation_shelf: ^1.0.1 copied to clipboard

Production Shelf server tracing and metrics middleware for Obsi.

obsi_instrumentation_shelf #

pub package CI License: MIT

obsi_instrumentation_shelf instruments inbound Shelf requests. It extracts W3C trace context and baggage, creates server spans, and optionally records OpenTelemetry-compatible request-duration metrics.

The package requires obsi. The core provides the tracer, meter, exporters, sampling, error management, and lifecycle.

Installation #

dart pub add obsi obsi_instrumentation_shelf shelf
import 'package:obsi/obsi.dart';
import 'package:obsi_instrumentation_shelf/obsi_instrumentation_shelf.dart';
import 'package:shelf/shelf.dart';

How it works #

The middleware surrounds a Shelf handler and keeps context current throughout its asynchronous execution and response body stream.

request → obsiMiddleware → handler → response stream
              │
              ├─ extract W3C context and baggage
              ├─ server span
              └─ http.server.request.duration

Basic usage #

final handler = const Pipeline()
    .addMiddleware(obsiMiddleware(
      tracer: Obsi.tracer,
      meter: Obsi.meter('http.server'),
      routeResolver: (request) => switch (request.url.path) {
        'users' => '/users',
        _ => '/unknown',
      },
    ))
    .addHandler((request) => Response.ok('ok'));

Incoming traceparent and tracestate continue a distributed trace. Incoming baggage is available through Baggage.current inside the handler.

Route templates and cardinality #

routeResolver should return a low-cardinality route template such as /users/:id, not the raw path /users/87421. The template is used in span names and metric attributes, so raw identifiers would create excessive cardinality.

obsiMiddleware(
  routeResolver: router.resolveTemplate,
  options: ObsiShelfOptions(
    shouldInstrument: (request) => request.url.path != 'health',
    requestAttributes: (request) => {
      'app.tenant.type': 'public',
    },
    responseAttributes: (request, response) => {
      'app.response.cached': response.headers['x-cache'] == 'HIT',
    },
    onInstrumentationError: diagnostics,
  ),
);

Route, filter, attribute, and propagator callbacks are failure-isolated. Their errors are reported through onInstrumentationError without replacing the application response.

HTTP semantics and failures #

Server spans and metrics use stable method, scheme, route, status, and error.type attributes. Query values are redacted. Unknown methods normalize to _OTHER, while the original method remains available on the span.

Server 4xx responses leave span status unset because they normally represent valid server handling of a client error. Server 5xx, handler exceptions, and response-stream failures set error status. Original errors and stack traces are re-thrown unchanged.

Response streams #

By default, the span remains open until the response body completes, fails, or is cancelled. This measures the full server operation.

obsiMiddleware(
  options: const ObsiShelfOptions(traceResponseBody: false),
);

Set traceResponseBody to false only when handler-return latency, rather than complete response duration, is the intended boundary.

Ownership and graceful shutdown #

The middleware owns neither the Shelf server, handler, response stream, tracer, nor meter. During shutdown, stop accepting requests, let active requests drain, then call await Obsi.shutdown().

API inventory #

Concept Public API When to use it
Shelf instrumentation obsiMiddleware Add server traces, W3C extraction, baggage, and metrics to a Shelf pipeline.
Configuration ObsiShelfOptions Configure filtering, custom attributes, response-stream boundaries, and diagnostics.
Request filter ShelfRequestPredicate Exclude health checks or intentionally unobserved routes.
Request attributes ShelfAttributeBuilder Add validated application metadata before the handler runs.
Response attributes ShelfResponseAttributeBuilder Add validated metadata after the handler returns.

Only declarations exported by package:obsi_instrumentation_shelf/obsi_instrumentation_shelf.dart are stable. See obsi for providers, sampling, semantic constants, privacy, and lifecycle. Licensed under the MIT License.

0
likes
160
points
63
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Production Shelf server tracing and metrics middleware for Obsi.

Repository (GitHub)
View/report issues
Contributing

Topics

#observability #shelf #server #tracing #metrics

License

MIT (license)

Dependencies

obsi, shelf

More

Packages that depend on obsi_instrumentation_shelf