Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
af6742b
fix(test-optimization): clear policies after settings failure (#9347)
BridgeAR Jul 16, 2026
712aefb
docs(orchestrion): refresh AST-rewriter reference for current engine …
BridgeAR Jul 16, 2026
d44fa82
test(agent): bind mock server to tracer address (#9400)
BridgeAR Jul 16, 2026
1f55304
fix(test-optimization): restore manual test context (#9356)
BridgeAR Jul 16, 2026
c4f9eec
perf(graphql): reuse path-string cache for collapsed fields (#9401)
BridgeAR Jul 16, 2026
4790e4b
feat(opentelemetry): correct Next.js root request span naming (#9119)
BridgeAR Jul 16, 2026
cc46262
test(coverage): warm source maps before process exit (#9330)
BridgeAR Jul 16, 2026
73845e5
fix(openfeature): support file-traced optional provider loading (#9324)
BridgeAR Jul 16, 2026
75ae111
test(runtime-metrics): validate CPU percentage against process usage …
BridgeAR Jul 16, 2026
4b42769
ci(workflows): add dd-octo-sts chainguard policy files (#8438)
lloeki Jul 16, 2026
072800d
test(electron): stabilize flaky CI (install/apt retries, IPC teardown…
rochdev Jul 16, 2026
eb3a449
ci(workflows): replace GITHUB_TOKEN with dd-octo-sts (#8432)
lloeki Jul 16, 2026
b563c53
chore(deps): bump the cloud-and-messaging group across 1 directory wi…
dependabot[bot] Jul 17, 2026
80f3493
chore(deps): bump the ai-and-llm group across 1 directory with 8 upda…
dependabot[bot] Jul 17, 2026
9f598bd
test(electron): give HTTP trace assertions the same timeout as IPC te…
rochdev Jul 17, 2026
15f28fc
feat(frontdoor-agw): Add implementation for Azure Frontdoor and App G…
TophrC-dd Jul 18, 2026
4ea3984
chore(deps): bump the cloud-and-messaging group across 1 directory wi…
dependabot[bot] Jul 20, 2026
63dfe20
test(appsec): deflake RASP SSRF "should not detect threat" express te…
CarlesDD Jul 20, 2026
b1bb0c7
feat(aiguard): evaluating anthropic calls with AI guard automatically…
IlyasShabi Jul 20, 2026
0936849
feat(ci): add Test Optimization validation runbook (#9323)
juan-fernandez Jul 20, 2026
8ce405c
test(ci): tolerate coverage preload in clean env tests (#9429)
juan-fernandez Jul 20, 2026
639f040
feat(ci): add code coverage report flags (#9418)
juan-fernandez Jul 20, 2026
c11ef28
test(config): isolate span sampling rules fixture (#9430)
juan-fernandez Jul 20, 2026
f0e7270
fix(nyc): preserve report generation failures (#9337)
BridgeAR Jul 20, 2026
1b64508
fix(graphql): preserve hook error overrides (#9435)
BridgeAR Jul 20, 2026
6cedb4c
feat(llmobs): control-plane HTTP client for experiments (#9158)
mehulsonowal Jul 20, 2026
11f9509
fix(cypress): support NODE_OPTIONS auto-instrumentation (#9371)
juan-fernandez Jul 20, 2026
44454df
test(openai): bump tested openai version with new cassettes (#9439)
sabrenner Jul 20, 2026
2d32fce
ci: update one-pipeline to 1.1.0 (#9438)
gh-worker-campaigns-3e9aa4[bot] Jul 20, 2026
d7cf21c
feat(llmobs): capture audio in messages and OpenAI chat completions (…
ZStriker19 Jul 20, 2026
2f09ea2
chore(deps): bump the cloud-and-messaging group across 1 directory wi…
dependabot[bot] Jul 21, 2026
a597b1d
chore(deps): bump the ai-and-llm group across 1 directory with 11 upd…
dependabot[bot] Jul 21, 2026
d063f8b
feat(playwright): upload failure screenshots (#9433)
juan-fernandez Jul 21, 2026
fceb0dd
fix(cucumber): support version 13.2 (#9456)
juan-fernandez Jul 21, 2026
a7d432a
chore(deps): bump import-in-the-middle to 3.3.2 (#9447)
BridgeAR Jul 21, 2026
dfd9e77
test(iast): drop redundant yarn install from sourcemap test (#9448)
BridgeAR Jul 21, 2026
a8f1d01
ci: run package scripts with npm (#9405)
BridgeAR Jul 21, 2026
0bc2b74
feat(express): surface repeated middleware next() as a span event (#9…
BridgeAR Jul 21, 2026
9d7153a
chore(deps): bump the npm_and_yarn group across 2 directories with 3 …
dependabot[bot] Jul 21, 2026
eea294d
chore(deps): bump the databases group across 1 directory with 18 upda…
dependabot[bot] Jul 21, 2026
59a9fae
chore(deps): bump brace-expansion (#9452)
dependabot[bot] Jul 21, 2026
35ca567
chore(deps): bump the test-versions group across 1 directory with 7 u…
dependabot[bot] Jul 21, 2026
45e9ecf
chore(deps): bump the web-frameworks group across 1 directory with 21…
dependabot[bot] Jul 21, 2026
5a499fd
feat(openfeature): support agentless feature flag configuration (#9397)
leoromanovsky Jul 21, 2026
538076e
fix(test-optimization): harden RUM correlation failures (#9408)
BridgeAR Jul 21, 2026
e991b97
feat(graphql): add field schema coordinates (#9346)
BridgeAR Jul 21, 2026
eb88cb2
docs(electron): replace README with internal-use-only notice on publi…
rochdev Jul 21, 2026
4675ec6
fix(config): apply pm2_env env vars before tracer init (#8863)
tlhunter Jul 21, 2026
245f614
fix(test-optimization): release removed replay probes (#9336)
BridgeAR Jul 21, 2026
6638d66
chore(deps): bump the test-versions group across 1 directory with 4 u…
dependabot[bot] Jul 21, 2026
3cfbd9b
test(init): guard fixture source logging (#9269)
crysmags Jul 21, 2026
6f5b886
chore(deps): bump @anthropic-ai/claude-agent-sdk (#9474)
dependabot[bot] Jul 22, 2026
fad4883
chore(deps): bump bullmq (#9471)
dependabot[bot] Jul 22, 2026
748d91b
fix(cypress): support numeric retries with ATR (#9484)
juan-fernandez Jul 22, 2026
2fd5f92
feat(appsec): report DD_APPSEC_AGENTIC_ONBOARDING in config telemetry…
christophe-papazian Jul 22, 2026
8e7dec1
feat(llmobs): support ai sdk v7 embedMany operations (#9466)
sabrenner Jul 22, 2026
3f0031a
fix(loader): defer instrumentation graph during preload (#9485)
BridgeAR Jul 22, 2026
8eebb8f
chore(deps): bump the vendor-minor-and-patch-dependencies group acros…
dependabot[bot] Jul 22, 2026
3c9a266
test(config): assert DD_APPSEC_AGENTIC_ONBOARDING in v5 appsec config…
christophe-papazian Jul 22, 2026
6d06800
chore(deps-dev): bump c8 from 11.0.0 to 12.0.0 (#9476)
dependabot[bot] Jul 22, 2026
5731bf3
chore(deps): bump fast-uri from 3.1.2 to 3.1.4 in /benchmark/sirun/st…
dependabot[bot] Jul 22, 2026
0232971
fix(ai): fix infinite recursion when using `BedrockChatLanguageModel`…
sabrenner Jul 22, 2026
0857bab
fix(instrumentation): preserve ESM export aliases (#9436)
BridgeAR Jul 22, 2026
a24aad0
fix(standalone): stamp _dd.apm.enabled on every exported chunk (#9483)
IlyasShabi Jul 22, 2026
e17c55d
v5.116.0
BridgeAR Jul 22, 2026
2518db2
Update LICENSE-3rdparty.csv
dd-octo-sts[bot] 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