{"version":3,"file":"instrumentation.js","sourceRoot":"","sources":["../../../src/v2-v3/instrumentation.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n  isWrapped,\n  InstrumentationBase,\n  InstrumentationNodeModuleDefinition,\n  safeExecuteInTheMiddle,\n  SemconvStability,\n  semconvStabilityFromStr,\n} from '@opentelemetry/instrumentation';\nimport {\n  endSpan,\n  getTracedCreateClient,\n  getTracedCreateStreamTrace,\n} from './utils';\nimport { RedisInstrumentationConfig } from '../types';\n/** @knipignore */\nimport { PACKAGE_NAME, PACKAGE_VERSION } from '../version';\nimport type { RedisCommand, RedisPluginClientTypes } from './internal-types';\nimport { Attributes, SpanKind, context, trace } from '@opentelemetry/api';\nimport {\n  ATTR_DB_SYSTEM_NAME,\n  ATTR_DB_QUERY_TEXT,\n  ATTR_DB_OPERATION_NAME,\n  ATTR_SERVER_ADDRESS,\n  ATTR_SERVER_PORT,\n} from '@opentelemetry/semantic-conventions';\nimport {\n  ATTR_DB_CONNECTION_STRING,\n  ATTR_DB_STATEMENT,\n  ATTR_DB_SYSTEM,\n  ATTR_NET_PEER_NAME,\n  ATTR_NET_PEER_PORT,\n  DB_SYSTEM_NAME_VALUE_REDIS,\n  DB_SYSTEM_VALUE_REDIS,\n} from '../semconv';\nimport { defaultDbStatementSerializer } from '@opentelemetry/redis-common';\n\nexport class RedisInstrumentationV2_V3 extends InstrumentationBase<RedisInstrumentationConfig> {\n  static readonly COMPONENT = 'redis';\n  private _semconvStability: SemconvStability;\n\n  constructor(config: RedisInstrumentationConfig = {}) {\n    super(PACKAGE_NAME, PACKAGE_VERSION, config);\n    this._semconvStability = config.semconvStability\n      ? config.semconvStability\n      : semconvStabilityFromStr(\n          'database',\n          process.env.OTEL_SEMCONV_STABILITY_OPT_IN\n        );\n  }\n\n  override setConfig(config: RedisInstrumentationConfig = {}) {\n    super.setConfig(config);\n    this._semconvStability = config.semconvStability\n      ? config.semconvStability\n      : semconvStabilityFromStr(\n          'database',\n          process.env.OTEL_SEMCONV_STABILITY_OPT_IN\n        );\n  }\n\n  protected init() {\n    return [\n      new InstrumentationNodeModuleDefinition(\n        'redis',\n        ['>=2.6.0 <4'],\n        moduleExports => {\n          if (\n            isWrapped(\n              moduleExports.RedisClient.prototype['internal_send_command']\n            )\n          ) {\n            this._unwrap(\n              moduleExports.RedisClient.prototype,\n              'internal_send_command'\n            );\n          }\n          this._wrap(\n            moduleExports.RedisClient.prototype,\n            'internal_send_command',\n            this._getPatchInternalSendCommand()\n          );\n\n          if (isWrapped(moduleExports.RedisClient.prototype['create_stream'])) {\n            this._unwrap(moduleExports.RedisClient.prototype, 'create_stream');\n          }\n          this._wrap(\n            moduleExports.RedisClient.prototype,\n            'create_stream',\n            this._getPatchCreateStream()\n          );\n\n          if (isWrapped(moduleExports.createClient)) {\n            this._unwrap(moduleExports, 'createClient');\n          }\n          this._wrap(\n            moduleExports,\n            'createClient',\n            this._getPatchCreateClient()\n          );\n          return moduleExports;\n        },\n        moduleExports => {\n          if (moduleExports === undefined) return;\n          this._unwrap(\n            moduleExports.RedisClient.prototype,\n            'internal_send_command'\n          );\n          this._unwrap(moduleExports.RedisClient.prototype, 'create_stream');\n          this._unwrap(moduleExports, 'createClient');\n        }\n      ),\n    ];\n  }\n\n  /**\n   * Patch internal_send_command(...) to trace requests\n   */\n  private _getPatchInternalSendCommand() {\n    const instrumentation = this;\n    return function internal_send_command(original: Function) {\n      return function internal_send_command_trace(\n        this: RedisPluginClientTypes,\n        cmd?: RedisCommand\n      ) {\n        // Versions of redis (2.4+) use a single options object\n        // instead of named arguments\n        if (arguments.length !== 1 || typeof cmd !== 'object') {\n          // We don't know how to trace this call, so don't start/stop a span\n          return original.apply(this, arguments);\n        }\n\n        const config = instrumentation.getConfig();\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 dbStatementSerializer =\n          config?.dbStatementSerializer || defaultDbStatementSerializer;\n\n        const attributes: Attributes = {};\n\n        if (instrumentation._semconvStability & SemconvStability.OLD) {\n          Object.assign(attributes, {\n            [ATTR_DB_SYSTEM]: DB_SYSTEM_VALUE_REDIS,\n            [ATTR_DB_STATEMENT]: dbStatementSerializer(cmd.command, cmd.args),\n          });\n        }\n\n        if (instrumentation._semconvStability & SemconvStability.STABLE) {\n          Object.assign(attributes, {\n            [ATTR_DB_SYSTEM_NAME]: DB_SYSTEM_NAME_VALUE_REDIS,\n            [ATTR_DB_OPERATION_NAME]: cmd.command,\n            [ATTR_DB_QUERY_TEXT]: dbStatementSerializer(cmd.command, cmd.args),\n          });\n        }\n\n        const span = instrumentation.tracer.startSpan(\n          `${RedisInstrumentationV2_V3.COMPONENT}-${cmd.command}`,\n          {\n            kind: SpanKind.CLIENT,\n            attributes,\n          }\n        );\n\n        // Set attributes for not explicitly typed RedisPluginClientTypes\n        if (this.connection_options) {\n          const connectionAttributes: Attributes = {};\n\n          if (instrumentation._semconvStability & SemconvStability.OLD) {\n            Object.assign(connectionAttributes, {\n              [ATTR_NET_PEER_NAME]: this.connection_options.host,\n              [ATTR_NET_PEER_PORT]: this.connection_options.port,\n            });\n          }\n\n          if (instrumentation._semconvStability & SemconvStability.STABLE) {\n            Object.assign(connectionAttributes, {\n              [ATTR_SERVER_ADDRESS]: this.connection_options.host,\n              [ATTR_SERVER_PORT]: this.connection_options.port,\n            });\n          }\n\n          span.setAttributes(connectionAttributes);\n        }\n\n        if (\n          this.address &&\n          instrumentation._semconvStability & SemconvStability.OLD\n        ) {\n          span.setAttribute(\n            ATTR_DB_CONNECTION_STRING,\n            `redis://${this.address}`\n          );\n        }\n\n        const originalCallback = arguments[0].callback;\n        if (originalCallback) {\n          const originalContext = context.active();\n          (arguments[0] as RedisCommand).callback = function callback<T>(\n            this: unknown,\n            err: Error | null,\n            reply: T\n          ) {\n            if (config?.responseHook) {\n              const responseHook = config.responseHook;\n              safeExecuteInTheMiddle(\n                () => {\n                  responseHook(span, cmd.command, cmd.args, reply);\n                },\n                err => {\n                  if (err) {\n                    instrumentation._diag.error(\n                      'Error executing responseHook',\n                      err\n                    );\n                  }\n                },\n                true\n              );\n            }\n\n            endSpan(span, err);\n            return context.with(\n              originalContext,\n              originalCallback,\n              this,\n              ...arguments\n            );\n          };\n        }\n        try {\n          // Span will be ended in callback\n          return original.apply(this, arguments);\n        } catch (rethrow: any) {\n          endSpan(span, rethrow);\n          throw rethrow; // rethrow after ending span\n        }\n      };\n    };\n  }\n\n  private _getPatchCreateClient() {\n    return function createClient(original: Function) {\n      return getTracedCreateClient(original);\n    };\n  }\n\n  private _getPatchCreateStream() {\n    return function createReadStream(original: Function) {\n      return getTracedCreateStreamTrace(original);\n    };\n  }\n}\n"]}