Add optional OpenTelemetry telemetry adapter for API calls#123
Add optional OpenTelemetry telemetry adapter for API calls#123cb-karthikp wants to merge 3 commits into
Conversation
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
There was a problem hiding this comment.
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
| File | Types | Count | ||||||
|---|---|---|---|---|---|---|---|---|
|
| Line | Type | Preview |
|---|---|---|
| — | PII: Email Address | dx@chargebee.com |
src/telemetry/index.ts
| Line | Type | Preview |
|---|---|---|
| — | PII: Email Address | dx@chargebee.com |
src/telemetry/types.ts
| Line | Type | Preview |
|---|---|---|
| — | PII: Email Address | dx@chargebee.com |
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
telemetryAdapteroption to the top-levelChargebeeconfiguration and environment, allowing users to plug in custom telemetry (e.g. OpenTelemetry) without bundling any telemetry libraries into the SDK. - Introduces a
TelemetryAdapterinterface 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 viaTelemetryAttributeKeysfor consistent usage across tools and SDKs. - Updates
RequestWrapperto 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
TelemetryAttributeKeysvia both CJS and ESM entrypoints and adds type declarations intypes/index.d.tsto 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
resourcenames are correctly set onapiCall; 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. |
…when unconfigured
There was a problem hiding this comment.
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
| File | Types | Count | ||||||
|---|---|---|---|---|---|---|---|---|
|
| Line | Type | Preview |
|---|---|---|
| — | PII: Email Address | dx@chargebee.com |
src/telemetry/index.ts
| Line | Type | Preview |
|---|---|---|
| — | PII: Email Address | dx@chargebee.com |
src/telemetry/types.ts
| Line | Type | Preview |
|---|---|---|
| — | PII: Email Address | dx@chargebee.com |
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
TelemetryAdapterinterface (plusNoOpTelemetryAdapter) and helper functions to build telemetry span names, attributes, contexts, and results for HTTP requests. - Integrates telemetry into
RequestWrapper.request()by:- Preserving the
telemetryAdapterreference when cloningenv. - Building the full request URL once via a new
_buildRequestUrlhelper. - Invoking
telemetryAdapter.onRequestStartbefore the request to collect context and headers, andonRequestEndafter 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.
- Preserving the
- Adds utility functions to extract HTTP status codes and standardised error metadata from errors for telemetry reporting.
- Exports telemetry-related types and
TelemetryAttributeKeysfrom 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.
requestUrlis now built once perrequest()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.
resolveChargebeeApiVersionderives the API version fromenv.apiPathwith a default ofv2; 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. |
There was a problem hiding this comment.
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
| File | Types | Count | ||||||
|---|---|---|---|---|---|---|---|---|
|
| Line | Type | Preview |
|---|---|---|
| — | PII: Email Address | dx@chargebee.com |
src/telemetry/index.ts
| Line | Type | Preview |
|---|---|---|
| — | PII: Email Address | dx@chargebee.com |
src/telemetry/types.ts
| Line | Type | Preview |
|---|---|---|
| — | PII: Email Address | dx@chargebee.com |
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 andchargebee.*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
OtelTelemetryAdapterimplementation 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. |
No description provided.