UNPKG

@temporalio/interceptors-opentelemetry

Version:
87 lines (81 loc) 3.13 kB
import type { SpanProcessor } from '@opentelemetry/sdk-trace-base'; import type { Resource } from '@opentelemetry/resources'; import { SimplePlugin } from '@temporalio/plugin'; import type { InjectedSinks, ReplayWorkerOptions, WorkerOptions } from '@temporalio/worker'; import type { InterceptorOptions } from './client'; import { OpenTelemetryWorkflowClientInterceptor } from './client'; import { makeWorkflowExporter, OpenTelemetryActivityInboundInterceptor, OpenTelemetryActivityOutboundInterceptor, OpenTelemetryNexusInboundInterceptor, OpenTelemetryNexusOutboundInterceptor, } from './worker'; import type { OpenTelemetrySinks } from './workflow'; /** * Configuration options for {@link OpenTelemetryPlugin}. * * @experimental Plugins is an experimental feature; APIs may change without notice. */ export interface OpenTelemetryPluginOptions extends InterceptorOptions { /** OpenTelemetry resource attributes to attach to exported spans */ readonly resource: Resource; /** Exporter used to send spans to a tracing backend */ readonly spanProcessor: SpanProcessor; } /** * A plugin that adds OpenTelemetry tracing. * * Configures Client, Activity, and Workflow interceptors for trace propagation and injects * a span exporter sink for Workflow spans. * * @experimental Plugins is an experimental feature; APIs may change without notice. */ export class OpenTelemetryPlugin extends SimplePlugin { constructor(readonly otelOptions: OpenTelemetryPluginOptions) { const workflowInterceptorsPath = require.resolve('./workflow-interceptors'); const interceptorOptions = otelOptions.tracer ? { tracer: otelOptions.tracer } : {}; super({ name: 'OpenTelemetryPlugin', clientInterceptors: { workflow: [new OpenTelemetryWorkflowClientInterceptor(interceptorOptions)], }, workerInterceptors: { client: { workflow: [new OpenTelemetryWorkflowClientInterceptor(interceptorOptions)], }, workflowModules: [workflowInterceptorsPath], activity: [ (ctx) => ({ inbound: new OpenTelemetryActivityInboundInterceptor(ctx, interceptorOptions), outbound: new OpenTelemetryActivityOutboundInterceptor(ctx), }), ], nexus: [ (ctx) => ({ inbound: new OpenTelemetryNexusInboundInterceptor(ctx, interceptorOptions), outbound: new OpenTelemetryNexusOutboundInterceptor(ctx), }), ], }, }); } configureWorker(options: WorkerOptions): WorkerOptions { return super.configureWorker(this.injectSinks(options)); } configureReplayWorker(options: ReplayWorkerOptions): ReplayWorkerOptions { return super.configureReplayWorker(this.injectSinks(options)); } private injectSinks<T extends { sinks?: InjectedSinks<any> }>(options: T): T { const sinks: InjectedSinks<OpenTelemetrySinks> = { exporter: makeWorkflowExporter(this.otelOptions.spanProcessor, this.otelOptions.resource), }; return { ...options, sinks: { ...options.sinks, ...sinks, }, }; } }