Skip to content

fix(opentelemetry): Patch otel sdk for span start time with nanosecond precision #1343

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: v2
Choose a base branch
from
Open
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
7 changes: 7 additions & 0 deletions .changeset/@graphql-hive_gateway-1343-dependencies.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@graphql-hive/gateway': patch
---

dependencies updates:

- Updated dependency [`@opentelemetry/sdk-trace-base@patch:@opentelemetry/sdk-trace-base@patch%3A@opentelemetry/sdk-trace-base@npm%253A2.0.1%23~/.yarn/patches/@opentelemetry-sdk-trace-base-npm-2.0.1-ebe4f8e34e.patch%3A%3Aversion=2.0.1&hash=212481#~/.yarn/patches/@opentelemetry-sdk-trace-base-patch-0b7dbf6a30.patch` ↗︎](https://www.npmjs.com/package/@opentelemetry/sdk-trace-base/v/3.0.0) (from `^2.0.1`, in `dependencies`)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@graphql-mesh/plugin-opentelemetry': patch
---

dependencies updates:

- Updated dependency [`@opentelemetry/sdk-trace-base@patch:@opentelemetry/sdk-trace-base@patch%3A@opentelemetry/sdk-trace-base@npm%253A2.0.1%23~/.yarn/patches/@opentelemetry-sdk-trace-base-npm-2.0.1-ebe4f8e34e.patch%3A%3Aversion=2.0.1&hash=212481#~/.yarn/patches/@opentelemetry-sdk-trace-base-patch-0b7dbf6a30.patch` ↗︎](https://www.npmjs.com/package/@opentelemetry/sdk-trace-base/v/3.0.0) (from `^2.0.1`, in `dependencies`)
6 changes: 6 additions & 0 deletions .changeset/strong-paws-complain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@graphql-mesh/plugin-opentelemetry': patch
'@graphql-hive/gateway': patch
---

Patch the `@opentelemetry/sdk-trace-base` package to fix span start time precision being millisecond instead of nanosecond.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
diff --git a/build/esm/Span.js b/build/esm/Span.js
index 185835fdc5667eddb072891618607ce213bb6625..5554c8bde3f6f44504587a88e115104a01d39ec4 100644
--- a/build/esm/Span.js
+++ b/build/esm/Span.js
@@ -66,7 +66,7 @@ export class SpanImpl {
this.parentSpanContext = opts.parentSpanContext;
this.kind = opts.kind;
this.links = opts.links || [];
- this.startTime = this._getTime(opts.startTime ?? now);
+ this.startTime = this._getTime(opts.startTime ?? hrTime(this._performanceStartTime + this._performanceOffset));
this.resource = opts.resource;
this.instrumentationScope = opts.scope;
if (opts.attributes != null) {
diff --git a/build/esnext/Span.js b/build/esnext/Span.js
index 185835fdc5667eddb072891618607ce213bb6625..5554c8bde3f6f44504587a88e115104a01d39ec4 100644
--- a/build/esnext/Span.js
+++ b/build/esnext/Span.js
@@ -66,7 +66,7 @@ export class SpanImpl {
this.parentSpanContext = opts.parentSpanContext;
this.kind = opts.kind;
this.links = opts.links || [];
- this.startTime = this._getTime(opts.startTime ?? now);
+ this.startTime = this._getTime(opts.startTime ?? hrTime(this._performanceStartTime + this._performanceOffset));
this.resource = opts.resource;
this.instrumentationScope = opts.scope;
if (opts.attributes != null) {
diff --git a/build/src/Span.js b/build/src/Span.js
index 5a807fe223a70e5e077b66ad74b8efe2eaabd8fa..6388deff9c1e83946f16b04cbfaf884b6f350d29 100644
--- a/build/src/Span.js
+++ b/build/src/Span.js
@@ -69,7 +69,7 @@ class SpanImpl {
this.parentSpanContext = opts.parentSpanContext;
this.kind = opts.kind;
this.links = opts.links || [];
- this.startTime = this._getTime(opts.startTime ?? now);
+ this.startTime = this._getTime(opts.startTime ?? hrTime(this._performanceStartTime + this._performanceOffset));
this.resource = opts.resource;
this.instrumentationScope = opts.scope;
if (opts.attributes != null) {
13 changes: 13 additions & 0 deletions .yarn/patches/@opentelemetry-sdk-trace-base-patch-0b7dbf6a30.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/build/src/Span.js b/build/src/Span.js
index 12c33551fa559f3657e1d9074cadb34b7e73a675..63ac0075b94eae4c519d94c5c141c7002d21e412 100644
--- a/build/src/Span.js
+++ b/build/src/Span.js
@@ -69,7 +69,7 @@ class SpanImpl {
this.parentSpanContext = opts.parentSpanContext;
this.kind = opts.kind;
this.links = opts.links || [];
- this.startTime = this._getTime(opts.startTime ?? hrTime(this._performanceStartTime + this._performanceOffset));
+ this.startTime = this._getTime(opts.startTime ?? core_1.hrTime(this._performanceStartTime + this._performanceOffset));
this.resource = opts.resource;
this.instrumentationScope = opts.scope;
if (opts.attributes != null) {
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
"pkgroll": "patch:pkgroll@npm:2.5.1#~/.yarn/patches/pkgroll-npm-2.5.1-9b062c22ca.patch",
"tar-fs": "3.0.10",
"tsx": "patch:tsx@npm%3A4.20.3#~/.yarn/patches/tsx-npm-4.20.3-7de67a623f.patch",
"vite": "6.3.5"
"vite": "6.3.5",
"@opentelemetry/sdk-trace-base@npm:2.0.1": "patch:@opentelemetry/sdk-trace-base@patch%3A@opentelemetry/sdk-trace-base@npm%253A2.0.1%23~/.yarn/patches/@opentelemetry-sdk-trace-base-npm-2.0.1-ebe4f8e34e.patch%3A%3Aversion=2.0.1&hash=212481#~/.yarn/patches/@opentelemetry-sdk-trace-base-patch-0b7dbf6a30.patch"
}
}
2 changes: 1 addition & 1 deletion packages/gateway/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
"@opentelemetry/sampler-jaeger-remote": "^0.203.0",
"@opentelemetry/sdk-logs": "^0.203.0",
"@opentelemetry/sdk-metrics": "^2.0.1",
"@opentelemetry/sdk-trace-base": "^2.0.1",
"@opentelemetry/sdk-trace-base": "patch:@opentelemetry/sdk-trace-base@patch%3A@opentelemetry/sdk-trace-base@npm%253A2.0.1%23~/.yarn/patches/@opentelemetry-sdk-trace-base-npm-2.0.1-ebe4f8e34e.patch%3A%3Aversion=2.0.1&hash=212481#~/.yarn/patches/@opentelemetry-sdk-trace-base-patch-0b7dbf6a30.patch",
"commander": "^13.1.0",
"dotenv": "^17.2.0",
"graphql-ws": "^6.0.6",
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/opentelemetry/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
"@opentelemetry/resources": "^2.0.1",
"@opentelemetry/sdk-logs": "^0.203.0",
"@opentelemetry/sdk-node": "^0.203.0",
"@opentelemetry/sdk-trace-base": "^2.0.1",
"@opentelemetry/sdk-trace-base": "patch:@opentelemetry/sdk-trace-base@patch%3A@opentelemetry/sdk-trace-base@npm%253A2.0.1%23~/.yarn/patches/@opentelemetry-sdk-trace-base-npm-2.0.1-ebe4f8e34e.patch%3A%3Aversion=2.0.1&hash=212481#~/.yarn/patches/@opentelemetry-sdk-trace-base-patch-0b7dbf6a30.patch",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Publishing this will break installs. Patches are only for local things. If patching the library is the only way to go, then we need to handle it differently - on Hive Console side.

P.S. Node has only millisecond precision, so we cannot expect it to give out accurate nanoseconds.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes, I should only add this to the root package.json.

It's more an experiment at this point for @n1ru4l

We can ship this in the binary, but not sure we should have such behavior diff between binary and node usage.

I'm trying to make a PR on opentelemetry side. Perhaps I can publish a fork ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think pushing this PR to OTEL is a good way to go. But we dont have to do all that just for one change, do you think they'd release soon or would it take months?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on other PR dates, it takes loooong time to merge things, even for member of the repo...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And we cannot handle it in Hive Console @n1ru4l? I can imagine others using Hive Console's observability features having the same issues, especially if based on OTEL's libs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can't be on Hive Console side, since it's the data producer that has the "bug".
It's span creation that uses a low precision timestamp...

A workaround for us waiting for a proper upstream fix would be to manually provide the start and end times. This way, we are sure that at least our spans have correct precision.

"@opentelemetry/semantic-conventions": "^1.36.0",
"@whatwg-node/promise-helpers": "1.3.0",
"tslib": "^2.8.1"
Expand Down
32 changes: 29 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4219,7 +4219,7 @@ __metadata:
"@opentelemetry/sampler-jaeger-remote": "npm:^0.203.0"
"@opentelemetry/sdk-logs": "npm:^0.203.0"
"@opentelemetry/sdk-metrics": "npm:^2.0.1"
"@opentelemetry/sdk-trace-base": "npm:^2.0.1"
"@opentelemetry/sdk-trace-base": "patch:@opentelemetry/sdk-trace-base@patch%3A@opentelemetry/sdk-trace-base@npm%253A2.0.1%23~/.yarn/patches/@opentelemetry-sdk-trace-base-npm-2.0.1-ebe4f8e34e.patch%3A%3Aversion=2.0.1&hash=212481#~/.yarn/patches/@opentelemetry-sdk-trace-base-patch-0b7dbf6a30.patch"
"@rollup/plugin-commonjs": "npm:^28.0.0"
"@rollup/plugin-json": "npm:^6.1.0"
"@rollup/plugin-node-resolve": "patch:@rollup/plugin-node-resolve@npm%3A16.0.1#~/.yarn/patches/@rollup-plugin-node-resolve-npm-16.0.1-2936474bab.patch"
Expand Down Expand Up @@ -4693,7 +4693,7 @@ __metadata:
"@opentelemetry/resources": "npm:^2.0.1"
"@opentelemetry/sdk-logs": "npm:^0.203.0"
"@opentelemetry/sdk-node": "npm:^0.203.0"
"@opentelemetry/sdk-trace-base": "npm:^2.0.1"
"@opentelemetry/sdk-trace-base": "patch:@opentelemetry/sdk-trace-base@patch%3A@opentelemetry/sdk-trace-base@npm%253A2.0.1%23~/.yarn/patches/@opentelemetry-sdk-trace-base-npm-2.0.1-ebe4f8e34e.patch%3A%3Aversion=2.0.1&hash=212481#~/.yarn/patches/@opentelemetry-sdk-trace-base-patch-0b7dbf6a30.patch"
"@opentelemetry/semantic-conventions": "npm:^1.36.0"
"@whatwg-node/promise-helpers": "npm:1.3.0"
"@whatwg-node/server": "npm:^0.10.0"
Expand Down Expand Up @@ -7793,7 +7793,7 @@ __metadata:
languageName: node
linkType: hard

"@opentelemetry/sdk-trace-base@npm:2.0.1, @opentelemetry/sdk-trace-base@npm:^2.0.1":
"@opentelemetry/sdk-trace-base@npm:2.0.1":
version: 2.0.1
resolution: "@opentelemetry/sdk-trace-base@npm:2.0.1"
dependencies:
Expand All @@ -7806,6 +7806,32 @@ __metadata:
languageName: node
linkType: hard

"@opentelemetry/sdk-trace-base@patch:@opentelemetry/sdk-trace-base@npm%3A2.0.1#~/.yarn/patches/@opentelemetry-sdk-trace-base-npm-2.0.1-ebe4f8e34e.patch::version=2.0.1&hash=212481":
version: 2.0.1
resolution: "@opentelemetry/sdk-trace-base@patch:@opentelemetry/sdk-trace-base@npm%3A2.0.1#~/.yarn/patches/@opentelemetry-sdk-trace-base-npm-2.0.1-ebe4f8e34e.patch::version=2.0.1&hash=212481"
dependencies:
"@opentelemetry/core": "npm:2.0.1"
"@opentelemetry/resources": "npm:2.0.1"
"@opentelemetry/semantic-conventions": "npm:^1.29.0"
peerDependencies:
"@opentelemetry/api": ">=1.3.0 <1.10.0"
checksum: 10c0/1eeddf77153d7f374e57c1033e0971a7aa27e489e17d5679368ccd39b71eb4c467516859e93b627f9bbe3b7af839db44c4de727d1c17bffd3775dd288e64974d
languageName: node
linkType: hard

"@opentelemetry/sdk-trace-base@patch:@opentelemetry/sdk-trace-base@patch%3A@opentelemetry/sdk-trace-base@npm%253A2.0.1%23~/.yarn/patches/@opentelemetry-sdk-trace-base-npm-2.0.1-ebe4f8e34e.patch%3A%3Aversion=2.0.1&hash=212481#~/.yarn/patches/@opentelemetry-sdk-trace-base-patch-0b7dbf6a30.patch":
version: 2.0.1
resolution: "@opentelemetry/sdk-trace-base@patch:@opentelemetry/sdk-trace-base@patch%3A@opentelemetry/sdk-trace-base@npm%253A2.0.1%23~/.yarn/patches/@opentelemetry-sdk-trace-base-npm-2.0.1-ebe4f8e34e.patch%3A%3Aversion=2.0.1&hash=212481#~/.yarn/patches/@opentelemetry-sdk-trace-base-patch-0b7dbf6a30.patch::version=2.0.1&hash=9e89a6"
dependencies:
"@opentelemetry/core": "npm:2.0.1"
"@opentelemetry/resources": "npm:2.0.1"
"@opentelemetry/semantic-conventions": "npm:^1.29.0"
peerDependencies:
"@opentelemetry/api": ">=1.3.0 <1.10.0"
checksum: 10c0/8dd7c5266da16f3eebe37a2d158c17394b8abfb078b7276600e158d2af280778b77eadc980b91a8ac8b5a3d30e8ebe3bf07308c8e8a859254e0a2c9d61d7d2cf
languageName: node
linkType: hard

"@opentelemetry/sdk-trace-node@npm:2.0.1":
version: 2.0.1
resolution: "@opentelemetry/sdk-trace-node@npm:2.0.1"
Expand Down
Loading