Skip to content

Add optional OpenTelemetry telemetry adapter for API calls#123

Merged
cb-alish merged 9 commits into
masterfrom
otel-integration
Jul 1, 2026
Merged

Add optional OpenTelemetry telemetry adapter for API calls#123
cb-alish merged 9 commits into
masterfrom
otel-integration

Conversation

@cb-karthikp

@cb-karthikp cb-karthikp commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Adds optional telemetryAdapter hook for tracing Chargebee API calls via OpenTelemetry (or any APM)
  • Emits one CLIENT span per API call: chargebee.{resource}.{operation} with OTel HTTP + chargebee.* attributes
  • Injects W3C trace context (traceparent) into outbound requests for distributed tracing
  • OpenTelemetry is not bundled — customers install OTEL in their app and pass a custom adapter
  • Fixes class-based adapters (new OtelTelemetryAdapter()) being silently dropped during env deep-clone
  • Adds unit tests, README docs

Adds optional telemetryAdapter tracing for Chargebee API calls. One OpenTelemetry CLIENT span per request (chargebee.{resource}.{operation}) with standardized http.* and chargebee.* attributes and W3C traceparent injection. Includes OpenTelemetry adapter export, updated public types/exports, config cloning fix for class adapters, plus README docs and unit tests.

@snyk-io

snyk-io Bot commented Jun 12, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@hivel-marco hivel-marco Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

PR Complexity Score: 6.1 - Complex

View Breakdown
  • Lines Changed: 823
  • Files Changed: 11
  • Complexity Added: 59
  • Raw Score: 137.96
⚠️ Sensitive Data (PII/ Secrets) Detected
FileTypesCount
src/telemetry/TelemetryAdapter.ts
LineTypePreview
PII: Email Addressdx@chargebee.com
Email Address1
src/telemetry/index.ts
LineTypePreview
PII: Email Addressdx@chargebee.com
Email Address1
src/telemetry/types.ts
LineTypePreview
PII: Email Addressdx@chargebee.com
Email Address1
Overview

This PR introduces an optional telemetry adapter API to the Chargebee Node SDK so users can integrate API call tracing with observability tools such as OpenTelemetry. It standardises span naming and attributes, exposes telemetry types and constants in the public API, and ensures telemetry is strictly best-effort and non-breaking. The README is updated with documentation and an end-to-end OpenTelemetry example.

Key Changes
  • Adds a telemetryAdapter option to the top-level Chargebee configuration and environment, allowing users to plug in custom telemetry (e.g. OpenTelemetry) without bundling any telemetry libraries into the SDK.
  • Introduces a TelemetryAdapter interface and supporting types (RequestTelemetryContext, RequestTelemetryResult, RequestTelemetryError, RequestTelemetryHandle) to describe request lifecycle events for observability.
  • Implements span naming (chargebee.{resource}.{operation}) and attributes aligned with OpenTelemetry HTTP semantic conventions plus Chargebee-specific keys, exported via TelemetryAttributeKeys for consistent usage across tools and SDKs.
  • Updates RequestWrapper to build a canonical request URL, construct telemetry context/results, propagate telemetry headers, and call the adapter once per API call (spanning all retries), while handling any adapter errors gracefully and logging them.
  • Ensures class-based telemetry adapters are preserved when environment config is merged (avoiding prototype loss) by storing the adapter by reference, not via deep cloning.
  • Exposes TelemetryAttributeKeys via both CJS and ESM entrypoints and adds type declarations in types/index.d.ts to make telemetry primitives available to consumers.
  • Adds tests covering header behaviour with retries, telemetry adapter invocation patterns, error attribution, safety on adapter exceptions, and runtime export of telemetry constants.
  • Extends documentation with a dedicated “Telemetry (OpenTelemetry)” section and a complete Node/OpenTelemetry integration example, including span propagation and status reporting.
Risks & Considerations
  • Telemetry context assumes resource names are correctly set on apiCall; incorrect or missing resource metadata could produce misleading span names and attributes.
  • The inferred API version uses apiPath === '/api/v1' ? 'v1' : 'v2'; any future path variants may need explicit handling to keep telemetry accurate.
  • Telemetry adapter errors are intentionally swallowed (with logging) to avoid impacting API calls, so misconfigurations may silently degrade observability unless logs are monitored.
  • Request URL and query parameter construction have been refactored into _buildRequestUrl; regressions would surface as incorrect URLs or query strings and warrant careful review of URL/param handling.
  • Consumers implementing telemetry must ensure their adapter does not mutate headers or throw unexpectedly in production, as it can affect propagation behaviour even though API calls continue.
