{"version":3,"file":"instrumentation.js","sourceRoot":"","sources":["../../src/instrumentation.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport * as api from '@opentelemetry/api';\n/** @knipignore */\nimport { PACKAGE_NAME, PACKAGE_VERSION } from './version';\nimport * as constants from './constants';\nimport {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n InstrumentationNodeModuleFile,\n isWrapped,\n} from '@opentelemetry/instrumentation';\nimport {\n SEMATTRS_DB_NAME,\n SEMATTRS_DB_OPERATION,\n SEMATTRS_DB_SQL_TABLE,\n SEMATTRS_DB_STATEMENT,\n SEMATTRS_DB_SYSTEM,\n SEMATTRS_DB_USER,\n SEMATTRS_NET_PEER_NAME,\n SEMATTRS_NET_PEER_PORT,\n SEMATTRS_NET_TRANSPORT,\n} from '@opentelemetry/semantic-conventions';\nimport * as utils from './utils';\nimport { KnexInstrumentationConfig } from './types';\n\nconst contextSymbol = Symbol('opentelemetry.instrumentation-knex.context');\nconst DEFAULT_CONFIG: KnexInstrumentationConfig = {\n maxQueryLength: 1022,\n requireParentSpan: false,\n};\n\nexport class KnexInstrumentation extends InstrumentationBase {\n constructor(config: KnexInstrumentationConfig = {}) {\n super(PACKAGE_NAME, PACKAGE_VERSION, { ...DEFAULT_CONFIG, ...config });\n }\n\n override setConfig(config: KnexInstrumentationConfig = {}) {\n super.setConfig({ ...DEFAULT_CONFIG, ...config });\n }\n\n init() {\n const module = new InstrumentationNodeModuleDefinition(\n constants.MODULE_NAME,\n constants.SUPPORTED_VERSIONS\n );\n\n module.files.push(\n this.getClientNodeModuleFileInstrumentation('src'),\n this.getClientNodeModuleFileInstrumentation('lib'),\n this.getRunnerNodeModuleFileInstrumentation('src'),\n this.getRunnerNodeModuleFileInstrumentation('lib'),\n this.getRunnerNodeModuleFileInstrumentation('lib/execution')\n );\n\n return module;\n }\n\n private getRunnerNodeModuleFileInstrumentation(basePath: string) {\n return new InstrumentationNodeModuleFile(\n `knex/${basePath}/runner.js`,\n constants.SUPPORTED_VERSIONS,\n (Runner: any, moduleVersion) => {\n this.ensureWrapped(\n Runner.prototype,\n 'query',\n this.createQueryWrapper(moduleVersion)\n );\n return Runner;\n },\n (Runner: any, moduleVersion) => {\n this._unwrap(Runner.prototype, 'query');\n return Runner;\n }\n );\n }\n\n private getClientNodeModuleFileInstrumentation(basePath: string) {\n return new InstrumentationNodeModuleFile(\n `knex/${basePath}/client.js`,\n constants.SUPPORTED_VERSIONS,\n (Client: any) => {\n this.ensureWrapped(\n Client.prototype,\n 'queryBuilder',\n this.storeContext.bind(this)\n );\n this.ensureWrapped(\n Client.prototype,\n 'schemaBuilder',\n this.storeContext.bind(this)\n );\n this.ensureWrapped(\n Client.prototype,\n 'raw',\n this.storeContext.bind(this)\n );\n return Client;\n },\n (Client: any) => {\n this._unwrap(Client.prototype, 'queryBuilder');\n this._unwrap(Client.prototype, 'schemaBuilder');\n this._unwrap(Client.prototype, 'raw');\n return Client;\n }\n );\n }\n\n private createQueryWrapper(moduleVersion?: string) {\n const instrumentation = this;\n return function wrapQuery(original: (...args: any[]) => any) {\n return function wrapped_logging_method(this: any, query: any) {\n const config = this.client.config;\n\n const table = utils.extractTableName(this.builder);\n // `method` actually refers to the knex API method - Not exactly \"operation\"\n // in the spec sense, but matches most of the time.\n const operation = query?.method;\n const name =\n config?.connection?.filename || config?.connection?.database;\n const { maxQueryLength } = instrumentation.getConfig();\n\n const attributes: api.SpanAttributes = {\n 'knex.version': moduleVersion,\n [SEMATTRS_DB_SYSTEM]: utils.mapSystem(config.client),\n [SEMATTRS_DB_SQL_TABLE]: table,\n [SEMATTRS_DB_OPERATION]: operation,\n [SEMATTRS_DB_USER]: config?.connection?.user,\n [SEMATTRS_DB_NAME]: name,\n [SEMATTRS_NET_PEER_NAME]: config?.connection?.host,\n [SEMATTRS_NET_PEER_PORT]: config?.connection?.port,\n [SEMATTRS_NET_TRANSPORT]:\n config?.connection?.filename === ':memory:' ? 'inproc' : undefined,\n };\n if (maxQueryLength) {\n // filters both undefined and 0\n attributes[SEMATTRS_DB_STATEMENT] = utils.limitLength(\n query?.sql,\n maxQueryLength\n );\n }\n\n const parentContext =\n this.builder[contextSymbol] || api.context.active();\n const parentSpan = api.trace.getSpan(parentContext);\n const hasActiveParent =\n parentSpan && api.trace.isSpanContextValid(parentSpan.spanContext());\n if (instrumentation._config.requireParentSpan && !hasActiveParent) {\n return original.bind(this)(...arguments);\n }\n\n const span = instrumentation.tracer.startSpan(\n utils.getName(name, operation, table),\n {\n kind: api.SpanKind.CLIENT,\n attributes,\n },\n parentContext\n );\n const spanContext = api.trace.setSpan(api.context.active(), span);\n\n return api.context\n .with(spanContext, original, this, ...arguments)\n .then((result: unknown) => {\n span.end();\n return result;\n })\n .catch((err: any) => {\n // knex adds full query with all the binding values to the message,\n // we want to undo that without changing the original error\n const formatter = utils.getFormatter(this);\n const fullQuery = formatter(query.sql, query.bindings || []);\n const message = err.message.replace(fullQuery + ' - ', '');\n const clonedError = utils.cloneErrorWithNewMessage(err, message);\n span.recordException(clonedError);\n span.setStatus({ code: api.SpanStatusCode.ERROR, message });\n span.end();\n throw err;\n });\n };\n };\n }\n\n private storeContext(original: Function) {\n return function wrapped_logging_method(this: any) {\n const builder = original.apply(this, arguments);\n // Builder is a custom promise type and when awaited it fails to propagate context.\n // We store the parent context at the moment of initiating the builder\n // otherwise we'd have nothing to attach the span as a child for in `query`.\n Object.defineProperty(builder, contextSymbol, {\n value: api.context.active(),\n });\n return builder;\n };\n }\n\n ensureWrapped(obj: any, methodName: string, wrapper: (original: any) => any) {\n if (isWrapped(obj[methodName])) {\n this._unwrap(obj, methodName);\n }\n this._wrap(obj, methodName, wrapper);\n }\n}\n"]}