Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
3933080
fix(test-optimization): clear policies after settings failure (#9347)
BridgeAR Jul 16, 2026
5cb1e3c
docs(orchestrion): refresh AST-rewriter reference for current engine …
BridgeAR Jul 16, 2026
2e8f8a5
test(agent): bind mock server to tracer address (#9400)
BridgeAR Jul 16, 2026
04bb2f8
fix(test-optimization): restore manual test context (#9356)
BridgeAR Jul 16, 2026
7663aca
perf(graphql): reuse path-string cache for collapsed fields (#9401)
BridgeAR Jul 16, 2026
a65d763
feat(opentelemetry): correct Next.js root request span naming (#9119)
BridgeAR Jul 16, 2026
c503a17
test(coverage): warm source maps before process exit (#9330)
BridgeAR Jul 16, 2026
ef1b124
fix(openfeature): support file-traced optional provider loading (#9324)
BridgeAR Jul 16, 2026
ecac977
test(runtime-metrics): validate CPU percentage against process usage …
BridgeAR Jul 16, 2026
27f069f
ci(workflows): add dd-octo-sts chainguard policy files (#8438)
lloeki Jul 16, 2026
6e8c3d3
test(electron): stabilize flaky CI (install/apt retries, IPC teardown…
rochdev Jul 16, 2026
0e29e72
ci(workflows): replace GITHUB_TOKEN with dd-octo-sts (#8432)
lloeki Jul 16, 2026
c41327e
chore(deps): bump the cloud-and-messaging group across 1 directory wi…
dependabot[bot] Jul 17, 2026
8c97269
chore(deps): bump the ai-and-llm group across 1 directory with 8 upda…
dependabot[bot] Jul 17, 2026
ae9993f
test(electron): give HTTP trace assertions the same timeout as IPC te…
rochdev Jul 17, 2026
6dd385b
feat(frontdoor-agw): Add implementation for Azure Frontdoor and App G…
TophrC-dd Jul 18, 2026
9010665
chore(deps): bump the cloud-and-messaging group across 1 directory wi…
dependabot[bot] Jul 20, 2026
d318db0
test(appsec): deflake RASP SSRF "should not detect threat" express te…
CarlesDD Jul 20, 2026
0182b3f
feat(aiguard): evaluating anthropic calls with AI guard automatically…
IlyasShabi Jul 20, 2026
f24fb88
feat(ci): add Test Optimization validation runbook (#9323)
juan-fernandez Jul 20, 2026
5203d36
test(ci): tolerate coverage preload in clean env tests (#9429)
juan-fernandez Jul 20, 2026
943f787
feat(ci): add code coverage report flags (#9418)
juan-fernandez Jul 20, 2026
5070987
test(config): isolate span sampling rules fixture (#9430)
juan-fernandez Jul 20, 2026
3ea431c
fix(nyc): preserve report generation failures (#9337)
BridgeAR Jul 20, 2026
912f3cd
fix(graphql): preserve hook error overrides (#9435)
BridgeAR Jul 20, 2026
e6e8b5d
feat(llmobs): control-plane HTTP client for experiments (#9158)
mehulsonowal Jul 20, 2026
8416198
fix(cypress): support NODE_OPTIONS auto-instrumentation (#9371)
juan-fernandez Jul 20, 2026
92eb862
test(openai): bump tested openai version with new cassettes (#9439)
sabrenner Jul 20, 2026
1194dc2
ci: update one-pipeline to 1.1.0 (#9438)
gh-worker-campaigns-3e9aa4[bot] Jul 20, 2026
6769a0c
feat(llmobs): capture audio in messages and OpenAI chat completions (…
ZStriker19 Jul 20, 2026
a2d75d7
chore(deps): bump the cloud-and-messaging group across 1 directory wi…
dependabot[bot] Jul 21, 2026
fd22520
chore(deps): bump the ai-and-llm group across 1 directory with 11 upd…
dependabot[bot] Jul 21, 2026
358426b
feat(playwright): upload failure screenshots (#9433)
juan-fernandez Jul 21, 2026
a9ee3eb
fix(cucumber): support version 13.2 (#9456)
juan-fernandez Jul 21, 2026
98c2134
chore(deps): bump import-in-the-middle to 3.3.2 (#9447)
BridgeAR Jul 21, 2026
8a9d490
test(iast): drop redundant yarn install from sourcemap test (#9448)
BridgeAR Jul 21, 2026
e5fd236
ci: run package scripts with npm (#9405)
BridgeAR Jul 21, 2026
911c738
feat(express): surface repeated middleware next() as a span event (#9…
BridgeAR Jul 21, 2026
7d623c6
chore(deps): bump the npm_and_yarn group across 2 directories with 3 …
dependabot[bot] Jul 21, 2026
ff9e3f0
chore(deps): bump the databases group across 1 directory with 18 upda…
dependabot[bot] Jul 21, 2026
313e706
chore(deps): bump brace-expansion (#9452)
dependabot[bot] Jul 21, 2026
58887c3
chore(deps): bump the test-versions group across 1 directory with 7 u…
dependabot[bot] Jul 21, 2026
2aafec9
chore(deps): bump the web-frameworks group across 1 directory with 21…
dependabot[bot] Jul 21, 2026
6bdd727
feat(openfeature): support agentless feature flag configuration (#9397)
leoromanovsky Jul 21, 2026
f4bcc2f
fix(test-optimization): harden RUM correlation failures (#9408)
BridgeAR Jul 21, 2026
f0d7a68
feat(graphql): add field schema coordinates (#9346)
BridgeAR Jul 21, 2026
b683463
docs(electron): replace README with internal-use-only notice on publi…
rochdev Jul 21, 2026
6722675
fix(config): apply pm2_env env vars before tracer init (#8863)
tlhunter Jul 21, 2026
e0d3400
fix(test-optimization): release removed replay probes (#9336)
BridgeAR Jul 21, 2026
c5e4a3c
chore(deps): bump the test-versions group across 1 directory with 4 u…
dependabot[bot] Jul 21, 2026
258d01e
test(init): guard fixture source logging (#9269)
crysmags Jul 21, 2026
bff3b0a
chore(deps): bump @anthropic-ai/claude-agent-sdk (#9474)
dependabot[bot] Jul 22, 2026
c4fb0b0
chore(deps): bump bullmq (#9471)
dependabot[bot] Jul 22, 2026
aa47338
fix(cypress): support numeric retries with ATR (#9484)
juan-fernandez Jul 22, 2026
b95c6ea
feat(appsec): report DD_APPSEC_AGENTIC_ONBOARDING in config telemetry…
christophe-papazian Jul 22, 2026
05058d5
feat(llmobs): support ai sdk v7 embedMany operations (#9466)
sabrenner Jul 22, 2026
a81f198
fix(loader): defer instrumentation graph during preload (#9485)
BridgeAR Jul 22, 2026
36ec97f
chore(deps): bump the vendor-minor-and-patch-dependencies group acros…
dependabot[bot] Jul 22, 2026
08c399d
test(config): assert DD_APPSEC_AGENTIC_ONBOARDING in v5 appsec config…
christophe-papazian Jul 22, 2026
0daf919
chore(deps-dev): bump c8 from 11.0.0 to 12.0.0 (#9476)
dependabot[bot] Jul 22, 2026
7861b3f
chore(deps): bump fast-uri from 3.1.2 to 3.1.4 in /benchmark/sirun/st…
dependabot[bot] Jul 22, 2026
50dbd17
fix(ai): fix infinite recursion when using `BedrockChatLanguageModel`…
sabrenner Jul 22, 2026
4b3a3b6
fix(instrumentation): preserve ESM export aliases (#9436)
BridgeAR Jul 22, 2026
4e329b3
fix(standalone): stamp _dd.apm.enabled on every exported chunk (#9483)
IlyasShabi Jul 22, 2026
22dfb6b
test(couchbase,kafkajs): wait for client readiness (#9455)
BridgeAR Jul 22, 2026
7678b16
chore: update eslint unicorn plugin to v65 (#8838)
BridgeAR Jul 22, 2026
6467519
chore(deps-dev): bump graphql from 16.14.2 to 17.0.2 (#9328)
dependabot[bot] Jul 22, 2026
a90e54e
revert: feat(aiguard): remove Anthropic auto-instrumentation (#9495)
BridgeAR Jul 22, 2026
10d5625
v5.116.0
BridgeAR Jul 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
49 changes: 29 additions & 20 deletions .agents/skills/apm-integrations/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ dd-trace-js provides automatic tracing for 100+ third-party libraries. Each inte

## Architecture

```
```text
┌──────────────────────────┐ diagnostic channels ┌─────────────────────────┐
│ Instrumentation │ ──────────────────────────▶ │ Plugin │
│ datadog-instrumentations │ apm:<name>:<op>:start │ datadog-plugin-<name> │
Expand All @@ -26,6 +26,9 @@ dd-trace-js provides automatic tracing for 100+ third-party libraries. Each inte
└──────────────────────────┘ └─────────────────────────┘
```

`finish` above is the legacy manual-channel completion event. `tracingChannel`
and Orchestrion use `end` / `asyncEnd`, as described below.

**Instrumentation** (`packages/datadog-instrumentations/src/`):
Hooks into a library's internals and publishes events with context data to named diagnostic channels. Has zero knowledge of tracing — only emits events.

Expand All @@ -36,7 +39,7 @@ Both layers are always needed for a new integration.

## Instrumentation: Orchestrion First

**Orchestrion is the required default for all new instrumentations.** It is an AST rewriter that automatically wraps methods via JSON configuration, with correct CJS and ESM handling built in. Orchestrion handles ESM code far more reliably than traditional shimmer-based wrapping, which struggles with ESM's static module structure.
**Orchestrion is the required default when the work exists as a source function.** It rewrites matched CJS/ESM source from JavaScript config, avoiding runtime monkey-patching and ESM's static-binding traps. Start there for top-level declarations, class/object methods, named expressions, and assignments to named receivers. Use shimmer only when the work is created entirely at runtime or the required argument/result mutation cannot happen from Orchestrion's subscriber lifecycle.

Config lives in `packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/<name>.js`. See [Orchestrion Reference](references/orchestrion.md) for the full config format and examples.

Expand All @@ -45,16 +48,16 @@ Config lives in `packages/datadog-instrumentations/src/helpers/rewriter/instrume
Shimmer (`addHook` + `shimmer.wrap`) should **only** be used when orchestrion cannot handle the pattern. When using shimmer, **always include a code comment explaining why orchestrion is not viable.** Valid reasons:

- **Dynamic method interception** — methods created at runtime or on prototype chains that orchestrion's static analysis cannot reach
- **Factory patterns** — wrapping return values of factory functions
- **Argument modification** — instrumentations that need to mutate arguments before the original call
- **Factory results that cannot be substituted** — `end` can replace synchronous results and `asyncEnd` can replace native-Promise results; shimmer remains necessary for Promise subclasses, userland thenables, or APIs that require the original result's identity
- **Pre-lifecycle argument modification** — arguments must be changed before Orchestrion's `bindStart` / subscribers can run

If none of these apply, use orchestrion. For shimmer patterns, refer to existing shimmer-based instrumentations in the codebase (e.g., `packages/datadog-instrumentations/src/pg.js`). Always try to use Orchestrion when beginning a new integration!

## Plugin Base Classes

Plugins extend a base class matching the library type. The base class provides automatic channel subscriptions, span lifecycle, and type-specific tags.

```
```text
Plugin
├── CompositePlugin — Multiple sub-plugins (produce + consume)
├── LogPlugin — Log correlation injection (no spans)
Expand Down Expand Up @@ -86,7 +89,7 @@ Two ways to fetch the source locally:
git clone --depth 1 --branch v<x.y.z> https://github.com/<org>/<repo>.git /tmp/<lib>-versions/v<x.y.z>
```

2. **`npm pack`** when the published runtime artifact is what matters:
1. **`npm pack`** when the published runtime artifact is what matters:

```bash
cd /tmp/<lib>-versions && npm pack <lib>@<x.y.z>
Expand All @@ -98,6 +101,7 @@ Read the file the wrap hooks, the base classes the hooked methods inherit from,
## Key Concepts

### The `ctx` Object

Context flows from instrumentation to plugin:

- **Orchestrion**: automatically provides `ctx.arguments` (method args) and `ctx.self` (instance)
Expand All @@ -106,18 +110,21 @@ Context flows from instrumentation to plugin:
- **On completion**: `ctx.result` or `ctx.error`

### Channel Event Lifecycle

- `runStores()` for **start** events — establishes async context (always)
- `publish()` for **finish/error** events — notification only
- `hasSubscribers` guard — skip instrumentation when no plugin listens (performance fast path)
- `publish()` for **completion/error** events — notification only
- `hasSubscribers` guard — skip publish/subscriber work when no plugin listens; orchestrion still pays wrapper setup in current templates
- When shimmer is necessary, prefer `tracingChannel` (from `dc-polyfill`) over manual channels — it provides `start/end/asyncStart/asyncEnd/error` events automatically

### Channel Prefix Patterns

- **Orchestrion**: `tracing:orchestrion:<npm-package>:<channelName>` (set via `static prefix`)
- **Shimmer + `tracingChannel`** (preferred): `tracing:apm:<name>:<operation>` (set via `static prefix`)
- **Shimmer + manual channels** (legacy): `apm:{id}:{operation}` (default, no `static prefix` needed)

### `bindStart` / `bindFinish`
Primary plugin methods. Base classes handle most lifecycle; often only `bindStart` is needed to create the span and set tags.
### `bindStart` and completion handlers

Use `bindStart` to create the span and return its store. Finish in the event the instrumentation emits: usually `end` for synchronous work, `asyncEnd` for promises/callbacks, and `finish` only for legacy instrumentations that publish it. Orchestrion does not publish `finish`.

### Subscriber Cardinality (`channel.publish` position)

Expand All @@ -133,7 +140,7 @@ Before adding or moving a gate in front of a publish, grep the repo for the chan
**Always read 1-2 references of the same type before writing or modifying code.**

| Library Type | Plugin | Instrumentation | Base Class |
|---|---|---|---|
| --- | --- | --- | --- |
| Database | `datadog-plugin-pg` | `src/pg.js` | `DatabasePlugin` |
| Cache | `datadog-plugin-redis` | `src/redis.js` | `CachePlugin` |
| HTTP client | `datadog-plugin-fetch` | `src/fetch.js` | `HttpClientPlugin` (extends `ClientPlugin`) |
Expand Down Expand Up @@ -161,21 +168,23 @@ Follow these steps when creating or modifying an integration:
4. **Register** — Add entries in `packages/dd-trace/src/plugins/index.js`, `index.d.ts`, `docs/test.ts`, `docs/API.md`, and `.github/workflows/apm-integrations.yml`.
5. **Write tests** — Add unit tests and ESM integration tests. See [Testing](references/testing.md) for templates.
6. **Run tests** — Validate with:
```bash
# Run plugin tests (preferred CI command — handles yarn services automatically)
PLUGINS="<name>" npm run test:plugins:ci

# If the plugin needs external services (databases, message brokers, etc.),
# check docker-compose.yml for available service names, then:
docker compose up -d <service>
PLUGINS="<name>" npm run test:plugins:ci
```
```bash
# Run plugin tests (preferred CI command — handles yarn services automatically)
PLUGINS="<name>" npm run test:plugins:ci

# If the plugin needs external services (databases, message brokers, etc.),
# check docker-compose.yml for available service names, then:
docker compose up -d <service>
PLUGINS="<name>" npm run test:plugins:ci
```

7. **Verify** — Confirm all tests pass before marking work as complete.

## Reference Files

- **[New Integration Guide](references/new-integration-guide.md)** — Step-by-step guide and checklist for creating a new integration end-to-end
- **[Orchestrion Reference](references/orchestrion.md)** — JSON config format, channel naming, function kinds, plugin subscription
- **[Orchestrion Reference](references/orchestrion.md)** — JavaScript config format, channel naming, function kinds, plugin subscription
- **[Plugin Patterns](references/plugin-patterns.md)** — `startSpan()` API, `ctx` object details, `CompositePlugin`, channel subscriptions, code style
- **[Testing](references/testing.md)** — Unit test and ESM integration test templates
- **[Reference Plugins](references/reference-plugins.md)** — All plugins organized by base class
190 changes: 0 additions & 190 deletions .agents/skills/apm-integrations/references/async-iterator-pattern.md

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ Step-by-step checklist for creating a new dd-trace-js integration from scratch.

### Orchestrion (Default)

Orchestrion requires three files:
Orchestrion requires four files:

**1. JSON config** — `packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/<name>.js`:
**1. JavaScript config** — `packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/<name>.js`:

```javascript
module.exports = [{
Expand All @@ -26,7 +26,7 @@ module.exports = [{
functionQuery: {
methodName: 'query',
className: 'Client',
kind: 'Async' // Async | Callback | Sync
kind: 'Async' // Async | Auto | Callback | Sync
},
channelName: 'Client_query'
}]
Expand All @@ -48,7 +48,14 @@ for (const hook of getHooks('<npm-package>')) {

`getHooks` reads the orchestrion config and generates `addHook` entries automatically. This file is needed so the module hooks are registered for the rewriter to process.

**3. hooks.js entry** — (see Register in hooks.js below)
**3. Config registry entry** —
`packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js`:

```javascript
...require('./<name>'),
```

**4. hooks.js entry** — (see Register in hooks.js below)

See [Orchestrion Reference](orchestrion.md) for the full config schema, ESQuery support, and channel naming.

Expand Down Expand Up @@ -262,7 +269,7 @@ Add to `.github/workflows/apm-integrations.yml`:
with:
version: ${{ matrix.node-version }}
- uses: ./.github/actions/install
- run: yarn test:plugins:ci
- run: npm run test:plugins:ci
strategy:
matrix:
node-version: [18, 22]
Expand All @@ -284,7 +291,8 @@ PLUGINS="<name>" npm run test:plugins:ci

## Checklist

- [ ] Instrumentation created (orchestrion JSON config + hooks file, or shimmer with justification comment)
- [ ] Instrumentation created (orchestrion JavaScript config + hooks file, or shimmer with justification comment)
- [ ] Orchestrion config registered in `rewriter/instrumentations/index.js` (orchestrion only)
- [ ] Registered in hooks.js (required for both orchestrion and shimmer paths)
- [ ] Plugin created with correct base class
- [ ] Plugin registered in `packages/dd-trace/src/plugins/index.js`
Expand Down
Loading
Loading