Skip to content

Commit d9b709f

Browse files
committed
feat(instrumentation-redis): support redis v5
1 parent e9987a7 commit d9b709f

File tree

12 files changed

+137
-226
lines changed

12 files changed

+137
-226
lines changed

packages/instrumentation-redis/.tav.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ redis:
44
mode: latest-minors
55
commands: npm run test-v2-v3
66
- versions:
7-
include: '>=4 <5'
7+
include: '>=4 <6'
88
# "4.6.9" was a bad release that accidentally broke node v14 support.
99
exclude: "4.6.9"
1010
mode: latest-minors
11-
commands: npm test
11+
commands: npm run test-v4-v5

packages/instrumentation-redis/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
},
1212
"scripts": {
1313
"test-v2-v3": "nyc mocha --require '@opentelemetry/contrib-test-utils' 'test/v2-v3/*.test.ts'",
14-
"test": "nyc mocha --require '@opentelemetry/contrib-test-utils' 'test/v4/*.test.ts'",
14+
"test-v4-v5": "nyc mocha --require '@opentelemetry/contrib-test-utils' 'test/v4-v5/*.test.ts'",
1515
"test:debug": "cross-env RUN_REDIS_TESTS_LOCAL=true mocha --inspect-brk --no-timeouts 'test/**/*.test.ts'",
1616
"test:local": "cross-env RUN_REDIS_TESTS_LOCAL=true npm run test",
1717
"test:docker:run": "docker run --rm -d --name otel-redis -p 63790:6379 redis:alpine",

packages/instrumentation-redis/src/redis.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { RedisInstrumentationConfig } from './types';
1919
import { PACKAGE_NAME, PACKAGE_VERSION } from './version';
2020
import { RedisInstrumentationV2_V3 } from './v2-v3/instrumentation';
2121
import { TracerProvider } from '@opentelemetry/api';
22-
import { RedisInstrumentationV4 } from './v4/instrumentation';
22+
import { RedisInstrumentationV4_V5 } from './v4-v5/instrumentation';
2323

2424
const DEFAULT_CONFIG: RedisInstrumentationConfig = {
2525
requireParentSpan: false,
@@ -28,7 +28,7 @@ const DEFAULT_CONFIG: RedisInstrumentationConfig = {
2828
// Wrapper RedisInstrumentation that address all supported versions
2929
export class RedisInstrumentation extends InstrumentationBase<RedisInstrumentationConfig> {
3030
private instrumentationV2_V3: RedisInstrumentationV2_V3;
31-
private instrumentationV4: RedisInstrumentationV4;
31+
private instrumentationV4_V5: RedisInstrumentationV4_V5;
3232

3333
// this is used to bypass a flaw in the base class constructor, which is calling
3434
// member functions before the constructor has a chance to fully initialize the member variables.
@@ -39,7 +39,7 @@ export class RedisInstrumentation extends InstrumentationBase<RedisInstrumentati
3939
super(PACKAGE_NAME, PACKAGE_VERSION, resolvedConfig);
4040

4141
this.instrumentationV2_V3 = new RedisInstrumentationV2_V3(this.getConfig());
42-
this.instrumentationV4 = new RedisInstrumentationV4(this.getConfig());
42+
this.instrumentationV4_V5 = new RedisInstrumentationV4_V5(this.getConfig());
4343
this.initialized = true;
4444
}
4545

@@ -51,7 +51,7 @@ export class RedisInstrumentation extends InstrumentationBase<RedisInstrumentati
5151
}
5252

5353
this.instrumentationV2_V3.setConfig(newConfig);
54-
this.instrumentationV4.setConfig(newConfig);
54+
this.instrumentationV4_V5.setConfig(newConfig);
5555
}
5656

5757
override init() {}
@@ -62,7 +62,7 @@ export class RedisInstrumentation extends InstrumentationBase<RedisInstrumentati
6262
return;
6363
}
6464
this.instrumentationV2_V3.setTracerProvider(tracerProvider);
65-
this.instrumentationV4.setTracerProvider(tracerProvider);
65+
this.instrumentationV4_V5.setTracerProvider(tracerProvider);
6666
}
6767

6868
override enable() {
@@ -71,7 +71,7 @@ export class RedisInstrumentation extends InstrumentationBase<RedisInstrumentati
7171
return;
7272
}
7373
this.instrumentationV2_V3.enable();
74-
this.instrumentationV4.enable();
74+
this.instrumentationV4_V5.enable();
7575
}
7676

7777
override disable() {
@@ -80,6 +80,6 @@ export class RedisInstrumentation extends InstrumentationBase<RedisInstrumentati
8080
return;
8181
}
8282
this.instrumentationV2_V3.disable();
83-
this.instrumentationV4.disable();
83+
this.instrumentationV4_V5.disable();
8484
}
8585
}