File-level change summary
File Change summary
README.md Adds a “Telemetry (OpenTelemetry)” section with conceptual docs and a full OpenTelemetry integration example using a custom TelemetryAdapter.
src/RequestWrapper.ts Integrates telemetry adapter hooks around request execution, refactors URL construction, propagates telemetry headers, and wraps retry logic with telemetry-safe error handling.
src/chargebee.cjs.ts Re-exports TelemetryAttributeKeys from the telemetry module for CommonJS consumers.
src/chargebee.esm.ts Re-exports TelemetryAttributeKeys from the telemetry module for ESM consumers.
src/createChargebee.ts Adjusts environment merging to keep telemetryAdapter by reference, sets HTTP client from config properly, and tags each ResourceType with its resource name for telemetry.
src/telemetry/TelemetryAdapter.ts Defines the TelemetryAdapter interface, no-op adapter, and helper functions to build span names, attributes, telemetry context/results, and to extract error/status info.
src/telemetry/index.ts Central telemetry barrel file exporting telemetry constants, types, adapter interface, helpers, and the no-op adapter.
src/telemetry/types.ts Declares telemetry-related constants (CHARGEBEE_SDK_NAME, TELEMETRY_SPAN_NAME_PREFIX, TelemetryAttributeKeys) and the core telemetry type definitions.
src/types.d.ts Extends internal types to include telemetryAdapter on EnvType/Config and adds a resource field to ResourceType for telemetry context.
test/requestWrapper.test.ts Adds and refines tests for retry headers plus new tests validating telemetry adapter invocation, error mapping, resilience to adapter failures, class-based adapters, and runtime export of TelemetryAttributeKeys.
types/index.d.ts Updates public TypeScript declarations to include telemetry config on Config, telemetry attribute constants, and all telemetry-related types and interfaces.

@hivel-marco hivel-marco Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

PR Complexity Score: 3.9 - Simple

View Breakdown
  • Lines Changed: 361
  • Files Changed: 4
  • Complexity Added: 31
  • Raw Score: 65.72
⚠️ Sensitive Data (PII/ Secrets) Detected
FileTypesCount
src/telemetry/TelemetryAdapter.ts
LineTypePreview
PII: Email Addressdx@chargebee.com
Email Address1
src/telemetry/index.ts
LineTypePreview
PII: Email Addressdx@chargebee.com
Email Address1
src/telemetry/types.ts
LineTypePreview
PII: Email Addressdx@chargebee.com
Email Address1
Overview

This PR adds a pluggable telemetry layer to the SDK so HTTP requests can be observed by external systems (e.g. OpenTelemetry) without affecting behaviour when telemetry is disabled. It introduces a TelemetryAdapter abstraction, request-level telemetry context/result builders, and integrates them into RequestWrapper’s lifecycle. It also exposes telemetry types and attribute keys from the main Chargebee entrypoints.

Key Changes
  • Introduces a TelemetryAdapter interface (plus NoOpTelemetryAdapter) and helper functions to build telemetry span names, attributes, contexts, and results for HTTP requests.
  • Integrates telemetry into RequestWrapper.request() by:
    • Preserving the telemetryAdapter reference when cloning env.
    • Building the full request URL once via a new _buildRequestUrl helper.
    • Invoking telemetryAdapter.onRequestStart before the request to collect context and headers, and onRequestEnd after success or error with status code, duration, and error details.
    • Merging telemetry headers into the existing request headers and using robust error handling/logging if the adapter throws.
  • Adds utility functions to extract HTTP status codes and standardised error metadata from errors for telemetry reporting.
  • Exports telemetry-related types and TelemetryAttributeKeys from both CJS and ESM entrypoints so integrators can implement adapters and use the canonical attribute names.
Risks & Considerations
  • Telemetry adapter failures are logged but intentionally non-fatal; reviewers should confirm this is the desired behaviour and that logging levels/messages are appropriate.
  • requestUrl is now built once per request() call and reused across retries; reviewers should verify this does not conflict with any future per-attempt URL mutation needs.
  • Telemetry headers are reused across retries and merged into request headers; ensure no adapter-dependent state leaks or header mutations cause issues across attempts.
  • resolveChargebeeApiVersion derives the API version from env.apiPath with a default of v2; confirm this assumption matches all supported configurations.
File-level change summary
File Change summary
src/RequestWrapper.ts Integrates the telemetry adapter into the request lifecycle, adds URL-building helper, merges telemetry headers into requests, and wraps retry execution with start/end telemetry reporting and error extraction.
src/chargebee.cjs.ts Exposes TelemetryAttributeKeys and re-exports telemetry-related TypeScript types from the CommonJS entrypoint.
src/chargebee.esm.ts Exposes TelemetryAttributeKeys and re-exports telemetry-related TypeScript types from the ESM entrypoint.
src/telemetry/TelemetryAdapter.ts Adds the TelemetryAdapter interface, no-op adapter, and helper functions to build telemetry contexts/results, derive span names and attributes, and extract error/status information for telemetry.

