{"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 {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n InstrumentationNodeModuleFile,\n isWrapped,\n safeExecuteInTheMiddle,\n SemconvStability,\n semconvStabilityFromStr,\n} from '@opentelemetry/instrumentation';\nimport {\n DB_SYSTEM_VALUE_MYSQL,\n ATTR_DB_STATEMENT,\n ATTR_DB_SYSTEM,\n} from './semconv';\nimport { addSqlCommenterComment } from '@opentelemetry/sql-common';\nimport type * as mysqlTypes from 'mysql2';\nimport { MySQL2InstrumentationConfig } from './types';\nimport {\n getConnectionAttributes,\n getConnectionPrototypeToInstrument,\n getQueryText,\n getSpanName,\n once,\n} from './utils';\n/** @knipignore */\nimport { PACKAGE_NAME, PACKAGE_VERSION } from './version';\nimport {\n ATTR_DB_QUERY_TEXT,\n ATTR_DB_SYSTEM_NAME,\n DB_SYSTEM_NAME_VALUE_MYSQL,\n} from '@opentelemetry/semantic-conventions';\n\ntype formatType = typeof mysqlTypes.format;\n\nconst supportedVersions = ['>=1.4.2 <4'];\n\nexport class MySQL2Instrumentation extends InstrumentationBase {\n private _netSemconvStability!: SemconvStability;\n private _dbSemconvStability!: SemconvStability;\n\n constructor(config: MySQL2InstrumentationConfig = {}) {\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 let format: formatType | undefined;\n function setFormatFunction(moduleExports: any) {\n if (!format && moduleExports.format) {\n format = moduleExports.format;\n }\n }\n const patch = (ConnectionPrototype: mysqlTypes.Connection) => {\n if (isWrapped(ConnectionPrototype.query)) {\n this._unwrap(ConnectionPrototype, 'query');\n }\n this._wrap(\n ConnectionPrototype,\n 'query',\n this._patchQuery(format, false) as any\n );\n if (isWrapped(ConnectionPrototype.execute)) {\n this._unwrap(ConnectionPrototype, 'execute');\n }\n this._wrap(\n ConnectionPrototype,\n 'execute',\n this._patchQuery(format, true) as any\n );\n };\n const unpatch = (ConnectionPrototype: mysqlTypes.Connection) => {\n this._unwrap(ConnectionPrototype, 'query');\n this._unwrap(ConnectionPrototype, 'execute');\n };\n return [\n new InstrumentationNodeModuleDefinition(\n 'mysql2',\n supportedVersions,\n (moduleExports: any) => {\n setFormatFunction(moduleExports);\n return moduleExports;\n },\n () => {},\n [\n new InstrumentationNodeModuleFile(\n 'mysql2/promise.js',\n supportedVersions,\n (moduleExports: any) => {\n setFormatFunction(moduleExports);\n return moduleExports;\n },\n () => {}\n ),\n new InstrumentationNodeModuleFile(\n 'mysql2/lib/connection.js',\n supportedVersions,\n (moduleExports: any) => {\n const ConnectionPrototype: mysqlTypes.Connection =\n getConnectionPrototypeToInstrument(moduleExports);\n patch(ConnectionPrototype);\n return moduleExports;\n },\n (moduleExports: any) => {\n if (moduleExports === undefined) return;\n const ConnectionPrototype: mysqlTypes.Connection =\n getConnectionPrototypeToInstrument(moduleExports);\n unpatch(ConnectionPrototype);\n }\n ),\n ]\n ),\n ];\n }\n\n private _patchQuery(format: formatType | undefined, isPrepared: boolean) {\n return (originalQuery: Function): Function => {\n const thisPlugin = this;\n return function query(\n this: mysqlTypes.Connection,\n query: string | mysqlTypes.Query | mysqlTypes.QueryOptions,\n _valuesOrCallback?: unknown[] | Function,\n _callback?: Function\n ) {\n let values;\n if (Array.isArray(_valuesOrCallback)) {\n values = _valuesOrCallback;\n } else if (arguments[2]) {\n values = [_valuesOrCallback];\n }\n const { maskStatement, maskStatementHook, responseHook } =\n thisPlugin.getConfig();\n\n const attributes: api.Attributes = getConnectionAttributes(\n this.config,\n thisPlugin._dbSemconvStability,\n thisPlugin._netSemconvStability\n );\n const dbQueryText = getQueryText(\n query,\n format,\n values,\n maskStatement,\n maskStatementHook\n );\n if (thisPlugin._dbSemconvStability & SemconvStability.OLD) {\n attributes[ATTR_DB_SYSTEM] = DB_SYSTEM_VALUE_MYSQL;\n attributes[ATTR_DB_STATEMENT] = dbQueryText;\n }\n if (thisPlugin._dbSemconvStability & SemconvStability.STABLE) {\n attributes[ATTR_DB_SYSTEM_NAME] = DB_SYSTEM_NAME_VALUE_MYSQL;\n attributes[ATTR_DB_QUERY_TEXT] = dbQueryText;\n }\n\n const span = thisPlugin.tracer.startSpan(getSpanName(query), {\n kind: api.SpanKind.CLIENT,\n attributes,\n });\n\n if (\n !isPrepared &&\n thisPlugin.getConfig().addSqlCommenterCommentToQueries\n ) {\n arguments[0] = query =\n typeof query === 'string'\n ? addSqlCommenterComment(span, query)\n : Object.assign(query, {\n sql: addSqlCommenterComment(span, query.sql),\n });\n }\n\n const endSpan = once((err?: any, results?: any) => {\n if (err) {\n span.setStatus({\n code: api.SpanStatusCode.ERROR,\n message: err.message,\n });\n } else {\n if (typeof responseHook === 'function') {\n safeExecuteInTheMiddle(\n () => {\n responseHook(span, {\n queryResults: results,\n });\n },\n err => {\n if (err) {\n thisPlugin._diag.warn('Failed executing responseHook', err);\n }\n },\n true\n );\n }\n }\n\n span.end();\n });\n\n if (arguments.length === 1) {\n if (typeof (query as any).onResult === 'function') {\n thisPlugin._wrap(\n query as any,\n 'onResult',\n thisPlugin._patchCallbackQuery(endSpan)\n );\n }\n\n const streamableQuery: mysqlTypes.Query = originalQuery.apply(\n this,\n arguments\n );\n\n // `end` in mysql behaves similarly to `result` in mysql2.\n streamableQuery\n .once('error', err => {\n endSpan(err);\n })\n .once('result', results => {\n endSpan(undefined, results);\n });\n\n return streamableQuery;\n }\n\n if (typeof arguments[1] === 'function') {\n thisPlugin._wrap(\n arguments,\n 1,\n thisPlugin._patchCallbackQuery(endSpan)\n );\n } else if (typeof arguments[2] === 'function') {\n thisPlugin._wrap(\n arguments,\n 2,\n thisPlugin._patchCallbackQuery(endSpan)\n );\n }\n\n return originalQuery.apply(this, arguments);\n };\n };\n }\n\n private _patchCallbackQuery(endSpan: Function) {\n return (originalCallback: Function) => {\n return function (\n err: mysqlTypes.QueryError | null,\n results?: any,\n fields?: mysqlTypes.FieldPacket[]\n ) {\n endSpan(err, results);\n return originalCallback(...arguments);\n };\n };\n }\n}\n"]}