packages/instrumentation-redis/src/v2-v3/instrumentation.ts

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,11 @@ import { PACKAGE_NAME, PACKAGE_VERSION } from '../version';
3131
import type { RedisCommand, RedisPluginClientTypes } from './internal-types';
3232
import { SpanKind, context, trace } from '@opentelemetry/api';
3333
import {
34-
DBSYSTEMVALUES_REDIS,
35-
SEMATTRS_DB_CONNECTION_STRING,
36-
SEMATTRS_DB_STATEMENT,
37-
SEMATTRS_DB_SYSTEM,
38-
SEMATTRS_NET_PEER_NAME,
39-
SEMATTRS_NET_PEER_PORT,
34+
ATTR_DB_SYSTEM_NAME,
35+
ATTR_DB_QUERY_TEXT,
36+
ATTR_DB_OPERATION_NAME,
37+
ATTR_SERVER_ADDRESS,
38+
ATTR_SERVER_PORT,
4039
} from '@opentelemetry/semantic-conventions';
4140
import { defaultDbStatementSerializer } from '@opentelemetry/redis-common';
4241

@@ -132,8 +131,9 @@ export class RedisInstrumentationV2_V3 extends InstrumentationBase<RedisInstrume
132131
{
133132
kind: SpanKind.CLIENT,
134133
attributes: {
135-
[SEMATTRS_DB_SYSTEM]: DBSYSTEMVALUES_REDIS,
136-
[SEMATTRS_DB_STATEMENT]: dbStatementSerializer(
134+
[ATTR_DB_SYSTEM_NAME]: 'redis',
135+
[ATTR_DB_OPERATION_NAME]: cmd.command,
136+
[ATTR_DB_QUERY_TEXT]: dbStatementSerializer(
137137
cmd.command,
138138
cmd.args
139139
),
@@ -144,15 +144,16 @@ export class RedisInstrumentationV2_V3 extends InstrumentationBase<RedisInstrume
144144
// Set attributes for not explicitly typed RedisPluginClientTypes
145145
if (this.connection_options) {
146146
span.setAttributes({
147-
[SEMATTRS_NET_PEER_NAME]: this.connection_options.host,
148-
[SEMATTRS_NET_PEER_PORT]: this.connection_options.port,
147+
[ATTR_SERVER_ADDRESS]: this.connection_options.host,
148+
[ATTR_SERVER_PORT]: this.connection_options.port,
149149
});
150150
}
151151
if (this.address) {
152-
span.setAttribute(
153-
SEMATTRS_DB_CONNECTION_STRING,
154-
`redis://${this.address}`
155-
);
152+
// DB_CONNECTION_STRING is deprecated; Replaced by server.address and server.port.
153+
// span.setAttribute(
154+
// SEMATTRS_DB_CONNECTION_STRING,
155+
// `redis://${this.address}`
156+
// );
156157
}
157158

158159
const originalCallback = arguments[0].callback;

packages/instrumentation-redis/src/v4/instrumentation.ts renamed to packages/instrumentation-redis/src/v4-v5/instrumentation.ts

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ import { defaultDbStatementSerializer } from '@opentelemetry/redis-common';
3232
import { RedisInstrumentationConfig } from '../types';
3333
/** @knipignore */
3434
import { PACKAGE_NAME, PACKAGE_VERSION } from '../version';
35-
import { SEMATTRS_DB_STATEMENT } from '@opentelemetry/semantic-conventions';
35+
import {
36+
ATTR_DB_OPERATION_NAME,
37+
ATTR_DB_QUERY_TEXT,
38+
ATTR_DB_OPERATION_BATCH_SIZE,
39+
} from '@opentelemetry/semantic-conventions';
3640
import type { MultiErrorReply } from './internal-types';
3741

3842
const OTEL_OPEN_SPANS = Symbol(
@@ -48,7 +52,7 @@ interface MutliCommandInfo {
4852
commandArgs: Array<string | Buffer>;
4953
}
5054

51-
export class RedisInstrumentationV4 extends InstrumentationBase<RedisInstrumentationConfig> {
55+
export class RedisInstrumentationV4_V5 extends InstrumentationBase<RedisInstrumentationConfig> {
5256
static readonly COMPONENT = 'redis';
5357

5458
constructor(config: RedisInstrumentationConfig = {}) {
@@ -111,7 +115,7 @@ export class RedisInstrumentationV4 extends InstrumentationBase<RedisInstrumenta
111115

112116
const multiCommanderModule = new InstrumentationNodeModuleFile(
113117
`${basePackageName}/dist/lib/client/multi-command.js`,
114-
['^1.0.0'],
118+
['^1.0.0', '^5.0.0'],
115119
(moduleExports: any) => {
116120
const redisClientMultiCommandPrototype =
117121
moduleExports?.default?.prototype;
@@ -150,7 +154,7 @@ export class RedisInstrumentationV4 extends InstrumentationBase<RedisInstrumenta
150154

151155
const clientIndexModule = new InstrumentationNodeModuleFile(
152156
`${basePackageName}/dist/lib/client/index.js`,
153-
['^1.0.0'],
157+
['^1.0.0', '^5.0.0'],
154158
(moduleExports: any) => {
155159
const redisClientPrototype = moduleExports?.default?.prototype;
156160

@@ -213,7 +217,7 @@ export class RedisInstrumentationV4 extends InstrumentationBase<RedisInstrumenta
213217

214218
return new InstrumentationNodeModuleDefinition(
215219
basePackageName,
216-
['^1.0.0'],
220+
['^1.0.0', '^5.0.0'],
217221
(moduleExports: any) => {
218222
return moduleExports;
219223
},
@@ -327,11 +331,10 @@ export class RedisInstrumentationV4 extends InstrumentationBase<RedisInstrumenta
327331
return function connectWrapper(original: Function) {
328332
return function patchedConnect(this: any): Promise<void> {
329333
const options = this.options;
330-
331-
const attributes = getClientAttributes(plugin._diag, options);
334+
const attributes = getClientAttributes(options);
332335

333336
const span = plugin.tracer.startSpan(
334-
`${RedisInstrumentationV4.COMPONENT}-connect`,
337+
`${RedisInstrumentationV4_V5.COMPONENT}-connect`,
335338
{
336339
kind: SpanKind.CLIENT,
337340
attributes,
@@ -379,12 +382,13 @@ export class RedisInstrumentationV4 extends InstrumentationBase<RedisInstrumenta
379382
const dbStatementSerializer =
380383
this.getConfig().dbStatementSerializer || defaultDbStatementSerializer;
381384

382-
const attributes = getClientAttributes(this._diag, clientOptions);
385+
const attributes = getClientAttributes(clientOptions);
383386

384387
try {
388+
attributes[ATTR_DB_OPERATION_NAME] = commandName;
385389
const dbStatement = dbStatementSerializer(commandName, commandArgs);
386390
if (dbStatement != null) {
387-
attributes[SEMATTRS_DB_STATEMENT] = dbStatement;
391+
attributes[ATTR_DB_QUERY_TEXT] = dbStatement;
388392
}
389393
} catch (e) {
390394
this._diag.error('dbStatementSerializer throw an exception', e, {
@@ -393,7 +397,7 @@ export class RedisInstrumentationV4 extends InstrumentationBase<RedisInstrumenta
393397
}
394398

395399
const span = this.tracer.startSpan(
396-
`${RedisInstrumentationV4.COMPONENT}-${commandName}`,
400+
`${RedisInstrumentationV4_V5.COMPONENT}-${commandName}`,
397401
{
398402
kind: SpanKind.CLIENT,
399403
attributes,
@@ -447,8 +451,12 @@ export class RedisInstrumentationV4 extends InstrumentationBase<RedisInstrumenta
447451
'number of multi command spans does not match response from redis'
448452
);
449453
}
454+
450455
for (let i = 0; i < openSpans.length; i++) {
451456
const { span, commandName, commandArgs } = openSpans[i];
457+
if (openSpans.length >= 2) {
458+
span.setAttribute(ATTR_DB_OPERATION_BATCH_SIZE, openSpans.length);
459+
}
452460
const currCommandRes = replies[i];
453461
const [res, err] =
454462
currCommandRes instanceof Error
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
import { Attributes } from '@opentelemetry/api';
17+
import {
18+
ATTR_DB_SYSTEM_NAME,
19+
ATTR_SERVER_ADDRESS,
20+
ATTR_SERVER_PORT,
21+
} from '@opentelemetry/semantic-conventions';
22+
23+
export function getClientAttributes(options: any): Attributes {
24+
const attrs: Attributes = {
25+
[ATTR_DB_SYSTEM_NAME]: 'redis',
26+
[ATTR_SERVER_ADDRESS]: options?.socket?.host,
27+
[ATTR_SERVER_PORT]: options?.socket?.port,
28+
};
29+
30+
return attrs;
31+
}

packages/instrumentation-redis/src/v4/utils.ts

Lines changed: 0 additions & 63 deletions
This file was deleted.

0 commit comments

Comments
 (0)