Skip to content

Commit 5090d2a

Browse files
committed
Add opentelemetry tracing support
1 parent 3b2bd67 commit 5090d2a

File tree

4 files changed

+51
-24
lines changed

4 files changed

+51
-24
lines changed

.changeset/funny-spoons-lick.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@labdigital/graphql-fetcher": minor
3+
---
4+
5+
Add opentelemetry support for server fetcher

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
"peerDependencies": {
6666
"graphql": ">= 16.6.0",
6767
"react": ">= 18.0.0",
68-
"react-dom": ">= 18.2.0"
68+
"react-dom": ">= 18.2.0",
69+
"@opentelemetry/api": ">= 1.7.0"
6970
}
7071
}

pnpm-lock.yaml

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

src/server.ts

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { DocumentTypeDecoration } from "@graphql-typed-document-node/core";
22
import type { GqlResponse, NextFetchRequestConfig } from "./helpers";
3+
import { trace } from "@opentelemetry/api";
34
import {
45
createSha256,
56
defaultHeaders,
@@ -12,6 +13,9 @@ type Options = {
1213
disableCache?: boolean;
1314
};
1415

16+
// TODO: make version dynamic, or part of the release process
17+
const tracer = trace.getTracer("@labdigital/graphql-fetcher", "0.3.0");
18+
1519
export const initServerFetcher =
1620
(url: string, options?: Options) =>
1721
/**
@@ -25,14 +29,18 @@ export const initServerFetcher =
2529
next: NextFetchRequestConfig = {}
2630
): Promise<GqlResponse<TResponse>> => {
2731
const query = astNode.toString();
28-
const operationName = extractOperationName(query);
32+
const operationName = extractOperationName(query) || "(GraphQL)";
2933

3034
if (options?.disableCache) {
31-
return gqlPost<TResponse>(
32-
url,
33-
JSON.stringify({ operationName, query, variables }),
34-
"no-store",
35-
{ ...next, revalidate: 0 }
35+
return tracer.startActiveSpan(operationName, async (span) =>
36+
gqlPost<TResponse>(
37+
url,
38+
JSON.stringify({ operationName, query, variables }),
39+
"no-store",
40+
{ ...next, revalidate: 0 }
41+
).finally(() => {
42+
span.end();
43+
})
3644
);
3745
}
3846

@@ -44,24 +52,29 @@ export const initServerFetcher =
4452
};
4553

4654
// Otherwise, try to get the cached query
47-
const response = await gqlPersistedQuery<TResponse>(
48-
url,
49-
getQueryString(operationName, variables, extensions),
50-
cache,
51-
next
55+
return tracer.startActiveSpan(operationName, async (span) =>
56+
gqlPersistedQuery<TResponse>(
57+
url,
58+
getQueryString(operationName, variables, extensions),
59+
cache,
60+
next
61+
)
62+
.then((response) => {
63+
// If it doesn't exist, do a POST request anyway and cache it.
64+
if (response.errors?.[0]?.message === "PersistedQueryNotFound") {
65+
return gqlPost<TResponse>(
66+
url,
67+
JSON.stringify({ operationName, query, variables, extensions }),
68+
cache,
69+
next
70+
);
71+
}
72+
return response;
73+
})
74+
.finally(() => {
75+
span.end();
76+
})
5277
);
53-
54-
// If it doesn't exist, do a POST request anyway and cache it.
55-
if (response.errors?.[0]?.message === "PersistedQueryNotFound") {
56-
return gqlPost<TResponse>(
57-
url,
58-
JSON.stringify({ operationName, query, variables, extensions }),
59-
cache,
60-
next
61-
);
62-
}
63-
64-
return response;
6578
};
6679

6780
const gqlPost = <T>(

0 commit comments

Comments
 (0)