Skip to content

Commit

Permalink
Merge pull request #372 from blumamir/ioredis-require-parent-span
Browse files Browse the repository at this point in the history
feat(instrumentation-ioredis): add requireParentSpan option to config
  • Loading branch information
Naseem authored Mar 4, 2021
2 parents e3c1359 + 310e21a commit ff68407
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ IORedis instrumentation has few options available to choose from. You can set th
| ------- | ---- | ----------- |
| `dbStatementSerializer` | `DbStatementSerializer` | IORedis instrumentation will serialize db.statement using the specified function. |
| `responseHook` | `RedisResponseCustomAttributeFunction` | Function for adding custom attributes on db response |
| `requireParentSpan` | `boolean` | Require parent to create ioredis span, default when unset is true |

#### Custom db.statement Serializer
The instrumentation serializes the whole command into a Span attribute called `db.statement`. The standard serialization format is `{cmdName} {cmdArgs.join(',')}`.
Expand Down
12 changes: 10 additions & 2 deletions plugins/node/opentelemetry-instrumentation-ioredis/src/ioredis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,22 @@ import { IORedisInstrumentationConfig } from './types';
import { traceConnection, traceSendCommand } from './utils';
import { VERSION } from './version';

const DEFAULT_CONFIG: IORedisInstrumentationConfig = {
requireParentSpan: true,
};

export class IORedisInstrumentation extends InstrumentationBase<
typeof ioredisTypes
> {
static readonly DB_SYSTEM = 'redis';
readonly supportedVersions = ['>1 <5'];

constructor(protected _config: IORedisInstrumentationConfig = {}) {
super('@opentelemetry/instrumentation-ioredis', VERSION, _config);
constructor(_config: IORedisInstrumentationConfig = {}) {
super(
'@opentelemetry/instrumentation-ioredis',
VERSION,
Object.assign({}, DEFAULT_CONFIG, _config)
);
}

init(): InstrumentationNodeModuleDefinition<typeof ioredisTypes>[] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,7 @@ export interface IORedisInstrumentationConfig extends InstrumentationConfig {

/** Function for adding custom attributes on db response */
responseHook?: RedisResponseCustomAttributeFunction;

/** Require parent to create ioredis span, default when unset is true */
requireParentSpan?: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,9 @@ export const traceSendCommand = (
if (arguments.length < 1 || typeof cmd !== 'object') {
return original.apply(this, arguments);
}
// Do not trace if there is not parent span
if (getSpan(context.active()) === undefined) {

const hasNoParentSpan = getSpan(context.active()) === undefined;
if (config?.requireParentSpan === true && hasNoParentSpan) {
return original.apply(this, arguments);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,52 @@ describe('ioredis', () => {
});
});

describe('Instrumentation with requireParentSpan', () => {
it('should instrument with requireParentSpan equal false', async () => {
instrumentation.disable();
const config: IORedisInstrumentationConfig = {
requireParentSpan: false,
};
instrumentation = new IORedisInstrumentation(config);
instrumentation.setTracerProvider(provider);
require('ioredis');

await client.set(testKeyName, 'data');
const result = await client.del(testKeyName);
assert.strictEqual(result, 1);

const endedSpans = memoryExporter.getFinishedSpans();
assert.strictEqual(endedSpans.length, 2);

testUtils.assertSpan(
endedSpans[0],
SpanKind.CLIENT,
{
...DEFAULT_ATTRIBUTES,
[DatabaseAttribute.DB_STATEMENT]: `set ${testKeyName} data`,
},
[],
unsetStatus
);
});

it('should not instrument with requireParentSpan equal true', async () => {
instrumentation.disable();
const config: IORedisInstrumentationConfig = {
requireParentSpan: true,
};
instrumentation = new IORedisInstrumentation(config);
instrumentation.setTracerProvider(provider);
require('ioredis');

await client.set(testKeyName, 'data');
const result = await client.del(testKeyName);
assert.strictEqual(result, 1);

assert.strictEqual(memoryExporter.getFinishedSpans().length, 0);
});
});

describe('Instrumenting with a custom db.statement serializer', () => {
const dbStatementSerializer: DbStatementSerializer = (cmdName, cmdArgs) =>
`FOOBAR_${cmdName}: ${cmdArgs[0]}`;
Expand Down

0 comments on commit ff68407

Please sign in to comment.