import { type Span, type SpanAttributes, SpanKind } from '@opentelemetry/api'; /** * Options shared by both calling conventions of {@link withSpan}. */ export interface WithSpanOptions { /** * OTel span kind. * @default SpanKind.INTERNAL */ kind?: SpanKind; /** Initial attributes to set on the span. */ attributes?: SpanAttributes; /** * Tracer name used when resolving the OTel tracer. * @default '@cleverbrush/otel' */ tracerName?: string; /** Tracer version. */ tracerVersion?: string; } /** * Handle returned by the disposable form of {@link withSpan}. * * Implements `AsyncDisposable` so it can be used with `await using`: * ```ts * await using handle = withSpan('my.operation'); * handle.span.setAttribute('key', value); * try { * // ... do work ... * } catch (err) { * handle.fail(err); * throw err; * } * // span.end() is called automatically when the block exits * ``` * * **Note:** The span created by the disposable form is NOT activated as * the current context span (OTel's public API requires a callback scope * for context propagation). DB / outbound-HTTP child spans created * inside the `await using` block will be siblings of this span (both * children of the enclosing HTTP span) rather than nested under it. * Use the callback form of `withSpan` when proper nesting is required. */ export interface SpanHandle { /** The underlying OTel span. Use it to set attributes or add events. */ readonly span: Span; /** * Records an exception and marks the span as errored. * * Idempotent — safe to call in a `catch` block even if the same * error might be reported elsewhere. */ fail(err: unknown): void; /** Ends the span. Called automatically when exiting an `await using` block. */ [Symbol.asyncDispose](): Promise; } /** * Wraps `fn` in a custom OTel span and returns whatever `fn` returns. * * The span is activated as the current context span via * `startActiveSpan`, so any child spans created inside `fn` (e.g. DB * queries from `instrumentKnex`) will be correctly nested under it. * Error handling is automatic — exceptions are recorded and the span is * marked `ERROR` before re-throwing. * * @example * ```ts * const result = await withSpan('order.process', async span => { * span.setAttribute('order.id', orderId); * return processOrder(orderId); // DB spans nest under this span * }); * ``` */ export declare function withSpan(name: string, fn: (span: Span) => T, options?: WithSpanOptions): T; /** * Creates a custom OTel span and returns a {@link SpanHandle} that * implements `AsyncDisposable`. * * Use with `await using` for an ergonomic resource-management syntax. * Note that the span is **not** the active context span (see * {@link SpanHandle} for details). Call {@link SpanHandle.fail} in a * `catch` block to record errors before re-throwing. * * @example * ```ts * await using handle = withSpan('todo.create', { attributes: { 'todo.user_id': userId } }); * try { * const todo = await db.todos.insert({...}); * handle.span.setAttribute('todo.id', todo.id); * } catch (err) { * handle.fail(err); * throw err; * } * ``` */ export declare function withSpan(name: string, options?: WithSpanOptions): SpanHandle;