Serverpod instrumentation and tracing
Relic SERVER spans, Postgres CLIENT spans, FutureCall CONSUMER traces, and outbound HttpClient traceparent in talaria_serverpod.
Turn Tracing on in Project settings. Successful transactions follow the traces sample rate. Error transactions are always sent. Spans use the OpenTelemetry span model. Inbound and outbound HTTP use W3C traceparent.
interceptDatabase is safe to register before init. It no-ops until a client exists and tracing is enabled.
Relic HTTP
TalariaServerpod.attach adds middleware on the API server and on the web server when that server exists. Each endpoint RPC and web route opens a SERVER span named {METHOD} {route}. An inbound traceparent is the parent. A streaming method keeps one SERVER span for the stream, not one per chunk.
A Flutter app using Talaria.wrapHttpClient continues into this span. The waterfall crosses the process boundary.
These paths are skipped: ingest (ingest and ingestBatch), Insights, /livez, /readyz, /startupz, /robots.txt, /favicon.ico, and /.well-known/.
Postgres
databaseInterceptor: TalariaServerpod.interceptDatabase wraps the session database. ORM queries and unsafeQuery become CLIENT spans with db.system.name. When raw SQL is available it is sanitized. Otherwise the span carries a stand-in such as SELECT Product. Bind values are not sent. Each repeated query is its own span, so an N+1 stays visible.
FutureCalls with no HTTP span in scope get a CONSUMER transaction named FutureCall.{name}. That transaction is not adopted from another session.
Outbound HTTP
dart:io HttpClient created after TalariaServerpod.init sends traceparent and records a CLIENT span while a request span is open. Ingest URLs are skipped.
package:http is not patched. Wrap it:
import 'package:http/http.dart' as http;
final httpClient = Talaria.wrapHttpClient(http.Client());Never wrap the SDK ingest client.
Manual spans
Redis and other caches are opt-in.
final span = Talaria.startSpan('charge', kind: SpanKind.client);
try {
await charge();
span.setStatus(SpanStatus.ok);
} catch (error, stackTrace) {
span.markError(message: error.toString());
await Talaria.captureException(error, stackTrace: stackTrace);
rethrow;
} finally {
span.finish();
}