@hivel-marco hivel-marco Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

PR Complexity Score: 1.5 - Trivial

View Breakdown
  • Lines Changed: 72
  • Files Changed: 1
  • Complexity Added: 4
  • Raw Score: 10.44
⚠️ Sensitive Data (PII/ Secrets) Detected
FileTypesCount
src/telemetry/TelemetryAdapter.ts
LineTypePreview
PII: Email Addressdx@chargebee.com
Email Address1
src/telemetry/index.ts
LineTypePreview
PII: Email Addressdx@chargebee.com
Email Address1
src/telemetry/types.ts
LineTypePreview
PII: Email Addressdx@chargebee.com
Email Address1
Overview

Adds documentation for integrating Chargebee API calls with OpenTelemetry-based tracing via a pluggable telemetryAdapter.
Explains how to use standardized HTTP span attributes plus Chargebee-specific attributes, and provides a concrete TypeScript example using the OpenTelemetry Node SDK and OTLP exporter.
Clarifies that OpenTelemetry is not bundled with the SDK and must be configured by the application.

Key Changes
  • Introduces a new "Telemetry (OpenTelemetry)" section in the README describing how to trace Chargebee API calls using a TelemetryAdapter.
  • Documents the span naming convention (chargebee.{resource}.{operation}) and the HTTP and chargebee.* span attributes that the SDK will populate for consistency across observability tools.
  • Provides a step-by-step example showing installation of OpenTelemetry packages, NodeSDK configuration with OTLP HTTP exporter, and an OtelTelemetryAdapter implementation that starts, injects, and finalizes spans around API requests.
  • Clarifies that spans are exported solely via the host application's OpenTelemetry configuration, independent of the Chargebee SDK configuration.
Risks & Considerations
  • Example assumes familiarity with OpenTelemetry concepts (contexts, propagation, tracers, span status); users new to OTel may need additional guidance.
  • The documented attribute names and span conventions become de facto API contracts; future SDK or telemetry changes must preserve or version these semantics to avoid breaking existing dashboards.
  • Consumers must ensure their OpenTelemetry setup and exporter configuration (e.g., OTLP endpoint) are correct; misconfiguration will result in missing traces even though the SDK integration is wired.
File-level change summary
File Change summary
README.md Adds a new Telemetry (OpenTelemetry) section with installation guidance, span semantics, and a full TypeScript example of integrating a TelemetryAdapter using OpenTelemetry and OTLP exporter.

@hivel-marco hivel-marco Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

PR Complexity Score: 1.5 - Trivial

View Breakdown
  • Lines Changed: 73
  • Files Changed: 1
  • Complexity Added: 4
  • Raw Score: 10.46
⚠️ Sensitive Data (PII/ Secrets) Detected
FileTypesCount
src/telemetry/TelemetryAdapter.ts
LineTypePreview
PII: Email Addressdx@chargebee.com
Email Address1
src/telemetry/index.ts
LineTypePreview
PII: Email Addressdx@chargebee.com
Email Address1
src/telemetry/types.ts
LineTypePreview
PII: Email Addressdx@chargebee.com
Email Address1
Overview

This PR updates the README to document optional OpenTelemetry-based telemetry support for the Chargebee SDK. It explains how to plug in a telemetryAdapter to trace API calls and shows how spans are named and attributed. An end-to-end example demonstrates wiring Chargebee into an OpenTelemetry setup and exporting traces to an OTLP-compatible backend.

Key Changes
  • Adds a "Telemetry (OpenTelemetry)" section describing how to enable tracing of Chargebee API calls via a telemetryAdapter.
  • Documents the standardized HTTP span attributes and Chargebee-specific chargebee.* attributes used by the SDK, and how span names are structured (chargebee.{resource}.{operation}).
  • Provides a concrete TypeScript example implementing TelemetryAdapter with OpenTelemetry, including span lifecycle management and context propagation.
  • Clarifies that OpenTelemetry is not bundled with the SDK and must be installed, configured, and exported to the user's chosen APM backend.
Risks & Considerations
  • Readers may assume telemetry is enabled by default; it is optional and requires explicit adapter implementation and OpenTelemetry setup.
  • The example relies on specific OpenTelemetry packages (@opentelemetry/sdk-node, @opentelemetry/exporter-trace-otlp-http), which may change APIs over time and could require README updates.
  • Misconfiguring exporters or endpoints in the user's OpenTelemetry setup could result in missing or incomplete traces, even though Chargebee is configured correctly.
File-level change summary
File Change summary
README.md Adds documentation and a full TypeScript example for integrating Chargebee with OpenTelemetry via a custom telemetryAdapter.

Comment thread src/RequestWrapper.ts
@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: ea79f2bd-5691-4bec-bb8a-168989a3b8cf

