From f5f7ac6196b5422e030a6913c491117a6a3a0690 Mon Sep 17 00:00:00 2001 From: Christian Savard Date: Thu, 2 Mar 2023 02:08:01 -0500 Subject: [PATCH] feat(ioredis): Update instrumentation-ioredis to version 5.x.x (#1121) --- .../opentelemetry-redis-common/src/index.ts | 2 +- .../.tav.yml | 2 +- .../README.md | 4 +-- .../package.json | 4 +-- .../src/instrumentation.ts | 18 +++++------- .../src/internal-types.ts | 29 +++++++++++++++++++ .../src/types.ts | 25 ++++------------ .../test/ioredis.test.ts | 10 +++---- 8 files changed, 54 insertions(+), 40 deletions(-) create mode 100644 plugins/node/opentelemetry-instrumentation-ioredis/src/internal-types.ts diff --git a/packages/opentelemetry-redis-common/src/index.ts b/packages/opentelemetry-redis-common/src/index.ts index 03f0d2845a..eb093cb773 100644 --- a/packages/opentelemetry-redis-common/src/index.ts +++ b/packages/opentelemetry-redis-common/src/index.ts @@ -44,7 +44,7 @@ const serializationSubsets = [ export type DbStatementSerializer = ( cmdName: string, - cmdArgs: Array + cmdArgs: Array ) => string; /** diff --git a/plugins/node/opentelemetry-instrumentation-ioredis/.tav.yml b/plugins/node/opentelemetry-instrumentation-ioredis/.tav.yml index 5b1b56c88c..29bd4413db 100644 --- a/plugins/node/opentelemetry-instrumentation-ioredis/.tav.yml +++ b/plugins/node/opentelemetry-instrumentation-ioredis/.tav.yml @@ -1,6 +1,6 @@ ioredis: # Ignoring v4.19.0. Tests never ends. Caused by https://github.com/luin/ioredis/pull/1219 - versions: "^2.5.0 || ^3.2.2 || 4.14.1 || 4.16.3 || 4.17.3 || 4.18.0 || 4.19.2 || 4.19.4 || 4.22.0 || 4.24.5 || 4.26.0 || 4.27.2 || ^4.27.6" + versions: "^2.5.0 || ^3.2.2 || 4.14.1 || 4.16.3 || 4.17.3 || 4.18.0 || 4.19.2 || 4.19.4 || 4.22.0 || 4.24.5 || 4.26.0 || 4.27.2 || ^4.27.6 || 5.0.4 || ^5.2.4" commands: npm run test # Fix missing `contrib-test-utils` package diff --git a/plugins/node/opentelemetry-instrumentation-ioredis/README.md b/plugins/node/opentelemetry-instrumentation-ioredis/README.md index a9d72ffd3d..61444f28e7 100644 --- a/plugins/node/opentelemetry-instrumentation-ioredis/README.md +++ b/plugins/node/opentelemetry-instrumentation-ioredis/README.md @@ -17,7 +17,7 @@ npm install --save @opentelemetry/instrumentation-ioredis ### Supported Versions -- `>=2.0.0 <5` +- `>=2.0.0 <6` ## Usage @@ -47,7 +47,7 @@ registerInstrumentations({ IORedis instrumentation has few options available to choose from. You can set the following: | Options | Type | Description | -| ----------------------- | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | +|-------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------| | `dbStatementSerializer` | `DbStatementSerializer` | IORedis instrumentation will serialize db.statement using the specified function. | | `requestHook` | `RedisRequestCustomAttributeFunction` (function) | Function for adding custom attributes on db request. Receives params: `span, { moduleVersion, cmdName, cmdArgs }` | | `responseHook` | `RedisResponseCustomAttributeFunction` (function) | Function for adding custom attributes on db response | diff --git a/plugins/node/opentelemetry-instrumentation-ioredis/package.json b/plugins/node/opentelemetry-instrumentation-ioredis/package.json index c65c6b254d..385b403481 100644 --- a/plugins/node/opentelemetry-instrumentation-ioredis/package.json +++ b/plugins/node/opentelemetry-instrumentation-ioredis/package.json @@ -59,8 +59,8 @@ "@types/sinon": "10.0.9", "@types/node": "18.11.7", "cross-env": "7.0.3", + "ioredis": "5.2.2", "gts": "3.1.0", - "ioredis": "4.27.7", "mocha": "7.2.0", "nyc": "15.1.0", "rimraf": "3.0.2", @@ -73,7 +73,7 @@ "@opentelemetry/instrumentation": "^0.35.1", "@opentelemetry/redis-common": "^0.34.0", "@opentelemetry/semantic-conventions": "^1.0.0", - "@types/ioredis": "4.26.6" + "@types/ioredis4": "npm:@types/ioredis@^4.28.10" }, "homepage": "https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/plugins/node/opentelemetry-instrumentation-ioredis#readme" } diff --git a/plugins/node/opentelemetry-instrumentation-ioredis/src/instrumentation.ts b/plugins/node/opentelemetry-instrumentation-ioredis/src/instrumentation.ts index 8f0c793d50..94f8b850ed 100644 --- a/plugins/node/opentelemetry-instrumentation-ioredis/src/instrumentation.ts +++ b/plugins/node/opentelemetry-instrumentation-ioredis/src/instrumentation.ts @@ -15,13 +15,13 @@ */ import { diag, trace, context, SpanKind } from '@opentelemetry/api'; -import type * as ioredisTypes from 'ioredis'; import { InstrumentationBase, InstrumentationNodeModuleDefinition, isWrapped, } from '@opentelemetry/instrumentation'; -import { IORedisInstrumentationConfig, IORedisCommand } from './types'; +import { IORedisInstrumentationConfig } from './types'; +import { IORedisCommand, RedisInterface } from './internal-types'; import { DbSystemValues, SemanticAttributes, @@ -35,9 +35,7 @@ const DEFAULT_CONFIG: IORedisInstrumentationConfig = { requireParentSpan: true, }; -export class IORedisInstrumentation extends InstrumentationBase< - typeof ioredisTypes -> { +export class IORedisInstrumentation extends InstrumentationBase { constructor(_config: IORedisInstrumentationConfig = {}) { super( '@opentelemetry/instrumentation-ioredis', @@ -46,11 +44,11 @@ export class IORedisInstrumentation extends InstrumentationBase< ); } - init(): InstrumentationNodeModuleDefinition[] { + init(): InstrumentationNodeModuleDefinition[] { return [ - new InstrumentationNodeModuleDefinition( + new InstrumentationNodeModuleDefinition( 'ioredis', - ['>1 <5'], + ['>1', '<6'], (moduleExports, moduleVersion?: string) => { diag.debug('Applying patch for ioredis'); if (isWrapped(moduleExports.prototype.sendCommand)) { @@ -98,7 +96,7 @@ export class IORedisInstrumentation extends InstrumentationBase< private traceSendCommand = (original: Function, moduleVersion?: string) => { const instrumentation = this; - return function (this: ioredisTypes.Redis, cmd?: IORedisCommand) { + return function (this: RedisInterface, cmd?: IORedisCommand) { if (arguments.length < 1 || typeof cmd !== 'object') { return original.apply(this, arguments); } @@ -184,7 +182,7 @@ export class IORedisInstrumentation extends InstrumentationBase< private traceConnection = (original: Function) => { const instrumentation = this; - return function (this: ioredisTypes.Redis) { + return function (this: RedisInterface) { const config = instrumentation.getConfig() as IORedisInstrumentationConfig; const hasNoParentSpan = trace.getSpan(context.active()) === undefined; diff --git a/plugins/node/opentelemetry-instrumentation-ioredis/src/internal-types.ts b/plugins/node/opentelemetry-instrumentation-ioredis/src/internal-types.ts new file mode 100644 index 0000000000..b399a1eb79 --- /dev/null +++ b/plugins/node/opentelemetry-instrumentation-ioredis/src/internal-types.ts @@ -0,0 +1,29 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import type { Command, Redis } from 'ioredis'; +import type * as LegacyIORedis from 'ioredis4'; + +interface LegacyIORedisCommand { + reject: (err: Error) => void; + resolve: (result: {}) => void; + promise: Promise<{}>; + args: Array; + callback: LegacyIORedis.CallbackFunction; + name: string; +} + +export type IORedisCommand = Command | LegacyIORedisCommand; +export type RedisInterface = Redis | LegacyIORedis.Redis; diff --git a/plugins/node/opentelemetry-instrumentation-ioredis/src/types.ts b/plugins/node/opentelemetry-instrumentation-ioredis/src/types.ts index 66f3137484..5d32116a67 100644 --- a/plugins/node/opentelemetry-instrumentation-ioredis/src/types.ts +++ b/plugins/node/opentelemetry-instrumentation-ioredis/src/types.ts @@ -14,18 +14,10 @@ * limitations under the License. */ -import type * as ioredisTypes from 'ioredis'; import { InstrumentationConfig } from '@opentelemetry/instrumentation'; import { Span } from '@opentelemetry/api'; -export interface IORedisCommand { - reject: (err: Error) => void; - resolve: (result: {}) => void; - promise: Promise<{}>; - args: Array; - callback: ioredisTypes.CallbackFunction; - name: string; -} +export type CommandArgs = Array; /** * Function that can be used to serialize db.statement tag @@ -35,14 +27,14 @@ export interface IORedisCommand { * @returns serialized string that will be used as the db.statement attribute. */ export type DbStatementSerializer = ( - cmdName: IORedisCommand['name'], - cmdArgs: IORedisCommand['args'] + cmdName: string, + cmdArgs: CommandArgs ) => string; export interface IORedisRequestHookInformation { moduleVersion?: string; - cmdName: IORedisCommand['name']; - cmdArgs: IORedisCommand['args']; + cmdName: string; + cmdArgs: CommandArgs; } export interface RedisRequestCustomAttributeFunction { @@ -59,12 +51,7 @@ export interface RedisRequestCustomAttributeFunction { * The type of the response varies depending on the specific command. */ export interface RedisResponseCustomAttributeFunction { - ( - span: Span, - cmdName: IORedisCommand['name'], - cmdArgs: IORedisCommand['args'], - response: unknown - ): void; + (span: Span, cmdName: string, cmdArgs: CommandArgs, response: unknown): void; } /** diff --git a/plugins/node/opentelemetry-instrumentation-ioredis/test/ioredis.test.ts b/plugins/node/opentelemetry-instrumentation-ioredis/test/ioredis.test.ts index 4c42264209..5df678ea4d 100644 --- a/plugins/node/opentelemetry-instrumentation-ioredis/test/ioredis.test.ts +++ b/plugins/node/opentelemetry-instrumentation-ioredis/test/ioredis.test.ts @@ -81,7 +81,7 @@ const sanitizeEventForAssertion = (span: ReadableSpan) => { describe('ioredis', () => { const provider = new NodeTracerProvider(); - let ioredis: typeof ioredisTypes; + let ioredis: typeof ioredisTypes.default; let instrumentation: IORedisInstrumentation; const shouldTestLocal = process.env.RUN_REDIS_TESTS_LOCAL; const shouldTest = process.env.RUN_REDIS_TESTS || shouldTestLocal; @@ -188,14 +188,14 @@ describe('ioredis', () => { name: string; args: Array; expectedDbStatement: string; - method: (cb: ioredisTypes.CallbackFunction) => unknown; + method: (cb: ioredisTypes.Callback) => unknown; }> = [ { description: 'insert', name: 'hset', args: [hashKeyName, 'testField', 'testValue'], expectedDbStatement: `${hashKeyName} testField [1 other arguments]`, - method: (cb: ioredisTypes.CallbackFunction) => + method: (cb: ioredisTypes.Callback) => client.hset(hashKeyName, 'testField', 'testValue', cb), }, { @@ -203,7 +203,7 @@ describe('ioredis', () => { name: 'get', args: [testKeyName], expectedDbStatement: `${testKeyName}`, - method: (cb: ioredisTypes.CallbackFunction) => + method: (cb: ioredisTypes.Callback) => client.get(testKeyName, cb), }, ]; @@ -960,7 +960,7 @@ describe('ioredis', () => { describe('setConfig - custom dbStatementSerializer config', () => { const dbStatementSerializer = ( cmdName: string, - cmdArgs: Array + cmdArgs: Array ) => { return Array.isArray(cmdArgs) && cmdArgs.length ? `FooBar_${cmdName} ${cmdArgs.join(',')}`