Skip to content

Commit cba2ba5

Browse files
msonnbclaude
andauthored
feat(server-utils): Add db span op for generic-pool acquire spans (#23213)
`generic-pool.acquire` spans carried an `auto.db.generic_pool` origin but no op. They now have the generic `db` op (rather than `db.query`, since pool acquisition is no query) part of #23138 Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 672cc41 commit cba2ba5

5 files changed

Lines changed: 34 additions & 39 deletions

File tree

  • dev-packages
    • deno-integration-tests/suites/orchestrion-generic-pool
    • e2e-tests/test-applications/nextjs-16-orchestrion/tests
    • node-integration-tests/suites/tracing
  • packages/server-utils/src/integrations/tracing-channel

dev-packages/deno-integration-tests/suites/orchestrion-generic-pool/test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ Deno.test('generic-pool instrumentation: orchestrion:generic-pool:acquire channe
4545
"'parent' transaction",
4646
);
4747

48-
// generic-pool sets a name + origin but no `op`, so match on description.
4948
const poolSpan = parent.spans?.find(s => s.description === 'generic-pool.acquire');
5049
assertExists(
5150
poolSpan,
5251
`expected a generic-pool.acquire span, got descriptions: ${parent.spans?.map(s => s.description).join(', ')}`,
5352
);
5453
assertEquals(poolSpan!.data?.['sentry.origin'], 'auto.db.generic_pool');
54+
assertEquals(poolSpan!.op, 'db');
5555
});

