{"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  SemconvStability,\n  semconvStabilityFromStr,\n} from '@opentelemetry/instrumentation';\nimport {\n  ATTR_DB_COLLECTION_NAME,\n  ATTR_DB_NAMESPACE,\n  ATTR_DB_QUERY_TEXT,\n  ATTR_DB_SYSTEM_NAME,\n  ATTR_SERVER_ADDRESS,\n  ATTR_SERVER_PORT,\n  DB_SYSTEM_NAME_VALUE_MICROSOFT_SQL_SERVER,\n} from '@opentelemetry/semantic-conventions';\nimport {\n  DB_SYSTEM_VALUE_MSSQL,\n  ATTR_DB_NAME,\n  ATTR_DB_SQL_TABLE,\n  ATTR_DB_STATEMENT,\n  ATTR_DB_SYSTEM,\n  ATTR_DB_USER,\n  ATTR_NET_PEER_NAME,\n  ATTR_NET_PEER_PORT,\n} from './semconv';\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);\n\nexport const INJECTED_CTX = Symbol(\n  'opentelemetry.instrumentation-tedious.context-info-injected'\n);\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<TediousInstrumentationConfig> {\n  static readonly COMPONENT = 'tedious';\n  private _netSemconvStability!: SemconvStability;\n  private _dbSemconvStability!: SemconvStability;\n\n  constructor(config: TediousInstrumentationConfig = {}) {\n    super(PACKAGE_NAME, PACKAGE_VERSION, config);\n    this._setSemconvStabilityFromEnv();\n  }\n\n  // Used for testing.\n  private _setSemconvStabilityFromEnv() {\n    this._netSemconvStability = semconvStabilityFromStr(\n      'http',\n      process.env.OTEL_SEMCONV_STABILITY_OPT_IN\n    );\n    this._dbSemconvStability = semconvStabilityFromStr(\n      'database',\n      process.env.OTEL_SEMCONV_STABILITY_OPT_IN\n    );\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, moduleExports) 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 _buildTraceparent(span: api.Span): string {\n    const sc = span.spanContext();\n    return `00-${sc.traceId}-${sc.spanId}-0${Number(sc.traceFlags || api.TraceFlags.NONE).toString(16)}`;\n  }\n\n  /**\n   * Fire a one-off `SET CONTEXT_INFO @opentelemetry_traceparent` on the same\n   * connection. Marks the request with INJECTED_CTX so our patch skips it.\n   */\n  private _injectContextInfo(\n    connection: any,\n    tediousModule: typeof tedious,\n    traceparent: string\n  ): Promise<void> {\n    return new Promise(resolve => {\n      try {\n        const sql = 'set context_info @opentelemetry_traceparent';\n        const req = new tediousModule.Request(sql, (_err: any) => {\n          resolve();\n        });\n        Object.defineProperty(req, INJECTED_CTX, { value: true });\n        const buf = Buffer.from(traceparent, 'utf8');\n        req.addParameter(\n          'opentelemetry_traceparent',\n          (tediousModule as any).TYPES.VarBinary,\n          buf,\n          { length: buf.length }\n        );\n\n        connection.execSql(req);\n      } catch {\n        resolve();\n      }\n    });\n  }\n\n  private _shouldInjectFor(operation: string): boolean {\n    return (\n      operation === 'execSql' ||\n      operation === 'execSqlBatch' ||\n      operation === 'callProcedure' ||\n      operation === 'execute'\n    );\n  }\n\n  private _patchQuery(operation: string, tediousModule: typeof tedious) {\n    return (originalMethod: UnknownFunction): UnknownFunction => {\n      const thisPlugin = this;\n\n      function patchedMethod(this: ApproxConnection, request: ApproxRequest) {\n        // Skip our own injected request\n        if ((request as any)?.[INJECTED_CTX]) {\n          return originalMethod.apply(this, arguments as unknown as any[]);\n        }\n\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 attributes: api.Attributes = {};\n        if (thisPlugin._dbSemconvStability & SemconvStability.OLD) {\n          attributes[ATTR_DB_SYSTEM] = DB_SYSTEM_VALUE_MSSQL;\n          attributes[ATTR_DB_NAME] = databaseName;\n          // >=4 uses `authentication` object; older versions just userName and password pair\n          attributes[ATTR_DB_USER] =\n            this.config?.userName ??\n            this.config?.authentication?.options?.userName;\n          attributes[ATTR_DB_STATEMENT] = sql;\n          attributes[ATTR_DB_SQL_TABLE] = request.table;\n        }\n        if (thisPlugin._dbSemconvStability & SemconvStability.STABLE) {\n          // The OTel spec for \"db.namespace\" discusses handling for connection\n          // to MSSQL \"named instances\". This isn't currently supported.\n          //    https://opentelemetry.io/docs/specs/semconv/database/sql-server/#:~:text=%5B1%5D%20db%2Enamespace\n          attributes[ATTR_DB_NAMESPACE] = databaseName;\n          attributes[ATTR_DB_SYSTEM_NAME] =\n            DB_SYSTEM_NAME_VALUE_MICROSOFT_SQL_SERVER;\n          attributes[ATTR_DB_QUERY_TEXT] = sql;\n          attributes[ATTR_DB_COLLECTION_NAME] = request.table;\n          // See https://opentelemetry.io/docs/specs/semconv/database/sql-server/#spans\n          // TODO(3290): can `db.response.status_code` be added?\n          // TODO(3290): is `operation` correct for `db.operation.name`\n          // TODO(3290): can `db.query.summary` reliably be calculated?\n          // TODO(3290): `db.stored_procedure.name`\n        }\n        if (thisPlugin._netSemconvStability & SemconvStability.OLD) {\n          attributes[ATTR_NET_PEER_NAME] = this.config?.server;\n          attributes[ATTR_NET_PEER_PORT] = this.config?.options?.port;\n        }\n        if (thisPlugin._netSemconvStability & SemconvStability.STABLE) {\n          attributes[ATTR_SERVER_ADDRESS] = this.config?.server;\n          attributes[ATTR_SERVER_PORT] = this.config?.options?.port;\n        }\n        const span = thisPlugin.tracer.startSpan(\n          getSpanName(operation, databaseName, sql, request.table),\n          {\n            kind: api.SpanKind.CLIENT,\n            attributes,\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            // TODO(3290): set `error.type` attribute?\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        const runUserRequest = () => {\n          return api.context.with(\n            api.trace.setSpan(api.context.active(), span),\n            originalMethod,\n            this,\n            ...arguments\n          );\n        };\n\n        const cfg = thisPlugin.getConfig();\n        const shouldInject =\n          cfg.enableTraceContextPropagation &&\n          thisPlugin._shouldInjectFor(operation);\n\n        if (!shouldInject) return runUserRequest();\n\n        const traceparent = thisPlugin._buildTraceparent(span);\n\n        void thisPlugin\n          ._injectContextInfo(this, tediousModule, traceparent)\n          .finally(runUserRequest);\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"]}