Skip to content

@W-18759774 - Created opentelemetry.js file with utility functions to log OTel spans and metrics#2705

Merged
larnelleankunda merged 15 commits intofeature/opentelemetryfrom
W-18759774-opentelemetry-util
Jul 11, 2025
Merged

@W-18759774 - Created opentelemetry.js file with utility functions to log OTel spans and metrics#2705
larnelleankunda merged 15 commits intofeature/opentelemetryfrom
W-18759774-opentelemetry-util

Conversation

@larnelleankunda
Copy link
Contributor

@larnelleankunda larnelleankunda commented Jul 2, 2025

Created opentelemetry.js file with utility functions to log OTel spans and metrics as well as creates a test file for it

Description

Types of Changes

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Documentation update
  • Breaking change (could cause existing functionality to not work as expected)
  • Other changes (non-breaking changes that does not fit any of the above)

Breaking changes include:

  • Removing a public function or component or prop
  • Adding a required argument to a function
  • Changing the data type of a function parameter or return value
  • Adding a new peer dependency to package.json

Changes

  • Added an open telemetry javascript file with utility functions to log OTel Spans and Metrics as well as created tests for it.

How to Test-Drive This PR

  • Within the pwa-kit-react-sdk folder run this command to see if all tests for the open telemetry javascript file with utility functions pass - npm run test pwa-kit/packages/pwa-kit-react-sdk/src/utils/opentelemetry.test.js

Checklists

General

  • Changes are covered by test cases
  • CHANGELOG.md updated with a short description of changes (not required for documentation updates)

Accessibility Compliance

You must check off all items in one of the follow two lists:

  • There are no changes to UI

or...

Localization

  • Changes include a UI text update in the Retail React App (which requires translation)

…s and metricsas well as creates a test file for it
@larnelleankunda larnelleankunda requested a review from a team as a code owner July 2, 2025 00:26
@cc-prodsec
Copy link
Collaborator

cc-prodsec commented Jul 2, 2025

🎉 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)

@larnelleankunda larnelleankunda changed the title Created opentelemetry.js file with utility functions to log OTel spans and metrics @W-18759774 - Created opentelemetry.js file with utility functions to log OTel spans and metrics Jul 2, 2025
import {hrTimeToMilliseconds, hrTimeToTimeStamp} from '@opentelemetry/core'
import logger from './logger-instance'

const SERVICE_NAME = 'pwa-kit-react-sdk'
Copy link
Contributor

Choose a reason for hiding this comment

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

We have now have two different places where we are defining the service name value, one in the /utils/opentelemetry.js file and another one in the /server/opentelemetry-server.js file:

const DEFAULT_SERVICE_NAME = 'pwa-kit-react-sdk'

What do you think if we keep the opentelemetry config in the /utils/opentelemetry.js file as the source of truth, so we consistently use the same config values in the opentelemetry utils and opetelemetry server initialization files?

Example:

//utils/opentelemetry.js
const DEFAULT_SERVICE_NAME = 'pwa-kit-react-sdk'

export const OTEL_CONFIG = {
    serviceName: process.env.OTEL_SERVICE_NAME || DEFAULT_SERVICE_NAME,
    enabled: process.env.OTEL_SDK_ENABLED === 'true',
    b3TracingEnabled: process.env.OTEL_B3_TRACING_ENABLED === 'true',
}

export const getServiceName = () => OTEL_CONFIG.serviceName

Re-use the config in the opentelemetry-server.js file:

//server/opentelemetry-server.js

import {OTEL_CONFIG} from '../../utils/opentelemetry'

export const initializeServerTracing = (options = {}) => {
    const config = { ...OTEL_CONFIG, ...options }
    ...
}

Later, in future PRs we can use the config like this:

//server/react-rendering.js 
import {OTEL_CONFIG} from '../../utils/opentelemetry'
import {initializeServerTracing} from './opentelemetry-server'

initializeServerTracing(OTEL_CONFIG)
...

Copy link
Collaborator

@jeremy-jung1 jeremy-jung1 Jul 10, 2025

Choose a reason for hiding this comment

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

As I actually use the opentelemetry.js in peformance.js in development which gets it closer to working end-to-end. I see that the app errors out with an uncaught exception that process is not defined.

