{"version":3,"file":"instrumentation.js","sourceRoot":"","sources":["../../src/instrumentation.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,4CAM4B;AAC5B,oEAMwC;AAGxC,8EAK6C;AAC7C,uCAQmB;AACnB,oEAAwE;AACxE,mCAAkC;AAClC,8DAA2E;AAC3E,kBAAkB;AAClB,uCAA0D;AAE1D,MAAM,cAAc,GAAiC;IACnD,iBAAiB,EAAE,IAAI;CACxB,CAAC;AAEF,MAAa,sBAAuB,SAAQ,qCAAiD;IACnF,oBAAoB,CAAoB;IACxC,mBAAmB,CAAoB;IAE/C,YAAY,SAAuC,EAAE;QACnD,KAAK,CAAC,sBAAY,EAAE,yBAAe,EAAE,EAAE,GAAG,cAAc,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;QACvE,IAAI,CAAC,2BAA2B,EAAE,CAAC;IACrC,CAAC;IAED,oBAAoB;IACZ,2BAA2B;QACjC,IAAI,CAAC,oBAAoB,GAAG,IAAA,yCAAuB,EACjD,MAAM,EACN,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAC1C,CAAC;QACF,IAAI,CAAC,mBAAmB,GAAG,IAAA,yCAAuB,EAChD,UAAU,EACV,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAC1C,CAAC;IACJ,CAAC;IAEQ,SAAS,CAAC,SAAuC,EAAE;QAC1D,KAAK,CAAC,SAAS,CAAC,EAAE,GAAG,cAAc,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,IAAI;QACF,OAAO;YACL,IAAI,qDAAmC,CACrC,SAAS,EACT,CAAC,YAAY,CAAC,EACd,CAAC,MAAM,EAAE,aAAsB,EAAE,EAAE;gBACjC,MAAM,aAAa,GACjB,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,QAAQ;oBACrC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM;oBACvB,CAAC,CAAC,MAAM,CAAC,CAAC,WAAW;gBACzB,IAAI,IAAA,2BAAS,EAAC,aAAa,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE;oBAClD,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;iBACtD;gBACD,IAAI,CAAC,KAAK,CACR,aAAa,CAAC,SAAS,EACvB,aAAa,EACb,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,CACtC,CAAC;gBACF,IAAI,IAAA,2BAAS,EAAC,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE;oBAC9C,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;iBAClD;gBACD,IAAI,CAAC,KAAK,CACR,aAAa,CAAC,SAAS,EACvB,SAAS,EACT,IAAI,CAAC,gBAAgB,EAAE,CACxB,CAAC;gBACF,OAAO,MAAM,CAAC;YAChB,CAAC,EACD,MAAM,CAAC,EAAE;gBACP,IAAI,MAAM,KAAK,SAAS;oBAAE,OAAO;gBACjC,MAAM,aAAa,GACjB,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,QAAQ;oBACrC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM;oBACvB,CAAC,CAAC,MAAM,CAAC,CAAC,WAAW;gBACzB,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;gBACrD,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YACnD,CAAC,CACF;SACF,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,iBAAiB,CAAC,aAAsB;QAC9C,OAAO,CAAC,QAAkB,EAAE,EAAE;YAC5B,OAAO,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QACzD,CAAC,CAAC;IACJ,CAAC;IAEO,gBAAgB;QACtB,OAAO,CAAC,QAAkB,EAAE,EAAE;YAC5B,OAAO,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QACzC,CAAC,CAAC;IACJ,CAAC;IAEO,iBAAiB,CAAC,QAAkB,EAAE,aAAsB;QAClE,MAAM,eAAe,GAAG,IAAI,CAAC;QAC7B,OAAO,UAAgC,GAAoB;YACzD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;gBACnD,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;aACxC;YACD,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,EAAE,CAAC;YAC3C,MAAM,qBAAqB,GACzB,MAAM,CAAC,qBAAqB,IAAI,2CAA4B,CAAC;YAE/D,MAAM,eAAe,GAAG,WAAK,CAAC,OAAO,CAAC,aAAO,CAAC,MAAM,EAAE,CAAC,KAAK,SAAS,CAAC;YACtE,IAAI,MAAM,CAAC,iBAAiB,KAAK,IAAI,IAAI,eAAe,EAAE;gBACxD,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;aACxC;YAED,MAAM,UAAU,GAAe,EAAE,CAAC;YAClC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;YACpC,MAAM,WAAW,GAAG,qBAAqB,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;YAC9D,IAAI,eAAe,CAAC,mBAAmB,GAAG,kCAAgB,CAAC,GAAG,EAAE;gBAC9D,UAAU,CAAC,wBAAc,CAAC,GAAG,+BAAqB,CAAC;gBACnD,UAAU,CAAC,2BAAiB,CAAC,GAAG,WAAW,CAAC;gBAC5C,UAAU,CAAC,mCAAyB,CAAC,GAAG,WAAW,IAAI,IAAI,IAAI,EAAE,CAAC;aACnE;YACD,IAAI,eAAe,CAAC,mBAAmB,GAAG,kCAAgB,CAAC,MAAM,EAAE;gBACjE,UAAU,CAAC,0CAAmB,CAAC,GAAG,oCAA0B,CAAC;gBAC7D,UAAU,CAAC,yCAAkB,CAAC,GAAG,WAAW,CAAC;aAC9C;YACD,IAAI,eAAe,CAAC,oBAAoB,GAAG,kCAAgB,CAAC,GAAG,EAAE;gBAC/D,UAAU,CAAC,4BAAkB,CAAC,GAAG,IAAI,CAAC;gBACtC,UAAU,CAAC,4BAAkB,CAAC,GAAG,IAAI,CAAC;aACvC;YACD,IAAI,eAAe,CAAC,oBAAoB,GAAG,kCAAgB,CAAC,MAAM,EAAE;gBAClE,UAAU,CAAC,0CAAmB,CAAC,GAAG,IAAI,CAAC;gBACvC,UAAU,CAAC,uCAAgB,CAAC,GAAG,IAAI,CAAC;aACrC;YACD,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE;gBACtD,IAAI,EAAE,cAAQ,CAAC,MAAM;gBACrB,UAAU;aACX,CAAC,CAAC;YAEH,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC;YAC/B,IAAI,WAAW,EAAE;gBACf,IAAA,wCAAsB,EACpB,GAAG,EAAE,CACH,WAAW,CAAC,IAAI,EAAE;oBAChB,aAAa;oBACb,OAAO,EAAE,GAAG,CAAC,IAAI;oBACjB,OAAO,EAAE,GAAG,CAAC,IAAI;iBAClB,CAAC,EACJ,CAAC,CAAC,EAAE;oBACF,IAAI,CAAC,EAAE;wBACL,UAAI,CAAC,KAAK,CAAC,8CAA8C,EAAE,CAAC,CAAC,CAAC;qBAC/D;gBACH,CAAC,EACD,IAAI,CACL,CAAC;aACH;YAED,IAAI;gBACF,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;gBAE/C,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC;gBAChC,uDAAuD;gBACvD,GAAG,CAAC,OAAO,GAAG,UAAU,MAAW;oBACjC,IAAA,wCAAsB,EACpB,GAAG,EAAE,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,EAC7D,CAAC,CAAC,EAAE;wBACF,IAAI,CAAC,EAAE;4BACL,UAAI,CAAC,KAAK,CAAC,+CAA+C,EAAE,CAAC,CAAC,CAAC;yBAChE;oBACH,CAAC,EACD,IAAI,CACL,CAAC;oBAEF,IAAA,eAAO,EAAC,IAAI,EAAE,IAAI,CAAC,CAAC;oBACpB,WAAW,CAAC,MAAM,CAAC,CAAC;gBACtB,CAAC,CAAC;gBAEF,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC;gBAC9B,GAAG,CAAC,MAAM,GAAG,UAAU,GAAU;oBAC/B,IAAA,eAAO,EAAC,IAAI,EAAE,GAAG,CAAC,CAAC;oBACnB,UAAU,CAAC,GAAG,CAAC,CAAC;gBAClB,CAAC,CAAC;gBAEF,OAAO,MAAM,CAAC;aACf;YAAC,OAAO,KAAU,EAAE;gBACnB,IAAA,eAAO,EAAC,IAAI,EAAE,KAAK,CAAC,CAAC;gBACrB,MAAM,KAAK,CAAC;aACb;QACH,CAAC,CAAC;IACJ,CAAC;IAEO,gBAAgB,CAAC,QAAkB;QACzC,MAAM,eAAe,GAAG,IAAI,CAAC;QAC7B,OAAO;YACL,MAAM,eAAe,GAAG,WAAK,CAAC,OAAO,CAAC,aAAO,CAAC,MAAM,EAAE,CAAC,KAAK,SAAS,CAAC;YACtE,IACE,eAAe,CAAC,SAAS,EAAE,CAAC,iBAAiB,KAAK,IAAI;gBACtD,eAAe,EACf;gBACA,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;aACxC;YAED,MAAM,UAAU,GAAe,EAAE,CAAC;YAClC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;YACpC,IAAI,eAAe,CAAC,mBAAmB,GAAG,kCAAgB,CAAC,GAAG,EAAE;gBAC9D,UAAU,CAAC,wBAAc,CAAC,GAAG,+BAAqB,CAAC;gBACnD,UAAU,CAAC,2BAAiB,CAAC,GAAG,SAAS,CAAC;gBAC1C,UAAU,CAAC,mCAAyB,CAAC,GAAG,WAAW,IAAI,IAAI,IAAI,EAAE,CAAC;aACnE;YACD,IAAI,eAAe,CAAC,mBAAmB,GAAG,kCAAgB,CAAC,MAAM,EAAE;gBACjE,UAAU,CAAC,0CAAmB,CAAC,GAAG,oCAA0B,CAAC;gBAC7D,UAAU,CAAC,yCAAkB,CAAC,GAAG,SAAS,CAAC;aAC5C;YACD,IAAI,eAAe,CAAC,oBAAoB,GAAG,kCAAgB,CAAC,GAAG,EAAE;gBAC/D,UAAU,CAAC,4BAAkB,CAAC,GAAG,IAAI,CAAC;gBACtC,UAAU,CAAC,4BAAkB,CAAC,GAAG,IAAI,CAAC;aACvC;YACD,IAAI,eAAe,CAAC,oBAAoB,GAAG,kCAAgB,CAAC,MAAM,EAAE;gBAClE,UAAU,CAAC,0CAAmB,CAAC,GAAG,IAAI,CAAC;gBACvC,UAAU,CAAC,uCAAgB,CAAC,GAAG,IAAI,CAAC;aACrC;YACD,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE;gBACvD,IAAI,EAAE,cAAQ,CAAC,MAAM;gBACrB,UAAU;aACX,CAAC,CAAC;YAEH,IAAI;gBACF,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;gBAC/C,IAAA,eAAO,EAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBACpB,OAAO,MAAM,CAAC;aACf;YAAC,OAAO,KAAU,EAAE;gBACnB,IAAA,eAAO,EAAC,IAAI,EAAE,KAAK,CAAC,CAAC;gBACrB,MAAM,KAAK,CAAC;aACb;QACH,CAAC,CAAC;IACJ,CAAC;CACF;AA1ND,wDA0NC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n  diag,\n  trace,\n  context,\n  SpanKind,\n  type Attributes,\n} from '@opentelemetry/api';\nimport {\n  InstrumentationBase,\n  InstrumentationNodeModuleDefinition,\n  isWrapped,\n  SemconvStability,\n  semconvStabilityFromStr,\n} from '@opentelemetry/instrumentation';\nimport { IORedisInstrumentationConfig } from './types';\nimport { IORedisCommand, RedisInterface } from './internal-types';\nimport {\n  ATTR_DB_QUERY_TEXT,\n  ATTR_DB_SYSTEM_NAME,\n  ATTR_SERVER_ADDRESS,\n  ATTR_SERVER_PORT,\n} from '@opentelemetry/semantic-conventions';\nimport {\n  DB_SYSTEM_VALUE_REDIS,\n  DB_SYSTEM_NAME_VALUE_REDIS,\n  ATTR_DB_CONNECTION_STRING,\n  ATTR_DB_STATEMENT,\n  ATTR_DB_SYSTEM,\n  ATTR_NET_PEER_NAME,\n  ATTR_NET_PEER_PORT,\n} from './semconv';\nimport { safeExecuteInTheMiddle } from '@opentelemetry/instrumentation';\nimport { endSpan } from './utils';\nimport { defaultDbStatementSerializer } from '@opentelemetry/redis-common';\n/** @knipignore */\nimport { PACKAGE_NAME, PACKAGE_VERSION } from './version';\n\nconst DEFAULT_CONFIG: IORedisInstrumentationConfig = {\n  requireParentSpan: true,\n};\n\nexport class IORedisInstrumentation extends InstrumentationBase<IORedisInstrumentationConfig> {\n  private _netSemconvStability!: SemconvStability;\n  private _dbSemconvStability!: SemconvStability;\n\n  constructor(config: IORedisInstrumentationConfig = {}) {\n    super(PACKAGE_NAME, PACKAGE_VERSION, { ...DEFAULT_CONFIG, ...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  override setConfig(config: IORedisInstrumentationConfig = {}) {\n    super.setConfig({ ...DEFAULT_CONFIG, ...config });\n  }\n\n  init(): InstrumentationNodeModuleDefinition[] {\n    return [\n      new InstrumentationNodeModuleDefinition(\n        'ioredis',\n        ['>=2.0.0 <6'],\n        (module, moduleVersion?: string) => {\n          const moduleExports =\n            module[Symbol.toStringTag] === 'Module'\n              ? module.default // ESM\n              : module; // CommonJS\n          if (isWrapped(moduleExports.prototype.sendCommand)) {\n            this._unwrap(moduleExports.prototype, 'sendCommand');\n          }\n          this._wrap(\n            moduleExports.prototype,\n            'sendCommand',\n            this._patchSendCommand(moduleVersion)\n          );\n          if (isWrapped(moduleExports.prototype.connect)) {\n            this._unwrap(moduleExports.prototype, 'connect');\n          }\n          this._wrap(\n            moduleExports.prototype,\n            'connect',\n            this._patchConnection()\n          );\n          return module;\n        },\n        module => {\n          if (module === undefined) return;\n          const moduleExports =\n            module[Symbol.toStringTag] === 'Module'\n              ? module.default // ESM\n              : module; // CommonJS\n          this._unwrap(moduleExports.prototype, 'sendCommand');\n          this._unwrap(moduleExports.prototype, 'connect');\n        }\n      ),\n    ];\n  }\n\n  /**\n   * Patch send command internal to trace requests\n   */\n  private _patchSendCommand(moduleVersion?: string) {\n    return (original: Function) => {\n      return this._traceSendCommand(original, moduleVersion);\n    };\n  }\n\n  private _patchConnection() {\n    return (original: Function) => {\n      return this._traceConnection(original);\n    };\n  }\n\n  private _traceSendCommand(original: Function, moduleVersion?: string) {\n    const instrumentation = this;\n    return function (this: RedisInterface, cmd?: IORedisCommand) {\n      if (arguments.length < 1 || typeof cmd !== 'object') {\n        return original.apply(this, arguments);\n      }\n      const config = instrumentation.getConfig();\n      const dbStatementSerializer =\n        config.dbStatementSerializer || defaultDbStatementSerializer;\n\n      const hasNoParentSpan = trace.getSpan(context.active()) === undefined;\n      if (config.requireParentSpan === true && hasNoParentSpan) {\n        return original.apply(this, arguments);\n      }\n\n      const attributes: Attributes = {};\n      const { host, port } = this.options;\n      const dbQueryText = dbStatementSerializer(cmd.name, cmd.args);\n      if (instrumentation._dbSemconvStability & SemconvStability.OLD) {\n        attributes[ATTR_DB_SYSTEM] = DB_SYSTEM_VALUE_REDIS;\n        attributes[ATTR_DB_STATEMENT] = dbQueryText;\n        attributes[ATTR_DB_CONNECTION_STRING] = `redis://${host}:${port}`;\n      }\n      if (instrumentation._dbSemconvStability & SemconvStability.STABLE) {\n        attributes[ATTR_DB_SYSTEM_NAME] = DB_SYSTEM_NAME_VALUE_REDIS;\n        attributes[ATTR_DB_QUERY_TEXT] = dbQueryText;\n      }\n      if (instrumentation._netSemconvStability & SemconvStability.OLD) {\n        attributes[ATTR_NET_PEER_NAME] = host;\n        attributes[ATTR_NET_PEER_PORT] = port;\n      }\n      if (instrumentation._netSemconvStability & SemconvStability.STABLE) {\n        attributes[ATTR_SERVER_ADDRESS] = host;\n        attributes[ATTR_SERVER_PORT] = port;\n      }\n      const span = instrumentation.tracer.startSpan(cmd.name, {\n        kind: SpanKind.CLIENT,\n        attributes,\n      });\n\n      const { requestHook } = config;\n      if (requestHook) {\n        safeExecuteInTheMiddle(\n          () =>\n            requestHook(span, {\n              moduleVersion,\n              cmdName: cmd.name,\n              cmdArgs: cmd.args,\n            }),\n          e => {\n            if (e) {\n              diag.error('ioredis instrumentation: request hook failed', e);\n            }\n          },\n          true\n        );\n      }\n\n      try {\n        const result = original.apply(this, arguments);\n\n        const origResolve = cmd.resolve;\n        /* eslint-disable @typescript-eslint/no-explicit-any */\n        cmd.resolve = function (result: any) {\n          safeExecuteInTheMiddle(\n            () => config.responseHook?.(span, cmd.name, cmd.args, result),\n            e => {\n              if (e) {\n                diag.error('ioredis instrumentation: response hook failed', e);\n              }\n            },\n            true\n          );\n\n          endSpan(span, null);\n          origResolve(result);\n        };\n\n        const origReject = cmd.reject;\n        cmd.reject = function (err: Error) {\n          endSpan(span, err);\n          origReject(err);\n        };\n\n        return result;\n      } catch (error: any) {\n        endSpan(span, error);\n        throw error;\n      }\n    };\n  }\n\n  private _traceConnection(original: Function) {\n    const instrumentation = this;\n    return function (this: RedisInterface) {\n      const hasNoParentSpan = trace.getSpan(context.active()) === undefined;\n      if (\n        instrumentation.getConfig().requireParentSpan === true &&\n        hasNoParentSpan\n      ) {\n        return original.apply(this, arguments);\n      }\n\n      const attributes: Attributes = {};\n      const { host, port } = this.options;\n      if (instrumentation._dbSemconvStability & SemconvStability.OLD) {\n        attributes[ATTR_DB_SYSTEM] = DB_SYSTEM_VALUE_REDIS;\n        attributes[ATTR_DB_STATEMENT] = 'connect';\n        attributes[ATTR_DB_CONNECTION_STRING] = `redis://${host}:${port}`;\n      }\n      if (instrumentation._dbSemconvStability & SemconvStability.STABLE) {\n        attributes[ATTR_DB_SYSTEM_NAME] = DB_SYSTEM_NAME_VALUE_REDIS;\n        attributes[ATTR_DB_QUERY_TEXT] = 'connect';\n      }\n      if (instrumentation._netSemconvStability & SemconvStability.OLD) {\n        attributes[ATTR_NET_PEER_NAME] = host;\n        attributes[ATTR_NET_PEER_PORT] = port;\n      }\n      if (instrumentation._netSemconvStability & SemconvStability.STABLE) {\n        attributes[ATTR_SERVER_ADDRESS] = host;\n        attributes[ATTR_SERVER_PORT] = port;\n      }\n      const span = instrumentation.tracer.startSpan('connect', {\n        kind: SpanKind.CLIENT,\n        attributes,\n      });\n\n      try {\n        const client = original.apply(this, arguments);\n        endSpan(span, null);\n        return client;\n      } catch (error: any) {\n        endSpan(span, error);\n        throw error;\n      }\n    };\n  }\n}\n"]}