UNPKG

opentelemetry-plugin-better-sqlite3

Version:
111 lines (110 loc) 5.03 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BetterSqlite3Instrumentation = void 0; const api_1 = require("@opentelemetry/api"); const instrumentation_1 = require("@opentelemetry/instrumentation"); const semantic_conventions_1 = require("@opentelemetry/semantic-conventions"); const supportedVersions = ['^7.0.0', '^8.0.0', '^9.0.0', '^10.0.0', '^11.0.0', '^12.0.0']; class BetterSqlite3Instrumentation extends instrumentation_1.InstrumentationBase { static COMPONENT = 'better-sqlite3'; constructor(config) { super('opentelemetry-instrumentation-better-sqlite3', '1.0.0', config ?? {}); } init() { return [ new instrumentation_1.InstrumentationNodeModuleDefinition('better-sqlite3', supportedVersions, (moduleExports, moduleVersion) => { api_1.diag.debug(`Applying patch for better-sqlite3@${moduleVersion}`); const proto = 'prototype' in moduleExports ? moduleExports.prototype : moduleExports.default.prototype; if (!(0, instrumentation_1.isWrapped)(proto.exec)) { this._wrap(proto, 'exec', this.patchExec); this._wrap(proto, 'prepare', this.patchPrepare); this._wrap(proto, 'pragma', this.patchPragma); } return moduleExports; }, (moduleExports, moduleVersion) => { if (moduleExports !== undefined) { api_1.diag.debug(`Removing patch for better-sqlite3@${moduleVersion}`); const proto = 'prototype' in moduleExports ? moduleExports.prototype : moduleExports.default.prototype; this._massUnwrap([proto], ['exec', 'prepare', 'pragma']); } }), ]; } createSpan(query, db, operation) { const statement = query.trim().split(/\s/u)[0]; const spanName = operation ? `${operation}: ${statement}` : statement; return this.tracer.startSpan(spanName, { kind: api_1.SpanKind.CLIENT, attributes: { [semantic_conventions_1.ATTR_DB_SYSTEM_NAME]: 'sqlite3', [semantic_conventions_1.ATTR_DB_QUERY_TEXT]: query, [semantic_conventions_1.ATTR_DB_NAMESPACE]: db.name, }, }); } static defaultRunner(span, original, this_, params) { try { const result = original.apply(this_, params); span.setStatus({ code: api_1.SpanStatusCode.OK }); return result; } catch (e) { span.setStatus({ code: api_1.SpanStatusCode.ERROR, message: e.message }); throw e; } finally { span.end(); } } patchExec = (original) => { const self = this; return function exec(...params) { const span = self.createSpan(params[0], this); return api_1.context.with(api_1.trace.setSpan(api_1.context.active(), span), () => BetterSqlite3Instrumentation.defaultRunner(span, original, this, params)); }; }; patchPrepare = (original) => { const self = this; return function prepare(...params) { const span = self.createSpan(params[0], this, 'prepare'); return api_1.context.with(api_1.trace.setSpan(api_1.context.active(), span), () => { try { const result = original.apply(this, params); span.setStatus({ code: api_1.SpanStatusCode.OK }); self._massWrap([result], ['run', 'get', 'all'], self.patchStatement); return result; } catch (e) { span.setStatus({ code: api_1.SpanStatusCode.ERROR, message: e.message }); throw e; } finally { span.end(); } }); }; }; patchPragma = (original) => { const self = this; return function pragma(...params) { const span = self.createSpan(`PRAGMA ${params[0]}`, this); return api_1.context.with(api_1.trace.setSpan(api_1.context.active(), span), () => BetterSqlite3Instrumentation.defaultRunner(span, original, this, params)); }; }; patchStatement = (original) => { const self = this; return function statement_handler(...params) { if (!self.isEnabled()) { self._unwrap(this, original.name); return original.apply(this, params); } const span = self.createSpan(this.source, this.database, original.name); return api_1.context.with(api_1.trace.setSpan(api_1.context.active(), span), () => BetterSqlite3Instrumentation.defaultRunner(span, original, this, params)); }; }; } exports.BetterSqlite3Instrumentation = BetterSqlite3Instrumentation;