Skip to content

Commit ff68407

Browse files
author
Naseem
authored
Merge pull request #372 from blumamir/ioredis-require-parent-span
feat(instrumentation-ioredis): add requireParentSpan option to config
2 parents e3c1359 + 310e21a commit ff68407

File tree

5 files changed

+63
-4
lines changed

5 files changed

+63
-4
lines changed

plugins/node/opentelemetry-instrumentation-ioredis/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ IORedis instrumentation has few options available to choose from. You can set th
5757
| ------- | ---- | ----------- |
5858
| `dbStatementSerializer` | `DbStatementSerializer` | IORedis instrumentation will serialize db.statement using the specified function. |
5959
| `responseHook` | `RedisResponseCustomAttributeFunction` | Function for adding custom attributes on db response |
60+
| `requireParentSpan` | `boolean` | Require parent to create ioredis span, default when unset is true |
6061

6162
#### Custom db.statement Serializer
6263
The instrumentation serializes the whole command into a Span attribute called `db.statement`. The standard serialization format is `{cmdName} {cmdArgs.join(',')}`.

plugins/node/opentelemetry-instrumentation-ioredis/src/ioredis.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,22 @@ import { IORedisInstrumentationConfig } from './types';
2525
import { traceConnection, traceSendCommand } from './utils';
2626
import { VERSION } from './version';
2727

28+
const DEFAULT_CONFIG: IORedisInstrumentationConfig = {
29+
requireParentSpan: true,
30+
};
31+
2832
export class IORedisInstrumentation extends InstrumentationBase<
2933
typeof ioredisTypes
3034
> {
3135
static readonly DB_SYSTEM = 'redis';
3236
readonly supportedVersions = ['>1 <5'];
3337

34-
constructor(protected _config: IORedisInstrumentationConfig = {}) {
35-
super('@opentelemetry/instrumentation-ioredis', VERSION, _config);
38+
constructor(_config: IORedisInstrumentationConfig = {}) {
39+
super(
40+
'@opentelemetry/instrumentation-ioredis',
41+
VERSION,
42+
Object.assign({}, DEFAULT_CONFIG, _config)
43+
);
3644
}
3745

3846
init(): InstrumentationNodeModuleDefinition<typeof ioredisTypes>[] {

plugins/node/opentelemetry-instrumentation-ioredis/src/types.ts

+3
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,7 @@ export interface IORedisInstrumentationConfig extends InstrumentationConfig {
6868

6969
/** Function for adding custom attributes on db response */
7070
responseHook?: RedisResponseCustomAttributeFunction;
71+
72+
/** Require parent to create ioredis span, default when unset is true */
73+
requireParentSpan?: boolean;
7174
}

plugins/node/opentelemetry-instrumentation-ioredis/src/utils.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,9 @@ export const traceSendCommand = (
9393
if (arguments.length < 1 || typeof cmd !== 'object') {
9494
return original.apply(this, arguments);
9595
}
96-
// Do not trace if there is not parent span
97-
if (getSpan(context.active()) === undefined) {
96+
97+
const hasNoParentSpan = getSpan(context.active()) === undefined;
98+
if (config?.requireParentSpan === true && hasNoParentSpan) {
9899
return original.apply(this, arguments);
99100
}
100101

plugins/node/opentelemetry-instrumentation-ioredis/test/ioredis.test.ts

+46
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,52 @@ describe('ioredis', () => {
627627
});
628628
});
629629

630+
describe('Instrumentation with requireParentSpan', () => {
631+
it('should instrument with requireParentSpan equal false', async () => {
632+
instrumentation.disable();
633+
const config: IORedisInstrumentationConfig = {
634+
requireParentSpan: false,
635+
};
636+
instrumentation = new IORedisInstrumentation(config);
637+
instrumentation.setTracerProvider(provider);
638+
require('ioredis');
639+
640+
await client.set(testKeyName, 'data');
641+
const result = await client.del(testKeyName);
642+
assert.strictEqual(result, 1);
643+
644+
const endedSpans = memoryExporter.getFinishedSpans();
645+
assert.strictEqual(endedSpans.length, 2);
646+
647+
testUtils.assertSpan(
648+
endedSpans[0],
649+
SpanKind.CLIENT,
650+
{
651+
...DEFAULT_ATTRIBUTES,
652+
[DatabaseAttribute.DB_STATEMENT]: `set ${testKeyName} data`,
653+
},
654+
[],
655+
unsetStatus
656+
);
657+
});
658+
659+
it('should not instrument with requireParentSpan equal true', async () => {
660+
instrumentation.disable();
661+
const config: IORedisInstrumentationConfig = {
662+
requireParentSpan: true,
663+
};
664+
instrumentation = new IORedisInstrumentation(config);
665+
instrumentation.setTracerProvider(provider);
666+
require('ioredis');
667+
668+
await client.set(testKeyName, 'data');
669+
const result = await client.del(testKeyName);
670+
assert.strictEqual(result, 1);
671+
672+
assert.strictEqual(memoryExporter.getFinishedSpans().length, 0);
673+
});
674+
});
675+
630676
describe('Instrumenting with a custom db.statement serializer', () => {
631677
const dbStatementSerializer: DbStatementSerializer = (cmdName, cmdArgs) =>
632678
`FOOBAR_${cmdName}: ${cmdArgs[0]}`;

0 commit comments

Comments
 (0)