Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
45b0d93
chore: prep 2.1.0 (#468)
sjvans Aug 7, 2026
3e9d316
ci: run on pull requests to develop (#469)
sjvans Aug 7, 2026
29d0028
fix: trace Cloud SDK outbound requests (getter-only exports) (#451)
sjvans Aug 7, 2026
b439634
ci: target develop for dependabot updates (#470)
sjvans Aug 10, 2026
7790a99
feat: trace queue worker transactions + structured span test infrastr…
sjvans Aug 10, 2026
fdbd1bb
chore: migrate test runner from jest to vitest (#474)
sjvans Aug 10, 2026
205e449
chore: adopt oxfmt for code formatting (#476)
sjvans Aug 10, 2026
d8f3dd1
test: capture outbox+console metrics via in-memory reader & unit-test…
sjvans Aug 11, 2026
eb28f9b
chore(deps-dev): bump the OTLP dev-dependency group to 0.221 (pin sdk…
sjvans Aug 13, 2026
8f8485d
test: run full suite on HANA + fix two HANA span/metric bugs (#477 §2…
sjvans Aug 17, 2026
bfb8bcd
chore: release workflow (#484)
sjvans Aug 17, 2026
0b6211e
fix(logging): guard cds.log.format interception against re-entrancy; …
sjvans Aug 17, 2026
0c28b57
test: convert remote/span-name tracing tests to in-memory span export…
sjvans Aug 17, 2026
13e2c7e
test: enable HTTP instrumentation in tests; assert incoming SERVER sp…
sjvans Aug 20, 2026
65157bc
test: centralize duplicated test helpers into test-utils (#488) (#492)
sjvans Aug 20, 2026
f125e34
test: configure via .cdsrc.json profiles instead of process.env.cds_*…
sjvans Aug 20, 2026
057c829
docs: add TESTING.md; trim duplicated test comments to pointers (#487…
sjvans Aug 21, 2026
33b07ef
chore(deps-dev): bump the dev-dependencies group across 1 directory w…
dependabot[bot] Aug 31, 2026
99a6e2d
chore: add CODEOWNERS to develop (#497)
sjvans Aug 31, 2026
2db212d
Merge branch 'main' into develop
sjvans Aug 31, 2026
48c9934
feat: configurable span processor via telemetry.tracing.processor (#498)
sjvans Sep 1, 2026
abbed34
test: gate sqlite queue-worker tracing skips on @sap/cds >= 10.1 (cds…
sjvans Sep 7, 2026
429dd18
Add telemetry-to-caas kind for CaaS (Collector as a Service) support …
vkozyura Sep 16, 2026
1b1bf66
chore(deps-dev): bump the dev-dependencies group across 1 directory w…
dependabot[bot] Sep 16, 2026
f5c6a4b
chore(deps): bump the prod-dependencies group across 1 directory with…
dependabot[bot] Sep 16, 2026
e677c3e
feat: add tenant id and correlation id to logs (#506)
SirSimon04 Sep 16, 2026
16eaa41
refactor: modularize lib/utils and decouple mTLS cert sourcing (#508)
sjvans Sep 17, 2026
142c59b
fix(tracing): don't build a span processor without an exporter on the…
sjvans Sep 17, 2026
38326ca
Merge branch 'main' into develop
sjvans Sep 17, 2026
3ac0409
feat(tracing): support Dynatrace OneAgent in-process trace capture (#…
sjvans Sep 18, 2026
f7c24e5
docs: add changelog entry for tenant id log attribute (#513)
sjvans Sep 18, 2026
e50079c
docs: add SAP Cloud ALM (beta) section, carve out telemetry-to-caas (…
sjvans Sep 22, 2026
be2c6ae
final polishing (#517)
sjvans Sep 25, 2026
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
2 changes: 2 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ version: 2
updates:
- package-ecosystem: 'npm' # See documentation for possible values
directory: '/' # Location of package manifests
target-branch: 'develop'
versioning-strategy: increase-if-necessary
schedule:
interval: 'weekly'
Expand All @@ -26,6 +27,7 @@ updates:

- package-ecosystem: 'github-actions'
directory: '/'
target-branch: 'develop'
schedule:
interval: 'weekly'
cooldown:
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ permissions:
on:
workflow_dispatch:
push:
branches: [main]
branches: [main, develop]
pull_request:
branches: [main]
branches: [main, develop]

env:
NPM_CONFIG_IGNORE_SCRIPTS: true
Expand All @@ -20,6 +20,7 @@ jobs:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- run: npm i
- run: npm run lint
- run: npm run format:check
test:
runs-on: ubuntu-latest
strategy:
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ jobs:
node-version: 24
registry-url: https://registry.npmjs.org/
- name: run tests
# REVISIT: remove "npm explore better-sqlite3 -- npm run install" with cds^10
run: |
npm i -g @sap/cds-dk
npm i
Expand Down
21 changes: 21 additions & 0 deletions .oxfmtrc.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"$schema": "./node_modules/oxfmt/configuration_schema.json",
"arrowParens": "avoid",
"bracketSpacing": true,
"embeddedLanguageFormatting": "auto",
"htmlWhitespaceSensitivity": "css",
"insertPragma": false,
"jsxSingleQuote": false,
"printWidth": 120,
"proseWrap": "preserve",
"quoteProps": "as-needed",
"requirePragma": false,
"semi": false,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "none",
"useTabs": false,
"vueIndentScriptAndStyle": false,
"sortPackageJson": false,
"ignorePatterns": ["*.md", "node_modules/**", "package-lock.json"]
}
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,25 @@ All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
The format is based on [Keep a Changelog](http://keepachangelog.com/).

## Version 2.1.0 - tbd

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Suggested change
## Version 2.1.0 - tbd
## Version 2.1.0 - 2026-09-XX


### Added

- Support for `telemetry-to-caas` kind for CaaS (Collector as a Service). By default, mTLS certificates are provisioned and rotated automatically via the Zero Trust Identity (ZTI) sidecar; alternatively, mTLS certificates can be provided manually via `x509` credentials.
- Queue worker transactions are traced as coherent `<service> - tx` spans under the `cds.spawn - run task` root, instead of orphaned per-call spans
- The span processor is now configurable via `cds.requires.telemetry.tracing.processor = { kind, config? }` (`BatchSpanProcessor` or `SimpleSpanProcessor`); defaults to `BatchSpanProcessor`, and to `SimpleSpanProcessor` in the `[development]` profile
- Exported log records now carry the tenant as attribute `sap.tenancy.tenant_id` (when available from `cds.context`), aligning log metadata with traces and metrics

### Changed

### Fixed
Comment thread
sjvans marked this conversation as resolved.

- No longer crashes on startup when Dynatrace OneAgent is active (`DT_NODE_PRELOAD_OPTIONS` set, kind `*-to-dynatrace`, no `@opentelemetry/exporter-trace-otlp-proto` dependency): the tracing factory no longer builds a tracer provider with an undefined span processor (which crashed on the first span in `MultiSpanProcessor.onStart`). On this path it now registers a recording tracer provider without an exporter, so the CDS spans exist for OneAgent's in-process OpenTelemetry capture to pick up (no export by us, no duplicates)
- Logging no longer recurses through `@opentelemetry/sdk-logs` 0.221's export path: the log-processor construction now adapts to the installed sdk-logs version (0.221+ takes an `{ exporter }` options object, earlier versions the positional exporter), and a re-entrancy guard was added to the `cds.log.format` interception
- Cloud SDK outbound requests are traced again (patch getter-only `@sap-cloud-sdk/http-client` exports via `Object.defineProperty`)
- Raw SQL no longer leaks into HANA INSERT `prepare` span names (now uses operation + table, matching SELECT)
- Queue `*_storage_time_in_seconds` metrics are now correct on HANA (timezone-naive `min`/`max` timestamp aggregates were parsed as local time, skewing the values by the machine's UTC offset)

## Version 2.0.1 - 2026-07-03

### Fixed
Expand Down
46 changes: 34 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ Documentation can be found at [cap.cloud.sap](https://cap.cloud.sap/docs) and [o
- [`telemetry-to-cloud-logging`](#telemetry-to-cloud-logging)
- [`telemetry-to-jaeger`](#telemetry-to-jaeger)
- [`telemetry-to-otlp`](#telemetry-to-otlp)
- [Running with SAP Cloud ALM (beta)](#running-with-sap-cloud-alm-beta)
- [Detailed Configuration Options](#detailed-configuration-options)
- [Configuration Pass Through](#configuration-pass-through)
- [Resource Attributes](#resource-attributes)
- [Instrumentations](#instrumentations)
- [Sampler](#sampler)
- [Propagators](#propagators)
- [Span Processor](#span-processor)
- [Exporters](#exporters)
- [High Resolution Timestamps (beta)](#high-resolution-timestamps-beta)
- [Environment Variables](#environment-variables)
Expand Down Expand Up @@ -94,8 +96,7 @@ Example trace in Dynatrace:

An example trace printed to the console can be found in [`telemetry-to-console`](#telemetry-to-console).

In environments where Dynatrace OneAgent is installed (e.g., SAP BTP CF), no OpenTelemetry exporter is needed to transport the traces to Dynatrace.
`@cap-js/telemetry` recognizes this and ignores any exporter config if the predefined kind [`telemetry-to-dynatrace`](#telemetry-to-dynatrace) is used.
To export traces to Dynatrace, use the predefined kind [`telemetry-to-dynatrace`](#telemetry-to-dynatrace). If [Dynatrace OneAgent](#dynatrace-oneagent) is present, the CDS spans can alternatively be captured in-process by OneAgent, without the OTLP trace exporter.


### Metrics
Expand Down Expand Up @@ -219,7 +220,7 @@ Hence, a Dynatrace instance is required and the app must be bound to that Dynatr
Use via `cds.requires.telemetry.kind = 'to-dynatrace'`.

Required additional dependencies:
- `@opentelemetry/exporter-trace-otlp-proto` (optional, see [Leveraging Dynatrace OneAgent](#leveraging-dynatrace-oneagent))
- `@opentelemetry/exporter-trace-otlp-proto`
- `@opentelemetry/exporter-metrics-otlp-proto`

The necessary scopes for exporting traces (`openTelemetryTrace.ingest`) and metrics (`metrics.ingest`) are not part of the standard `apitoken` and must be requested.
Expand Down Expand Up @@ -248,16 +249,11 @@ In Dynatrace itself, you need to ensure that the following two features are enab
- From the Dynatrace menu, go to Settings > Server-side service monitoring > Deep monitoring > Distributed tracing.
- Turn on Send W3C Trace Context HTTP headers.

#### Leveraging Dynatrace OneAgent

If [Dynatrace OneAgent](https://www.dynatrace.com/platform/oneagent) is present, for example on SAP BTP CF, it will collect and transport the traces created by `@cap-js/telemetry` automatically.
(Your app still needs to be bound to a Dynatrace instance, of course. However, `@dynatrace/oneagent-sdk` is not required.)
Hence, additional dependency `@opentelemetry/exporter-trace-otlp-proto` and scope `openTelemetryTrace.ingest` are not required.
#### Dynatrace OneAgent

Please note, however, that Dynatrace only exports traces triggered by incoming HTTP requests.
That is, traces for background tasks started by `cds.spawn`, for example, would not be exported.
If [Dynatrace OneAgent](https://www.dynatrace.com/platform/oneagent) is present, for example on SAP BTP CF, and the OTLP trace exporter is *not* installed, `@cap-js/telemetry` does not export traces itself. Instead it registers a recording tracer provider without an exporter and relies on OneAgent's in-process OpenTelemetry capture to pick up the CDS spans — no OTLP export, no duplicate spans.

If dependency `@opentelemetry/exporter-trace-otlp-proto` is present anyway, `@cap-js/telemetry` will export the traces via OpenTelemetry as well.
Installing the OTLP trace exporter (`@opentelemetry/exporter-trace-otlp-proto`, see [Required additional dependencies](#telemetry-to-dynatrace) above) takes precedence: `@cap-js/telemetry` then exports the spans itself instead of relying on in-process capture, and the `openTelemetryTrace.ingest` scope must be granted.


### `telemetry-to-cloud-logging`
Expand All @@ -283,12 +279,13 @@ In order to receive OpenTelemetry credentials in the binding to the SAP Cloud Lo

If you are binding your app to SAP Cloud Logging via a [user-provided service instance](https://docs.cloudfoundry.org/devguide/services/user-provided.html), make sure that it has the tag `Cloud Logging`.

> Tip: To add the required tag to an existing user-provided service, you can use:
> Tip: To add the required tag to an existing user-provided service, you can use:
> ```
> cf update-user-provided-service {service-name} -t "Cloud Logging"
> ```
> For detailed information about binding resolution in CAP, consult [`cds.connect()` → Service Bindings](https://cap.cloud.sap/docs/node.js/cds-connect#service-bindings).


### `telemetry-to-jaeger`

Exports traces to Jaeger.
Expand Down Expand Up @@ -340,6 +337,16 @@ Please note that `@cap-js/telemetry` does not validate the configuration via env



## Running with SAP Cloud ALM (beta)

When your application already runs the SAP Cloud ALM agent extension (`@sap/xotel-agent-ext-js`), that agent owns the OpenTelemetry SDK. `@cap-js/telemetry` detects it and, instead of setting up its own tracer provider, contributes its CDS spans to the agent's tracing pipeline (as a delegate on the agent's span processor). Both run on a single, shared OpenTelemetry SDK instance, so the CDS spans appear alongside the data the agent already collects — no second SDK, no duplicate setup.

This requires `@sap/xotel-agent-ext-js` 2.0.4 or later. For enabling and onboarding the SAP Cloud ALM agent itself, refer to the [SAP Cloud ALM documentation](https://support.sap.com/en/alm/sap-cloud-alm/operations/expert-portal/data-collection-infrastructure.html).

> Note: this coexistence is currently in beta. Running the SAP Cloud ALM agent together with Dynatrace OneAgent is not supported.



## Detailed Configuration Options


Expand Down Expand Up @@ -428,6 +435,21 @@ Default:
```


### Span Processor

Configure via `cds.requires.telemetry.tracing.processor = { kind, config? }`, where `kind` is one of `BatchSpanProcessor` or `SimpleSpanProcessor` and `config` is passed through to the processor's constructor.

Default: `BatchSpanProcessor`, except in the `[development]` profile, which uses `SimpleSpanProcessor` so spans are exported immediately.
```json
{
"kind": "BatchSpanProcessor"
}
```

> [!NOTE]
> The `ConsoleSpanExporter` (the default `telemetry-to-console` exporter) has only been tested with the `SimpleSpanProcessor`. Combining it with the `BatchSpanProcessor` is not recommended.


### Exporters

Configure via:
Expand Down
Loading
Loading