UNPKG

opentelemetry-instrumentation-neo4j

Version:

open telemetry instrumentation for the `neo4j` javascript driver

93 lines 5.12 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Neo4jInstrumentation = void 0; const api_1 = require("@opentelemetry/api"); const semantic_conventions_1 = require("@opentelemetry/semantic-conventions"); const version_1 = require("./version"); const instrumentation_1 = require("@opentelemetry/instrumentation"); const utils_1 = require("./utils"); class Neo4jInstrumentation extends instrumentation_1.InstrumentationBase { constructor(config = {}) { super('opentelemetry-instrumentation-neo4j', version_1.VERSION, Object.assign({}, config)); } setConfig(config = {}) { this._config = config; } init() { return [ this.getModuleDefinition('neo4j-driver-core', ['>=4.3.0 <5']), this.getModuleDefinition('neo4j-driver', ['>=4.0.0 <4.3.0']), ]; } getModuleDefinition(name, supportedVersions) { const apiModuleFiles = ['session', 'transaction'].map((file) => new instrumentation_1.InstrumentationNodeModuleFile(`${name}/lib/${file}.js`, supportedVersions, this.patchSessionOrTransaction.bind(this), this.unpatchSessionOrTransaction.bind(this))); const module = new instrumentation_1.InstrumentationNodeModuleDefinition(name, supportedVersions, undefined, undefined, apiModuleFiles); return module; } patchSessionOrTransaction(fileExport, moduleVersion) { const self = this; this._wrap(fileExport.default.prototype, 'run', (originalRun) => { return function (query) { var _a; if (((_a = self._config) === null || _a === void 0 ? void 0 : _a.ignoreOrphanedSpans) && !api_1.trace.getSpan(api_1.context.active())) { return originalRun.apply(this, arguments); } const connectionAttributes = (0, utils_1.getAttributesFromNeo4jSession)(this); const operation = query.trim().split(/\s+/)[0]; const span = self.tracer.startSpan(`${operation} ${connectionAttributes[semantic_conventions_1.SEMATTRS_DB_NAME]}`, { attributes: Object.assign(Object.assign({}, connectionAttributes), { [semantic_conventions_1.SEMATTRS_DB_SYSTEM]: 'neo4j', [semantic_conventions_1.SEMATTRS_DB_OPERATION]: operation, [semantic_conventions_1.SEMATTRS_DB_STATEMENT]: query }), kind: api_1.SpanKind.CLIENT, }); if (self._config.moduleVersionAttributeName) { span.setAttribute(self._config.moduleVersionAttributeName, moduleVersion); } const response = originalRun.apply(this, arguments); const originalSubscribe = response.subscribe; response.subscribe = function (observer) { const records = []; return originalSubscribe.call(this, Object.assign(Object.assign({}, observer), { onKeys: function (_keys) { if (!observer.onKeys) return; if (!observer.onCompleted) { span.end(); } return observer.onKeys.apply(this, arguments); }, onNext: function (record) { if (self._config.responseHook) { records.push(record); } if (observer.onNext) return observer.onNext.apply(this, arguments); }, onCompleted: function (summary) { if (self._config.responseHook) { (0, instrumentation_1.safeExecuteInTheMiddle)(() => self._config.responseHook(span, { records: records, summary }), (e) => { if (e) { api_1.diag.error('neo4j instrumentation: responseHook error', e); } }, true); } span.end(); if (observer.onCompleted) return observer.onCompleted.apply(this, arguments); }, onError: function (err) { span.recordException(err); span.setStatus({ code: api_1.SpanStatusCode.ERROR, message: err.message, }); span.end(); if (observer.onError) return observer.onError.apply(this, arguments); } })); }; return response; }; }); return fileExport; } unpatchSessionOrTransaction(fileExport) { this._unwrap(fileExport.default.prototype, 'run'); } } exports.Neo4jInstrumentation = Neo4jInstrumentation; //# sourceMappingURL=neo4j.js.map