@fiberplane/hono-otel
Version:
Hono middleware to forward OpenTelemetry traces to a local instance of @fiberplane/studio
90 lines (89 loc) • 4.2 kB
TypeScript
import { type Attributes, type Span, type SpanKind } from "@opentelemetry/api";
import type { FpxLogger } from "./logger.js";
export type MeasureOptions<
/**
* Arguments for the function being measured
*/
ARGS,
/**
* The return type of the function being measured. This could be a value including a promise or a(n) (async) generator
*/
RESULT> = {
name: string;
/**
* The kind of the span
*/
spanKind?: SpanKind;
/**
* Attributes to be added to the span
*/
attributes?: Attributes;
onStart?: (span: Span, args: ARGS) => void;
/**
* Allows you to specify a function that will be called when the span ends
* and will be passed the span & result of the function being measured.
*
* This way you can do things like add additional attributes to the span
*/
onSuccess?: (span: Span, result: ExtractInnerResult<RESULT>) => RESULT extends Promise<unknown> ? Promise<void> | void : void;
/**
* This is an advanced feature in cases where you don't want the open telemetry spans
* to be ended automatically.
*
* Some disclaimers: this can only be used in combination with promises and with an onSuccess
* handler. This handler should call span.end() at some point. If you want the on success
* handler to trigger another async function you may want to use waitUntil to prevent the
* worker from terminating before the traces/spans are finished & send to the server
*
* How this is currently used;:
* We're using it to show the duration of a request in case it's being streamed back to
* the client. In those cases the response is returned early while work is still being done.
*
*/
endSpanManually?: boolean;
/**
* Allows you to specify a function that will be called when the span ends
* with an error and will be passed the (current) span & error that occurred.
*
* This way you can do things like add additional attributes to the span
*/
onError?: (span: Span, error: unknown) => void;
/**
* You can specify a function that will allow you to throw an error based on the value of the
* result (returned by the measured function). This error will only be used for recording the error
* in the span and will not be thrown.
*/
checkResult?: (result: ExtractInnerResult<RESULT>) => RESULT extends Promise<unknown> ? Promise<void> | void : RESULT extends AsyncGenerator<unknown, unknown, unknown> ? Promise<void> | void : void;
/**
* Optional logger module to use for logging on errors, etc.
* Similar to passing `console`. Should be an object with methods `debug`, `info`, `warn`, `error`.
*/
logger?: FpxLogger;
};
type ExtractInnerResult<TYPE> = TYPE extends Generator<infer T, infer TReturn, unknown> ? T | TReturn : TYPE extends AsyncGenerator<infer T, infer TReturn, unknown> ? T | TReturn : TYPE extends Promise<infer R> ? R : TYPE;
/**
* Wraps a function in a span, measuring the time it takes to execute
* the function.
*
* @param name (string) The name of the span that will be created
* @param fn (function) The function to be measured
* @returns (function) The wrapped function, with the same signature as the original function
*/
export declare function measure<T, A extends unknown[]>(name: string, fn: (...args: A) => T): (...args: A) => T;
/**
* Wraps a function in a span, measuring the time it takes to execute
* the function.
*
* @param options param name and spanKind
* @param fn
*/
export declare function measure<ARGS extends unknown[], RESULT>(options: MeasureOptions<ARGS, RESULT>, fn: (...args: ARGS) => RESULT): (...args: ARGS) => RESULT;
export declare function isGeneratorValue<T = unknown, TReturn = unknown, TNext = unknown>(value: unknown): value is Generator<T, TReturn, TNext>;
/**
* Type guard to check if a function is an async generator.
*
* @param fn - The function to be checked
* @returns true if the function is an async generator, otherwise false
*/
export declare function isAsyncGeneratorValue<T = unknown, TReturn = unknown, TNext = unknown>(value: unknown): value is AsyncGenerator<T, TReturn, TNext>;
export {};