{"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';\nimport { EventEmitter } from 'events';\nimport {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n isWrapped,\n} from '@opentelemetry/instrumentation';\nimport {\n DBSYSTEMVALUES_MSSQL,\n SEMATTRS_DB_NAME,\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} from '@opentelemetry/semantic-conventions';\nimport type * as tedious from 'tedious';\nimport { TediousInstrumentationConfig } from './types';\nimport { getSpanName, once } from './utils';\n/** @knipignore */\nimport { PACKAGE_NAME, PACKAGE_VERSION } from './version';\n\nconst CURRENT_DATABASE = Symbol(\n 'opentelemetry.instrumentation-tedious.current-database'\n);\nconst PATCHED_METHODS = [\n 'callProcedure',\n 'execSql',\n 'execSqlBatch',\n 'execBulkLoad',\n 'prepare',\n 'execute',\n];\n\ntype UnknownFunction = (...args: any[]) => any;\ntype ApproxConnection = EventEmitter & {\n [CURRENT_DATABASE]: string;\n config: any;\n};\ntype ApproxRequest = EventEmitter & {\n sqlTextOrProcedure: string | undefined;\n callback: any;\n table: string | undefined;\n parametersByName: any;\n};\n\nfunction setDatabase(this: ApproxConnection, databaseName: string) {\n Object.defineProperty(this, CURRENT_DATABASE, {\n value: databaseName,\n writable: true,\n });\n}\n\nexport class TediousInstrumentation extends InstrumentationBase {\n static readonly COMPONENT = 'tedious';\n\n constructor(config: TediousInstrumentationConfig = {}) {\n super(PACKAGE_NAME, PACKAGE_VERSION, config);\n }\n\n protected init() {\n return [\n new InstrumentationNodeModuleDefinition(\n TediousInstrumentation.COMPONENT,\n ['>=1.11.0 <20'],\n (moduleExports: typeof tedious) => {\n const ConnectionPrototype: any = moduleExports.Connection.prototype;\n for (const method of PATCHED_METHODS) {\n if (isWrapped(ConnectionPrototype[method])) {\n this._unwrap(ConnectionPrototype, method);\n }\n this._wrap(\n ConnectionPrototype,\n method,\n this._patchQuery(method) as any\n );\n }\n\n if (isWrapped(ConnectionPrototype.connect)) {\n this._unwrap(ConnectionPrototype, 'connect');\n }\n this._wrap(ConnectionPrototype, 'connect', this._patchConnect);\n\n return moduleExports;\n },\n (moduleExports: typeof tedious) => {\n if (moduleExports === undefined) return;\n const ConnectionPrototype: any = moduleExports.Connection.prototype;\n for (const method of PATCHED_METHODS) {\n this._unwrap(ConnectionPrototype, method);\n }\n this._unwrap(ConnectionPrototype, 'connect');\n }\n ),\n ];\n }\n\n private _patchConnect(original: UnknownFunction): UnknownFunction {\n return function patchedConnect(this: ApproxConnection) {\n setDatabase.call(this, this.config?.options?.database);\n\n // remove the listener first in case it's already added\n this.removeListener('databaseChange', setDatabase);\n this.on('databaseChange', setDatabase);\n\n this.once('end', () => {\n this.removeListener('databaseChange', setDatabase);\n });\n return original.apply(this, arguments as unknown as any[]);\n };\n }\n\n private _patchQuery(operation: string) {\n return (originalMethod: UnknownFunction): UnknownFunction => {\n const thisPlugin = this;\n\n function patchedMethod(this: ApproxConnection, request: ApproxRequest) {\n if (!(request instanceof EventEmitter)) {\n thisPlugin._diag.warn(\n `Unexpected invocation of patched ${operation} method. Span not recorded`\n );\n return originalMethod.apply(this, arguments as unknown as any[]);\n }\n let procCount = 0;\n let statementCount = 0;\n const incrementStatementCount = () => statementCount++;\n const incrementProcCount = () => procCount++;\n const databaseName = this[CURRENT_DATABASE];\n const sql = (request => {\n // Required for <11.0.9\n if (\n request.sqlTextOrProcedure === 'sp_prepare' &&\n request.parametersByName?.stmt?.value\n ) {\n return request.parametersByName.stmt.value;\n }\n return request.sqlTextOrProcedure;\n })(request);\n\n const span = thisPlugin.tracer.startSpan(\n getSpanName(operation, databaseName, sql, request.table),\n {\n kind: api.SpanKind.CLIENT,\n attributes: {\n [SEMATTRS_DB_SYSTEM]: DBSYSTEMVALUES_MSSQL,\n [SEMATTRS_DB_NAME]: databaseName,\n [SEMATTRS_NET_PEER_PORT]: this.config?.options?.port,\n [SEMATTRS_NET_PEER_NAME]: this.config?.server,\n // >=4 uses `authentication` object, older versions just userName and password pair\n [SEMATTRS_DB_USER]:\n this.config?.userName ??\n this.config?.authentication?.options?.userName,\n [SEMATTRS_DB_STATEMENT]: sql,\n [SEMATTRS_DB_SQL_TABLE]: request.table,\n },\n }\n );\n\n const endSpan = once((err?: any) => {\n request.removeListener('done', incrementStatementCount);\n request.removeListener('doneInProc', incrementStatementCount);\n request.removeListener('doneProc', incrementProcCount);\n request.removeListener('error', endSpan);\n this.removeListener('end', endSpan);\n\n span.setAttribute('tedious.procedure_count', procCount);\n span.setAttribute('tedious.statement_count', statementCount);\n if (err) {\n span.setStatus({\n code: api.SpanStatusCode.ERROR,\n message: err.message,\n });\n }\n span.end();\n });\n\n request.on('done', incrementStatementCount);\n request.on('doneInProc', incrementStatementCount);\n request.on('doneProc', incrementProcCount);\n request.once('error', endSpan);\n this.on('end', endSpan);\n\n if (typeof request.callback === 'function') {\n thisPlugin._wrap(\n request,\n 'callback',\n thisPlugin._patchCallbackQuery(endSpan)\n );\n } else {\n thisPlugin._diag.error('Expected request.callback to be a function');\n }\n\n return api.context.with(\n api.trace.setSpan(api.context.active(), span),\n originalMethod,\n this,\n ...arguments\n );\n }\n\n Object.defineProperty(patchedMethod, 'length', {\n value: originalMethod.length,\n writable: false,\n });\n\n return patchedMethod;\n };\n }\n\n private _patchCallbackQuery(endSpan: Function) {\n return (originalCallback: Function) => {\n return function (\n this: any,\n err: Error | undefined | null,\n rowCount?: number,\n rows?: any\n ) {\n endSpan(err);\n return originalCallback.apply(this, arguments);\n };\n };\n }\n}\n"]}