I believe this is because process.env, when accessed from this config in the top-level portion of this file outside of any functions, is in the context of the browser environment where it doesn't have the scope for process. Webpack includes the opentelemetry.js in the app bundle and the browser executes the top-level code. We might want to keep any usage of process.env within functions that are called server-side.

I'll make some changes to this in my performance.js PR

timestamp: hrTimeToTimeStamp(startTime),
duration: duration,
attributes: {
'service.name': SERVICE_NAME,
Copy link
Contributor

Choose a reason for hiding this comment

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

If you agree with the previous comment we need to replace all references of SERVICE_NAME:

Suggested change
'service.name': SERVICE_NAME,
'service.name': getServiceName(),

links: [],
start_time: startTime,
end_time: endTime,
forwardTrace: process.env.DISABLE_B3_TRACING !== 'true'
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
forwardTrace: process.env.DISABLE_B3_TRACING !== 'true'
forwardTrace: OTEL_CONFIG.b3TracingEnabled


const SERVICE_NAME = 'pwa-kit-react-sdk'

function logSpanData(span, event = 'start', res = null) {
Copy link
Contributor

@adamraya adamraya Jul 4, 2025

Choose a reason for hiding this comment

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

Can we use the arrow function pattern used throughout the codebase instead of regular function for consistency?

Suggested change
function logSpanData(span, event = 'start', res = null) {
const logSpanData = (span, event = 'start', res = null) => {

* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
/* eslint-disable @typescript-eslint/no-var-requires */
const base = require('internal-lib-build/configs/jest/jest.config')
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: Do we need this change?

Copy link
Collaborator

Choose a reason for hiding this comment

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

+1 on this nit. It may not seem like a big deal that a change like this that doesn't do anything goes in the PR, but one downside is in the future if someone wants to do a git blame to see "hey who added this line about requiring jest.config here and why did they do that" then they will see this PR instead of the originating PR.


export const OTEL_CONFIG = {
serviceName: process.env.OTEL_SERVICE_NAME || DEFAULT_SERVICE_NAME,
enabled: process.env.OTEL_SDK_ENABLED === 'true',
Copy link
Collaborator

Choose a reason for hiding this comment

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

I see we have an enabled flag in the CONFIG but are we reading this in anywhere? Or will this be used in future PR's when we make changes to performance and react-rendering?


export const getServiceName = () => OTEL_CONFIG.serviceName

const SERVICE_NAME = OTEL_CONFIG.serviceName
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
const SERVICE_NAME = OTEL_CONFIG.serviceName

We don't need this line. As Adam mentioned, we can replace all instances of SERVICE_NAME with getServiceName()

*/
export const createSpan = (name, options = {}) => {
try {
const tracer = trace.getTracer(SERVICE_NAME)
Copy link
Collaborator

Choose a reason for hiding this comment

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

For example, we would replace it here:

Suggested change
const tracer = trace.getTracer(SERVICE_NAME)
const tracer = trace.getTracer(getServiceName())

Comment on lines +179 to +180
const ctx = context.active()
// Note: parentSpan is not used in this implementation
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we need these 2 lines if ctx is not used anywhere?

Comment on lines +7 to +12
/*
* Copyright (c) 2025, Salesforce, Inc.
* All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
Copy link
Collaborator

Choose a reason for hiding this comment

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

Duplicate

Suggested change
/*
* Copyright (c) 2025, Salesforce, Inc.
* All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/

Copy link
Contributor

@adamraya adamraya left a comment

Choose a reason for hiding this comment

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

Thanks for making the changes. LGTM


const DEFAULT_SERVICE_NAME = 'pwa-kit-react-sdk'

export const OTEL_CONFIG = {
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's use the OTEL_CONFIG in packages/pwa-kit-react-sdk/src/utils/opentelemetry-server.js file.

Remove the DEFAULT_SERVICE_NAME constant from opentelemetry-server.js:

const DEFAULT_SERVICE_NAME = 'pwa-kit-react-sdk'

And replace it with getServiceName:

import {getServiceName, OTEL_CONFIG} from '../../utils/opentelemetry'

const serviceName = options.serviceName || getServiceName()
...

@larnelleankunda larnelleankunda merged commit 4fa34a2 into feature/opentelemetry Jul 11, 2025
35 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants