Skip to content

Commit 8f14dd3

Browse files
committed
[otel] rely on context for parenting spans correctly
1 parent 8c466f4 commit 8f14dd3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+978
-480
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@graphql-mesh/plugin-opentelemetry': patch
3+
---
4+
5+
dependencies updates:
6+
7+
- Added dependency [`@opentelemetry/context-async-hooks@^1.30.1` ↗︎](https://www.npmjs.com/package/@opentelemetry/context-async-hooks/v/1.30.1) (to `dependencies`)

e2e/opentelemetry/opentelemetry.e2e.ts

Lines changed: 81 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,18 @@ beforeAll(async () => {
2424
type JaegerTracesApiResponse = {
2525
data: Array<{
2626
traceID: string;
27-
spans: Array<{
28-
traceID: string;
29-
spanID: string;
30-
operationName: string;
31-
tags: Array<{ key: string; value: string; type: string }>;
32-
}>;
27+
spans: JaegerTraceSpan[];
3328
}>;
3429
};
3530

31+
type JaegerTraceSpan = {
32+
traceID: string;
33+
spanID: string;
34+
operationName: string;
35+
tags: Array<{ key: string; value: string; type: string }>;
36+
references: Array<{ refType: string; spanID: string; traceID: string }>;
37+
};
38+
3639
describe('OpenTelemetry', () => {
3740
(['grpc', 'http'] as const).forEach((OTLP_EXPORTER_TYPE) => {
3841
describe(`exporter > ${OTLP_EXPORTER_TYPE}`, () => {
@@ -77,6 +80,9 @@ describe('OpenTelemetry', () => {
7780
await checkFn(res);
7881
return;
7982
} catch (e) {
83+
if (signal.aborted) {
84+
throw err;
85+
}
8086
err = e;
8187
}
8288
}
@@ -559,40 +565,52 @@ describe('OpenTelemetry', () => {
559565
expect(relevantTraces.length).toBe(1);
560566
const relevantTrace = relevantTraces[0];
561567
expect(relevantTrace).toBeDefined();
562-
expect(relevantTrace?.spans.length).toBe(11);
568+
expect(relevantTrace!.spans.length).toBe(18);
563569

564-
expect(relevantTrace?.spans).toContainEqual(
565-
expect.objectContaining({ operationName: 'POST /graphql' }),
566-
);
567-
expect(relevantTrace?.spans).toContainEqual(
568-
expect.objectContaining({ operationName: 'graphql.parse' }),
569-
);
570-
expect(relevantTrace?.spans).toContainEqual(
571-
expect.objectContaining({ operationName: 'graphql.validate' }),
572-
);
573-
expect(relevantTrace?.spans).toContainEqual(
574-
expect.objectContaining({ operationName: 'graphql.execute' }),
570+
const spanTree = buildSpanTree(relevantTrace!.spans, 'POST /graphql');
571+
expect(spanTree).toBeDefined();
572+
573+
const expectedHttpChildren = [
574+
'graphql.parse',
575+
'graphql.validate',
576+
'graphql.execute',
577+
];
578+
expect(spanTree!.children).toHaveLength(3);
579+
for (const operationName of expectedHttpChildren) {
580+
expect(spanTree?.children).toContainEqual(
581+
expect.objectContaining({
582+
span: expect.objectContaining({ operationName }),
583+
}),
584+
);
585+
}
586+
587+
const executeSpan = spanTree?.children.find(
588+
({ span }) => span.operationName === 'graphql.execute',
575589
);
576-
expect(
577-
relevantTrace?.spans.filter(
578-
(r) => r.operationName === 'subgraph.execute (accounts)',
579-
).length,
580-
).toBe(2);
581-
expect(
582-
relevantTrace?.spans.filter(
583-
(r) => r.operationName === 'subgraph.execute (products)',
584-
).length,
585-
).toBe(2);
586-
expect(
587-
relevantTrace?.spans.filter(
588-
(r) => r.operationName === 'subgraph.execute (inventory)',
589-
).length,
590-
).toBe(1);
591-
expect(
592-
relevantTrace?.spans.filter(
593-
(r) => r.operationName === 'subgraph.execute (reviews)',
594-
).length,
595-
).toBe(2);
590+
591+
const expectedExecuteChildren = [
592+
['subgraph.execute (accounts)', 2],
593+
['subgraph.execute (products)', 2],
594+
['subgraph.execute (inventory)', 1],
595+
['subgraph.execute (reviews)', 2],
596+
] as const;
597+
598+
for (const [operationName, count] of expectedExecuteChildren) {
599+
const matchingChildren = executeSpan!.children.filter(
600+
({ span }) => span.operationName === operationName,
601+
);
602+
expect(matchingChildren).toHaveLength(count);
603+
for (const child of matchingChildren) {
604+
expect(child.children).toHaveLength(1);
605+
expect(child.children).toContainEqual(
606+
expect.objectContaining({
607+
span: expect.objectContaining({
608+
operationName: 'http.fetch',
609+
}),
610+
}),
611+
);
612+
}
613+
}
596614
});
597615
});
598616

@@ -1279,3 +1297,28 @@ describe('OpenTelemetry', () => {
12791297
});
12801298
});
12811299
});
1300+
1301+
type TraceTreeNode = {
1302+
span: JaegerTraceSpan;
1303+
children: TraceTreeNode[];
1304+
};
1305+
function buildSpanTree(
1306+
spans: JaegerTraceSpan[],
1307+
rootName: string,
1308+
): TraceTreeNode | undefined {
1309+
function buildNode(root: JaegerTraceSpan): TraceTreeNode {
1310+
return {
1311+
span: root,
1312+
children: spans
1313+
.filter((span) =>
1314+
span.references.find(
1315+
(ref) => ref.refType === 'CHILD_OF' && ref.spanID === root.spanID,
1316+
),
1317+
)
1318+
.map(buildNode),
1319+
};
1320+
}
1321+
1322+
const root = spans.find((span) => span.operationName === rootName);
1323+
return root && buildNode(root);
1324+
}

examples/apq-subgraphs/example.tar.gz

0 Bytes
Binary file not shown.

examples/apq-subgraphs/package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/apq-subgraphs/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"@graphql-mesh/compose-cli": "^1.2.13",
1010
"graphql": "^16.9.0",
1111
"tslib": "^2.8.1",
12-
"@graphql-hive/gateway": "^1.9.0"
12+
"@graphql-hive/gateway": "^1.9.1"
1313
},
1414
"scripts": {
1515
"service:greetings": "tsx services/greetings.ts",

examples/extra-fields/example.tar.gz

-1 Bytes
Binary file not shown.

examples/extra-fields/package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/extra-fields/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"graphql": "^16.9.0",
77
"graphql-yoga": "^5.10.11",
88
"tslib": "^2.8.1",
9-
"@graphql-hive/gateway": "^1.9.0"
9+
"@graphql-hive/gateway": "^1.9.1"
1010
},
1111
"devDependencies": {
1212
"tsx": "^4.19.2"
1 Byte
Binary file not shown.

examples/federation-example/package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/federation-example/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"@apollo/server": "^4.10.3",
1010
"@apollo/subgraph": "^2.7.2",
1111
"graphql": "^16.9.0",
12-
"@graphql-hive/gateway": "^1.9.0"
12+
"@graphql-hive/gateway": "^1.9.1"
1313
},
1414
"scripts": {
1515
"service:accounts": "tsx services/accounts/index.ts",
0 Bytes
Binary file not shown.

examples/federation-mixed/package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/federation-mixed/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"@apollo/server": "^4.10.3",
1010
"@apollo/subgraph": "^2.7.2",
1111
"fets": "^0.8.4",
12-
"@graphql-hive/gateway": "^1.9.0"
12+
"@graphql-hive/gateway": "^1.9.1"
1313
},
1414
"devDependencies": {
1515
"tsx": "^4.19.2",
Binary file not shown.

examples/federation-subscriptions-passthrough/package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/federation-subscriptions-passthrough/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"graphql-sse": "^2.5.3",
1616
"graphql-ws": "^5.16.0",
1717
"ws": "^8.17.1",
18-
"@graphql-hive/gateway": "^1.9.0"
18+
"@graphql-hive/gateway": "^1.9.1"
1919
},
2020
"devDependencies": {
2121
"tsx": "^4.19.2",

examples/file-upload/example.tar.gz

0 Bytes
Binary file not shown.

examples/file-upload/package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/file-upload/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"@graphql-mesh/compose-cli": "^1.2.13",
66
"graphql": "^16.9.0",
77
"tslib": "^2.8.1",
8-
"@graphql-hive/gateway": "^1.9.0"
8+
"@graphql-hive/gateway": "^1.9.1"
99
},
1010
"devDependencies": {
1111
"tsx": "^4.19.2"
2 Bytes
Binary file not shown.

examples/hmac-auth-https/package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/hmac-auth-https/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"dependencies": {
1313
"@apollo/server": "^4.10.3",
1414
"@apollo/subgraph": "^2.9.3",
15-
"@graphql-hive/gateway": "^1.9.0",
15+
"@graphql-hive/gateway": "^1.9.1",
1616
"@graphql-mesh/compose-cli": "^1.3.3",
1717
"@graphql-mesh/hmac-upstream-signature": "^1.2.19",
1818
"@graphql-mesh/plugin-jwt-auth": "^1.4.0",
Binary file not shown.

examples/interface-additional-resolvers/package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)