dev-packages/e2e-tests/test-applications/nextjs-16-orchestrion/tests/generic-pool.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ test('Instruments generic-pool automatically via orchestrion', async ({ baseURL
1717
expect(spans).toContainEqual(
1818
expect.objectContaining({
1919
description: 'generic-pool.acquire',
20+
op: 'db',
2021
origin: 'auto.db.generic_pool',
2122
status: 'ok',
2223
data: expect.objectContaining({

dev-packages/node-integration-tests/suites/tracing/genericPool-v2/test.ts

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
import { afterAll, describe, expect } from 'vitest';
2-
import { isOrchestrionEnabled } from '../../../utils';
32
import { cleanupChildProcesses, createEsmAndCjsTests } from '../../../utils/runner';
43

54
describe('genericPool v2 auto instrumentation', () => {
65
afterAll(() => {
76
cleanupChildProcesses();
87
});
98

10-
// The orchestrion channel integration replaces the OTel one 1:1 but tags spans with its own origin.
11-
const ORIGIN = isOrchestrionEnabled() ? 'auto.db.generic_pool' : 'auto.db.otel.generic_pool';
12-
139
createEsmAndCjsTests(
1410
__dirname,
1511
'scenario.mjs',
@@ -21,19 +17,21 @@ describe('genericPool v2 auto instrumentation', () => {
2117
spans: expect.arrayContaining([
2218
expect.objectContaining({
2319
description: 'generic-pool.acquire',
24-
origin: ORIGIN,
25-
data: {
26-
'sentry.origin': ORIGIN,
27-
},
20+
op: 'db',
21+
origin: 'auto.db.generic_pool',
22+
data: expect.objectContaining({
23+
'sentry.origin': 'auto.db.generic_pool',
24+
}),
2825
status: 'ok',
2926
}),
3027

3128
expect.objectContaining({
3229
description: 'generic-pool.acquire',
33-
origin: ORIGIN,
34-
data: {
35-
'sentry.origin': ORIGIN,
36-
},
30+
op: 'db',
31+
origin: 'auto.db.generic_pool',
32+
data: expect.objectContaining({
33+
'sentry.origin': 'auto.db.generic_pool',
34+
}),
3735
status: 'ok',
3836
}),
3937
]),
@@ -51,18 +49,14 @@ describe('genericPool v2 auto instrumentation', () => {
5149
'instrument.mjs',
5250
(createRunner, test) => {
5351
test('marks the `generic-pool.acquire` span as errored when acquiring fails', async () => {
54-
// The orchestrion path also records the rejection's `error.type` on the span.
55-
const errorData = isOrchestrionEnabled()
56-
? { 'sentry.origin': ORIGIN, 'error.type': 'Error' }
57-
: { 'sentry.origin': ORIGIN };
58-
5952
const EXPECTED_TRANSACTION = {
6053
transaction: 'Test Transaction',
6154
spans: expect.arrayContaining([
6255
expect.objectContaining({
6356
description: 'generic-pool.acquire',
64-
origin: ORIGIN,
65-
data: errorData,
57+
op: 'db',
58+
origin: 'auto.db.generic_pool',
59+
data: expect.objectContaining({ 'sentry.origin': 'auto.db.generic_pool', 'error.type': 'Error' }),
6660
status: 'internal_error',
6761
}),
6862
]),

dev-packages/node-integration-tests/suites/tracing/genericPool/test.ts

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,33 @@
11
import { afterAll, describe, expect } from 'vitest';
2-
import { isOrchestrionEnabled } from '../../../utils';
32
import { cleanupChildProcesses, createEsmAndCjsTests } from '../../../utils/runner';
43

54
describe('genericPool auto instrumentation', () => {
65
afterAll(() => {
76
cleanupChildProcesses();
87
});
98

10-
// The orchestrion channel integration replaces the OTel one 1:1 but tags spans with its own origin.
11-
const ORIGIN = isOrchestrionEnabled() ? 'auto.db.generic_pool' : 'auto.db.otel.generic_pool';
12-
139
createEsmAndCjsTests(__dirname, 'scenario.mjs', 'instrument.mjs', (createRunner, test) => {
1410
test('should auto-instrument `genericPool` package when calling pool.require()', async () => {
1511
const EXPECTED_TRANSACTION = {
1612
transaction: 'Test Transaction',
1713
spans: expect.arrayContaining([
1814
expect.objectContaining({
1915
description: 'generic-pool.acquire',
20-
origin: ORIGIN,
21-
data: {
22-
'sentry.origin': ORIGIN,
23-
},
16+
op: 'db',
17+
origin: 'auto.db.generic_pool',
18+
data: expect.objectContaining({
19+
'sentry.origin': 'auto.db.generic_pool',
20+
}),
2421
status: 'ok',
2522
}),
2623

2724
expect.objectContaining({
2825
description: 'generic-pool.acquire',
29-
origin: ORIGIN,
30-
data: {
31-
'sentry.origin': ORIGIN,
32-
},
26+
op: 'db',
27+
origin: 'auto.db.generic_pool',
28+
data: expect.objectContaining({
29+
'sentry.origin': 'auto.db.generic_pool',
30+
}),
3331
status: 'ok',
3432
}),
3533
]),
@@ -41,18 +39,17 @@ describe('genericPool auto instrumentation', () => {
4139

4240
createEsmAndCjsTests(__dirname, 'scenario-error.mjs', 'instrument.mjs', (createRunner, test) => {
4341
test('marks the `generic-pool.acquire` span as errored when acquiring fails', async () => {
44-
// The orchestrion path also records the rejection's `error.type` on the span.
45-
const errorData = isOrchestrionEnabled()
46-
? { 'sentry.origin': ORIGIN, 'error.type': 'TimeoutError' }
47-
: { 'sentry.origin': ORIGIN };
48-
4942
const EXPECTED_TRANSACTION = {
5043
transaction: 'Test Transaction',
5144
spans: expect.arrayContaining([
5245
expect.objectContaining({
5346
description: 'generic-pool.acquire',
54-
origin: ORIGIN,
55-
data: errorData,
47+
op: 'db',
48+
origin: 'auto.db.generic_pool',
49+
data: expect.objectContaining({
50+
'sentry.origin': 'auto.db.generic_pool',
51+
'error.type': 'TimeoutError',
52+
}),
5653
status: 'internal_error',
5754
}),
5855
]),

packages/server-utils/src/integrations/tracing-channel/generic-pool.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import * as diagnosticsChannel from 'node:diagnostics_channel';
2+
import { SENTRY_OP } from '@sentry/conventions/attributes';
3+
import { DATABASE_DB_SPAN_OP } from '@sentry/conventions/op';
24
import type { IntegrationFn } from '@sentry/core';
35
import { defineIntegration, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startInactiveSpan } from '@sentry/core';
46
import { CHANNELS } from '../../orchestrion/channels';
@@ -38,6 +40,7 @@ function instrumentGenericPool(): void {
3840
startInactiveSpan({
3941
name: 'generic-pool.acquire',
4042
attributes: {
43+
[SENTRY_OP]: DATABASE_DB_SPAN_OP,
4144
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.db.generic_pool',
4245
},
4346
}),

0 commit comments

Comments
 (0)