All files / packages/telemetry/src instrumentation.ts

100% Statements 20/20
90.9% Branches 10/11
100% Functions 4/4
100% Lines 18/18

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70                                                                    33x 33x       33x       68x 68x   34x 34x       68x   68x 68x   68x       34x 34x 34x 34x 34x 34x 34x      
import { InstrumentationBase, type InstrumentationConfig } from '@opentelemetry/instrumentation'
import { addClientMiddleware } from '@ydbjs/core'
 
import pkg from '../package.json' with { type: 'json' }
 
import { YdbMetricsPipeline } from './metrics.js'
import { propagator } from './propagation.js'
import { YdbTracesPipeline } from './traces.js'
 
export type YdbInstrumentationConfig = InstrumentationConfig & {
	/**
	 * Include raw query text as `db.query.text`. Default `false`.
	 * Query text can carry PII (literals interpolated by the user), so the
	 * safe default is to omit. Enable per environment when you control the
	 * data flowing through.
	 */
	captureQueryText?: boolean
	/**
	 * Emit `ydb.AcquireSession` span. Default `false`.
	 * Session acquisition is almost always instant (warm pool hit), so the
	 * span is noise in 99% of traces. Turn on only when debugging session-
	 * pool starvation.
	 */
	emitAcquireSessionSpan?: boolean
}
 
export class YdbInstrumentation extends InstrumentationBase<YdbInstrumentationConfig> {
	#traces: YdbTracesPipeline | undefined
	#metrics: YdbMetricsPipeline | undefined
	#propagatorHandle: Disposable | undefined
 
	constructor(config: YdbInstrumentationConfig = {}) {
		// Defer `enable()` until our private fields are constructed —
		// `InstrumentationBase` would otherwise call it from inside super().
		super(pkg.name, pkg.version, { ...config, enabled: false })
		Eif (config.enabled !== false) this.enable()
	}
 
	protected init(): undefined {
		return undefined
	}
 
	override enable(): void {
		super.enable()
		if (this.#traces || this.#metrics) return
 
		let cfg = this.getConfig()
		this.#traces = new YdbTracesPipeline(this.tracer, this._diag, {
			captureQueryText: cfg.captureQueryText ?? false,
			emitAcquireSessionSpan: cfg.emitAcquireSessionSpan ?? false,
		})
		this.#traces.enable()
 
		this.#metrics = new YdbMetricsPipeline(this.meter)
		this.#metrics.enable()
 
		this.#propagatorHandle = addClientMiddleware(propagator)
	}
 
	override disable(): void {
		super.disable()
		this.#traces?.disable()
		this.#traces = undefined
		this.#metrics?.disable()
		this.#metrics = undefined
		this.#propagatorHandle?.[Symbol.dispose]()
		this.#propagatorHandle = undefined
	}
}