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
834a908
fix(test-optimization): clear policies after settings failure (#9347)
BridgeAR Jul 16, 2026
54ac21a
docs(orchestrion): refresh AST-rewriter reference for current engine …
BridgeAR Jul 16, 2026
f9ff528
test(agent): bind mock server to tracer address (#9400)
BridgeAR Jul 16, 2026
fc6c399
fix(test-optimization): restore manual test context (#9356)
BridgeAR Jul 16, 2026
ba86323
perf(graphql): reuse path-string cache for collapsed fields (#9401)
BridgeAR Jul 16, 2026
63d3e0a
feat(opentelemetry): correct Next.js root request span naming (#9119)
BridgeAR Jul 16, 2026
56b9992
test(coverage): warm source maps before process exit (#9330)
BridgeAR Jul 16, 2026
195a7c2
fix(openfeature): support file-traced optional provider loading (#9324)
BridgeAR Jul 16, 2026
83dd549
test(runtime-metrics): validate CPU percentage against process usage …
BridgeAR Jul 16, 2026
082e8f1
ci(workflows): add dd-octo-sts chainguard policy files (#8438)
lloeki Jul 16, 2026
7d1287d
test(electron): stabilize flaky CI (install/apt retries, IPC teardown…
rochdev Jul 16, 2026
c25dbb3
ci(workflows): replace GITHUB_TOKEN with dd-octo-sts (#8432)
lloeki Jul 16, 2026
527c622
chore(deps): bump the cloud-and-messaging group across 1 directory wi…
dependabot[bot] Jul 17, 2026
6ded4c8
chore(deps): bump the ai-and-llm group across 1 directory with 8 upda…
dependabot[bot] Jul 17, 2026
0a81fdb
test(electron): give HTTP trace assertions the same timeout as IPC te…
rochdev Jul 17, 2026
b2d7934
feat(frontdoor-agw): Add implementation for Azure Frontdoor and App G…
TophrC-dd Jul 18, 2026
1f4f1cd
chore(deps): bump the cloud-and-messaging group across 1 directory wi…
dependabot[bot] Jul 20, 2026
1fc570f
test(appsec): deflake RASP SSRF "should not detect threat" express te…
CarlesDD Jul 20, 2026
fb0c990
feat(aiguard): evaluating anthropic calls with AI guard automatically…
IlyasShabi Jul 20, 2026
d26d253
feat(ci): add Test Optimization validation runbook (#9323)
juan-fernandez Jul 20, 2026
04ce2b7
test(ci): tolerate coverage preload in clean env tests (#9429)
juan-fernandez Jul 20, 2026
b17dbe3
feat(ci): add code coverage report flags (#9418)
juan-fernandez Jul 20, 2026
b5b5a3c
test(config): isolate span sampling rules fixture (#9430)
juan-fernandez Jul 20, 2026
d0a89cc
fix(nyc): preserve report generation failures (#9337)
BridgeAR Jul 20, 2026
ee8c8d1
fix(graphql): preserve hook error overrides (#9435)
BridgeAR Jul 20, 2026
49c76a2
feat(llmobs): control-plane HTTP client for experiments (#9158)
mehulsonowal Jul 20, 2026
e8dd2da
fix(cypress): support NODE_OPTIONS auto-instrumentation (#9371)
juan-fernandez Jul 20, 2026
6a4dbac
test(openai): bump tested openai version with new cassettes (#9439)
sabrenner Jul 20, 2026
dc6bf0b
ci: update one-pipeline to 1.1.0 (#9438)
gh-worker-campaigns-3e9aa4[bot] Jul 20, 2026
328b01c
feat(llmobs): capture audio in messages and OpenAI chat completions (…
ZStriker19 Jul 20, 2026
64e6d8b
chore(deps): bump the cloud-and-messaging group across 1 directory wi…
dependabot[bot] Jul 21, 2026
bad9a71
chore(deps): bump the ai-and-llm group across 1 directory with 11 upd…
dependabot[bot] Jul 21, 2026
57562fe
feat(playwright): upload failure screenshots (#9433)
juan-fernandez Jul 21, 2026
2ef16a1
fix(cucumber): support version 13.2 (#9456)
juan-fernandez Jul 21, 2026
9b0bdbc
chore(deps): bump import-in-the-middle to 3.3.2 (#9447)
BridgeAR Jul 21, 2026
57da130
test(iast): drop redundant yarn install from sourcemap test (#9448)
BridgeAR Jul 21, 2026
5057dcc
ci: run package scripts with npm (#9405)
BridgeAR Jul 21, 2026
b6534b5
feat(express): surface repeated middleware next() as a span event (#9…
BridgeAR Jul 21, 2026
71e6950
chore(deps): bump the npm_and_yarn group across 2 directories with 3 …
dependabot[bot] Jul 21, 2026
f2176b6
chore(deps): bump the databases group across 1 directory with 18 upda…
dependabot[bot] Jul 21, 2026
8d1b5df
chore(deps): bump brace-expansion (#9452)
dependabot[bot] Jul 21, 2026
f2417e3
chore(deps): bump the test-versions group across 1 directory with 7 u…
dependabot[bot] Jul 21, 2026
812c0c0
chore(deps): bump the web-frameworks group across 1 directory with 21…
dependabot[bot] Jul 21, 2026
807f022
feat(openfeature): support agentless feature flag configuration (#9397)
leoromanovsky Jul 21, 2026
0a12d1d
fix(test-optimization): harden RUM correlation failures (#9408)
BridgeAR Jul 21, 2026
5ae2572
feat(graphql): add field schema coordinates (#9346)
BridgeAR Jul 21, 2026
6e26e04
docs(electron): replace README with internal-use-only notice on publi…
rochdev Jul 21, 2026
6ab4406
fix(config): apply pm2_env env vars before tracer init (#8863)
tlhunter Jul 21, 2026
f66c70e
fix(test-optimization): release removed replay probes (#9336)
BridgeAR Jul 21, 2026
affd012
chore(deps): bump the test-versions group across 1 directory with 4 u…
dependabot[bot] Jul 21, 2026
c455bb8
test(init): guard fixture source logging (#9269)
crysmags Jul 21, 2026
0d8bd25
chore(deps): bump @anthropic-ai/claude-agent-sdk (#9474)
dependabot[bot] Jul 22, 2026
804496e
chore(deps): bump bullmq (#9471)
dependabot[bot] Jul 22, 2026
408e2ba
fix(cypress): support numeric retries with ATR (#9484)
juan-fernandez Jul 22, 2026
502c5e4
feat(appsec): report DD_APPSEC_AGENTIC_ONBOARDING in config telemetry…
christophe-papazian Jul 22, 2026
c72247b
feat(llmobs): support ai sdk v7 embedMany operations (#9466)
sabrenner Jul 22, 2026
2bb861b
fix(loader): defer instrumentation graph during preload (#9485)
BridgeAR Jul 22, 2026
8cc7e97
chore(deps): bump the vendor-minor-and-patch-dependencies group acros…
dependabot[bot] Jul 22, 2026
5069ebb
test(config): assert DD_APPSEC_AGENTIC_ONBOARDING in v5 appsec config…
christophe-papazian Jul 22, 2026
d4f2fb9
chore(deps-dev): bump c8 from 11.0.0 to 12.0.0 (#9476)
dependabot[bot] Jul 22, 2026
300f688
chore(deps): bump fast-uri from 3.1.2 to 3.1.4 in /benchmark/sirun/st…
dependabot[bot] Jul 22, 2026
acd404e
fix(ai): fix infinite recursion when using `BedrockChatLanguageModel`…
sabrenner Jul 22, 2026
3f7e1e0
fix(instrumentation): preserve ESM export aliases (#9436)
BridgeAR Jul 22, 2026
ed7eb17
fix(standalone): stamp _dd.apm.enabled on every exported chunk (#9483)
IlyasShabi Jul 22, 2026
263159a
test(couchbase,kafkajs): wait for client readiness (#9455)
BridgeAR Jul 22, 2026
4734e69
chore: update eslint unicorn plugin to v65 (#8838)
BridgeAR Jul 22, 2026
5b20aa2
chore(deps-dev): bump graphql from 16.14.2 to 17.0.2 (#9328)
dependabot[bot] Jul 22, 2026
e152317
revert: feat(aiguard): remove Anthropic auto-instrumentation (#9495)
BridgeAR Jul 22, 2026
bf02b47
v6.5.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