📥 Commits

Reviewing files that changed from the base of the PR and between f413706 and e6f5fbb.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (11)
  • CHANGELOG.md
  • README.md
  • VERSION
  • package.json
  • src/RequestWrapper.ts
  • src/chargebee.cjs.ts
  • src/chargebee.esm.ts
  • src/createChargebee.ts
  • src/environment.ts
  • src/types.d.ts
  • types/index.d.ts
✅ Files skipped from review due to trivial changes (3)
  • VERSION
  • src/environment.ts
  • CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (8)
  • src/chargebee.cjs.ts
  • src/createChargebee.ts
  • src/chargebee.esm.ts
  • README.md
  • src/types.d.ts
  • package.json
  • types/index.d.ts
  • src/RequestWrapper.ts

Walkthrough

Adds telemetry adapter support to the SDK, including telemetry types and helpers, a built-in OpenTelemetry adapter, request-flow wiring, public exports, tests, and documentation. The package and runtime version metadata are bumped to 3.28.0.

Changes

OpenTelemetry Telemetry Adapter

Layer / File(s) Summary
Telemetry types and public contracts
src/telemetry/types.ts, types/index.d.ts, src/types.d.ts
Defines telemetry constants, request telemetry types, the adapter interface, and SDK config/env typing updates for telemetryAdapter and resource.
Telemetry helpers and index exports
src/telemetry/TelemetryAdapter.ts, src/telemetry/index.ts
Implements span naming, header filtering, span attribute builders, telemetry context/result builders, and unknown-error/status-code extraction helpers, then re-exports the telemetry surface.
Built-in OpenTelemetry adapter
src/telemetry/otel.ts, types/telemetry/otel.d.ts, package.json
Implements OtelTelemetryAdapter, span creation/injection, end handling, the default adapter export, the chargebee/telemetry/otel subpath, and the optional @opentelemetry/api peer dependency.
RequestWrapper telemetry integration
src/RequestWrapper.ts, src/createChargebee.ts, src/environment.ts
Builds request URLs centrally, preserves telemetry config in the env, calls telemetry start/end hooks around retries, and merges telemetry headers into outgoing requests.
Public exports, tests, and docs
src/chargebee.esm.ts, src/chargebee.cjs.ts, test/requestWrapper.test.ts, README.md, CHANGELOG.md, VERSION, package.json
Re-exports telemetry symbols, expands telemetry and retry tests, documents telemetry usage, and bumps version/client metadata to 3.28.0.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes


Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/types.d.ts (1)

57-71: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Keep ResourceType backward-compatible.

Line 58 makes resource mandatory in a public declaration file. That will break downstream TypeScript consumers that construct ResourceType directly; either keep it optional or treat this as a major-version/API break.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/types.d.ts` around lines 57 - 71, `ResourceType` in the public type
declaration was made incompatible by requiring `resource`, which can break
downstream consumers that construct this type directly. Update the
`ResourceType` definition to preserve backward compatibility by keeping
`resource` optional (or otherwise retaining the previous contract) and make sure
the rest of the properties in the type still align with existing call sites such
as `methodName`, `httpMethod`, and `urlPrefix`.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/types.d.ts`:
- Around line 57-71: `ResourceType` in the public type declaration was made
incompatible by requiring `resource`, which can break downstream consumers that
construct this type directly. Update the `ResourceType` definition to preserve
backward compatibility by keeping `resource` optional (or otherwise retaining
the previous contract) and make sure the rest of the properties in the type
still align with existing call sites such as `methodName`, `httpMethod`, and
`urlPrefix`.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 1105b796-ad58-47cb-8ecc-5db71a6de130

📥 Commits

Reviewing files that changed from the base of the PR and between 1a10ac8 and b4b63bc.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (14)
  • README.md
  • package.json
  • src/RequestWrapper.ts
  • src/chargebee.cjs.ts
  • src/chargebee.esm.ts
  • src/createChargebee.ts
  • src/telemetry/TelemetryAdapter.ts
  • src/telemetry/index.ts
  • src/telemetry/otel.ts
  • src/telemetry/types.ts
  • src/types.d.ts
  • test/requestWrapper.test.ts
  • types/index.d.ts
  • types/telemetry/otel.d.ts

@cb-karthikp cb-karthikp requested a review from cb-alish June 30, 2026 07:23
@cb-karthikp cb-karthikp marked this pull request as ready for review June 30, 2026 07:23
# Conflicts:
#	CHANGELOG.md
#	package-lock.json
#	src/chargebee.cjs.ts
#	src/types.d.ts
#	types/index.d.ts
@cb-alish cb-alish merged commit 4947e33 into master Jul 1, 2026
8 checks passed
@cb-alish cb-alish deleted the otel-integration branch July 1, 2026 06:44
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.

2 participants