@W-18760780 Integrate opentelemetry into performance.js#2722
@W-18760780 Integrate opentelemetry into performance.js#2722jeremy-jung1 merged 28 commits intofeature/opentelemetryfrom
Conversation
🎉 Snyk checks have passed. No issues have been found so far.✅ security/snyk check is complete. No issues have been found. (View Details) ✅ license/snyk check is complete. No issues have been found. (View Details) |
| delete process.env.OTEL_SERVICE_NAME | ||
| delete process.env.OTEL_SDK_ENABLED | ||
| delete process.env.OTEL_B3_TRACING_ENABLED | ||
|
|
||
| const {getOTELConfig} = mockModule() | ||
| const config = getOTELConfig() | ||
|
|
||
| expect(config).toEqual({ | ||
| serviceName: 'pwa-kit-react-sdk', | ||
| enabled: false, | ||
| b3TracingEnabled: false | ||
| }) | ||
| }) |
There was a problem hiding this comment.
nit: insead of testing the combination of all the env variables would we consider having separate tests for each config?
- should return service name when OTEL_SERVICE_NAME is set
- should return default service when OTEL_SERVICE_NAME is not set
- should return enabled when OTEL_SDK_ENABLED is set
- should return disabled when OTEL_SDK_ENABLED is not set
...
That way if additional configs are added in the future each property is isolated
| }, this.maxSpanDuration) | ||
| this.spanTimeouts.set(name, timeoutId) | ||
| } | ||
| } |
There was a problem hiding this comment.
Should we log a warning in case we attempt to create a duplicate span name?
| endMark, | ||
| namespace: 'PerformanceTimer.mark' | ||
| }) | ||
| } |
There was a problem hiding this comment.
Should we also call cleanup in case of catching an error?
There was a problem hiding this comment.
The timed out automatic cleanup made for each span on creation would clean them up eventually. Even when endSpan logs an error within itself.
| mark(name, type, options = {}) { | ||
| if (!this.enabled) { | ||
| const {detail = ''} = options | ||
| if (!name || !type || !this.enabled) { |
There was a problem hiding this comment.
Should we keep checking if enabled first, then validate inputs?
| if (!name || !type || !this.enabled) { | |
| if (!this.enabled || !name || !type) { |
There was a problem hiding this comment.
Following the steps to test the changes I see in the logs we have a few "No parent span found" warnings and it looks like each span is using a different traceId instead of all spans sharing the same traceId.
...
pwa-kit-react-sdk.opentelemetry.logSpanData INFO OpenTelemetry span data {"traceId":"d8acdf23f3344d04d9da11e4dc6a6fed","name":"ssr.render-to-string","id":"e0a43b64a9e330bd","kind":0,"timestamp":"2025-07-16T02:09:20.417000000Z","duration":0,"attributes":{"service.name":"pwa-kit-react-sdk","performance_type":"start","performance.mark":"ssr.render-to-string","performance.type":"start","performance.detail":"","event":"start"},"status":{"code":0},"events":[],"links":[],"start_time":[1752631760,417000000],"end_time":[1752631760,417000000],"forwardTrace":false}
pwa-kit-react-sdk.opentelemetry.logSpanData INFO OpenTelemetry span data {"traceId":"d8acdf23f3344d04d9da11e4dc6a6fed","name":"ssr.render-to-string","id":"e0a43b64a9e330bd","kind":0,"timestamp":"2025-07-16T02:09:20.417000000Z","duration":68.30075,"attributes":{"service.name":"pwa-kit-react-sdk","performance_type":"start","performance.mark":"ssr.render-to-string","performance.type":"start","performance.detail":"","event":"end"},"status":{"code":1},"events":[],"links":[],"start_time":[1752631760,417000000],"end_time":[1752631760,485300750],"forwardTrace":false}
pwa-kit-react-sdk.opentelemetry.logSpanData INFO OpenTelemetry span data {"traceId":"714bd3edf17e826c55ed0dabb8f2cc38","name":"ssr.total","id":"31e2c7b3b61ff8f1","kind":0,"timestamp":"2025-07-16T02:09:19.220000000Z","duration":1266.033834,"attributes":{"service.name":"pwa-kit-react-sdk","performance_type":"start","performance.mark":"ssr.total","performance.type":"start","performance.detail":"","event":"end"},"status":{"code":1},"events":[],"links":[],"start_time":[1752631759,220000000],"end_time":[1752631760,486033834],"forwardTrace":false}
pwa-kit-react-sdk.opentelemetry WARN No parent span found in context {"metricName":"ssr.route-matching"}
pwa-kit-react-sdk.opentelemetry WARN No parent span found in context {"metricName":"ssr.load-component"}
pwa-kit-react-sdk.opentelemetry WARN No parent span found in context {"metricName":"ssr.fetch-strategies.react-query.pre-render"}
pwa-kit-react-sdk.opentelemetry WARN No parent span found in context {"metricName":"ssr.fetch-strategies.react-query.use-query.1"}
pwa-kit-react-sdk.opentelemetry WARN No parent span found in context {"metricName":"ssr.fetch-strategies.react-query.use-query.useCategory-0"}
pwa-kit-react-sdk.opentelemetry WARN No parent span found in context {"metricName":"ssr.fetch-strategies.react-query.use-query.useProductSearch-2"}
pwa-kit-react-sdk.opentelemetry WARN No parent span found in context {"metricName":"ssr.fetch-strategies"}
pwa-kit-react-sdk.opentelemetry WARN No parent span found in context {"metricName":"ssr.render-to-string"}
pwa-kit-react-sdk.opentelemetry WARN No parent span found in context {"metricName":"ssr.total"}
Are we missing wrapping the render function with a root span? Is this something we plan to do in a separated ticket?
https://github.com/SalesforceCommerceCloud/pwa-kit/blob/W-18129479-spike-o11y/packages/pwa-kit-react-sdk/src/ssr/server/react-rendering.js#L136
There was a problem hiding this comment.
Yeah that will be done in this ticket: https://gus.lightning.force.com/lightning/_classic/%2Fa07EE00002G04HYYAZ

Integrating opentelemetry spans into performance.js
Description
Types of Changes
Changes
How to Test-Drive This PR
pwa-kit-react-sdkand donpm run buildtemplate-retail-react-appand doexport OTEL_SDK_ENABLED=true && npm starthttp://localhost:3000/?__server_timing. See that you can see logs of spans:Checklists
General
Accessibility Compliance
You must check off all items in one of the follow two lists:
or...
Localization