Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dev-packages/node-integration-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
"http-terminator": "^3.2.0",
"ioredis": "5.10.1",
"ioredis-5": "npm:ioredis@^5.11.0",
"ioredis-6": "npm:ioredis@^6.0.0",
"kafkajs": "2.2.4",
"knex": "^2.5.1",
"koa": "^2.15.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ async function run() {

await Sentry.startSpan(
{
name: 'Test Span IORedis 5.11 DC',
op: 'test-span-ioredis-5-11-dc',
name: 'Test Span IORedis DC',
op: 'test-span-ioredis-dc',
},
async () => {
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import * as Sentry from '@sentry/node';

async function run() {
const { default: Redis } = await import('ioredis-6');
const redisClient = new Redis({ host: '127.0.0.1', port: 6382, lazyConnect: true });

await redisClient.connect();

await Sentry.startSpan(
{
name: 'Test Span IORedis DC',
op: 'test-span-ioredis-dc',
},
async () => {
try {
await redisClient.set('dc-test-key', 'test-value');
await redisClient.set('dc-cache:test-key', 'test-value');

await redisClient.set('dc-cache:test-key-ex', 'test-value', 'EX', 10);

await redisClient.get('dc-test-key');
await redisClient.get('dc-cache:test-key');
await redisClient.get('dc-cache:unavailable-data');

await redisClient.mget('dc-test-key', 'dc-cache:test-key', 'dc-cache:unavailable-data');
} finally {
await redisClient.disconnect();
}
},
);
}

run();
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ import { EXPECTED_SDK_NAME } from '../../../utils';
import { cleanupChildProcesses, createEsmAndCjsTests, describeWithDockerCompose } from '../../../utils/runner';

describeWithDockerCompose(
'ioredis v5.11 diagnostics_channel auto instrumentation',
'ioredis >=5.11 diagnostics_channel auto instrumentation',
{ workingDirectory: [__dirname] },
() => {
afterAll(() => {
cleanupChildProcesses();
});

const ORIGIN = 'auto.db.redis.diagnostic_channel';
const SEGMENT_NAME = 'Test Span IORedis 5.11 DC';
const SEGMENT_NAME = 'Test Span IORedis DC';
const HOST = '127.0.0.1';
const PORT = 6382;

Expand Down Expand Up @@ -89,69 +89,77 @@ describeWithDockerCompose(
attributes: Record<string, unknown>,
): unknown => streamedSpan(op, op, { ...PEER, [CACHE_OPERATION]: op.slice('cache.'.length), ...attributes });

createEsmAndCjsTests(__dirname, 'scenario-ioredis-5-11.mjs', 'instrument.mjs', (createTestRunner, test) => {
test('creates spans for ioredis v5.11 commands via diagnostics_channel', { timeout: 75_000 }, async () => {
await createTestRunner()
.expect({
span: container => {
// The connect span opens its own segment but shares the trace with the test span,
// so both segments arrive in the same container.
expect(container.items.filter(item => item.is_segment).map(item => item.name)).toEqual([
'redis-connect',
SEGMENT_NAME,
]);
const clients = [
{ label: 'v5.11', scenario: 'scenario-ioredis-5-11.mjs' },
// v6 defaults to RESP3 and adds a `hello` handshake; the channel payload is unchanged.
{ label: 'v6', scenario: 'scenario-ioredis-6.mjs' },
];

// ioredis' own handshake commands (`client SETINFO`, `info`) are emitted on the
// channel too, but belong to the connect segment — the test span's children are the
// commands the scenario issues.
const spans = container.items.filter(
item => !item.is_segment && item.attributes[SENTRY_SEGMENT_NAME]?.value === SEGMENT_NAME,
);
for (const { label, scenario } of clients) {
createEsmAndCjsTests(__dirname, scenario, 'instrument.mjs', (createTestRunner, test) => {
test(`creates spans for ioredis ${label} commands via diagnostics_channel`, { timeout: 75_000 }, async () => {
await createTestRunner()
.expect({
span: container => {
// The connect span opens its own segment but shares the trace with the test span,
// so both segments arrive in the same container.
expect(container.items.filter(item => item.is_segment).map(item => item.name)).toEqual([
'redis-connect',
SEGMENT_NAME,
]);

expect(spans).toEqual([
streamedSpan(`set ${HOST}:${PORT}`, DB_QUERY, {
[DB_OPERATION_NAME]: 'set',
[DB_QUERY_TEXT]: 'set dc-test-key ?',
}),
cacheSpan(CACHE_PUT, {
[DB_OPERATION_NAME]: 'set',
[DB_QUERY_TEXT]: 'set dc-cache:test-key ?',
[CACHE_KEY]: ['dc-cache:test-key'],
[CACHE_ITEM_SIZE]: 2,
}),
cacheSpan(CACHE_PUT, {
[DB_OPERATION_NAME]: 'set',
[DB_QUERY_TEXT]: 'set dc-cache:test-key-ex ? ? ?',
[CACHE_KEY]: ['dc-cache:test-key-ex'],
[CACHE_ITEM_SIZE]: 2,
}),
streamedSpan(`get ${HOST}:${PORT}`, DB_QUERY, {
[DB_OPERATION_NAME]: 'get',
[DB_QUERY_TEXT]: 'get dc-test-key',
}),
cacheSpan(CACHE_GET, {
[DB_OPERATION_NAME]: 'get',
[DB_QUERY_TEXT]: 'get dc-cache:test-key',
[CACHE_KEY]: ['dc-cache:test-key'],
[CACHE_HIT]: true,
[CACHE_ITEM_SIZE]: 10,
}),
cacheSpan(CACHE_GET, {
[DB_OPERATION_NAME]: 'get',
[DB_QUERY_TEXT]: 'get dc-cache:unavailable-data',
[CACHE_KEY]: ['dc-cache:unavailable-data'],
[CACHE_HIT]: false,
}),
streamedSpan(`mget ${HOST}:${PORT}`, DB_QUERY, {
[DB_OPERATION_NAME]: 'mget',
[DB_QUERY_TEXT]: 'mget ? ? ?',
}),
]);
},
})
.start()
.completed();
// ioredis' own handshake commands (`client SETINFO`, `info`) are emitted on the
// channel too, but belong to the connect segment — the test span's children are the
// commands the scenario issues.
const spans = container.items.filter(
item => !item.is_segment && item.attributes[SENTRY_SEGMENT_NAME]?.value === SEGMENT_NAME,
);

expect(spans).toEqual([
streamedSpan(`set ${HOST}:${PORT}`, DB_QUERY, {
[DB_OPERATION_NAME]: 'set',
[DB_QUERY_TEXT]: 'set dc-test-key ?',
}),
cacheSpan(CACHE_PUT, {
[DB_OPERATION_NAME]: 'set',
[DB_QUERY_TEXT]: 'set dc-cache:test-key ?',
[CACHE_KEY]: ['dc-cache:test-key'],
[CACHE_ITEM_SIZE]: 2,
}),
cacheSpan(CACHE_PUT, {
[DB_OPERATION_NAME]: 'set',
[DB_QUERY_TEXT]: 'set dc-cache:test-key-ex ? ? ?',
[CACHE_KEY]: ['dc-cache:test-key-ex'],
[CACHE_ITEM_SIZE]: 2,
}),
streamedSpan(`get ${HOST}:${PORT}`, DB_QUERY, {
[DB_OPERATION_NAME]: 'get',
[DB_QUERY_TEXT]: 'get dc-test-key',
}),
cacheSpan(CACHE_GET, {
[DB_OPERATION_NAME]: 'get',
[DB_QUERY_TEXT]: 'get dc-cache:test-key',
[CACHE_KEY]: ['dc-cache:test-key'],
[CACHE_HIT]: true,
[CACHE_ITEM_SIZE]: 10,
}),
cacheSpan(CACHE_GET, {
[DB_OPERATION_NAME]: 'get',
[DB_QUERY_TEXT]: 'get dc-cache:unavailable-data',
[CACHE_KEY]: ['dc-cache:unavailable-data'],
[CACHE_HIT]: false,
}),
streamedSpan(`mget ${HOST}:${PORT}`, DB_QUERY, {
[DB_OPERATION_NAME]: 'mget',
[DB_QUERY_TEXT]: 'mget ? ? ?',
}),
]);
},
})
.start()
.completed();
});
});
});
}
},
);
17 changes: 17 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5334,6 +5334,11 @@
resolved "https://registry.yarnpkg.com/@ioredis/commands/-/commands-1.5.1.tgz#a0a3449993b10c7aeb91ecb0d5f1a23692297e51"
integrity sha512-JH8ZL/ywcJyR9MmJ5BNqZllXNZQqQbnVZOqpPQqE1vHiFgAw4NHbvE0FOduNU8IX9babitBT46571OnPTT0Zcw==

"@ioredis/commands@2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@ioredis/commands/-/commands-2.0.0.tgz#7207c56e0be51fd9f2ec2505ebdb9372a3ceb76d"
integrity sha512-vrx0AE/T0h7cRZwfo1M39Cr+ZhZrkf0V8mQN75wucKCxCLD9l/VX6no3gFvrLqD1IlG/1LtzWovqEw3t0Vr9zg==

"@isaacs/cliui@^8.0.2":
version "8.0.2"
resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550"
Expand Down Expand Up @@ -17637,6 +17642,18 @@ invariant@^2.2.1, invariant@^2.2.2:
redis-parser "3.0.0"
standard-as-callback "2.1.0"

"ioredis-6@npm:ioredis@^6.0.0":
version "6.0.0"
resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-6.0.0.tgz#b757c590547c43a5e18ea9c312d05c5c46c7e6fa"
integrity sha512-f+Dtubxfpf6KYFq7WVXJoOLn0bk4TJrMrN9SzeE+jrWrCWj7XX3fA6vkryafhADX+GMymRxgDJDOI33COkJc0w==
dependencies:
"@ioredis/commands" "2.0.0"
cluster-key-slot "1.1.1"
debug "4.4.3"
denque "2.1.0"
redis-errors "1.2.0"
standard-as-callback "2.1.0"

ioredis@5.10.1, ioredis@^5.10.1:
version "5.10.1"
resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-5.10.1.tgz#6082781d8aec8d51ee4936bf81d0610404db1e3d"
Expand Down
Loading