Skip to content

Latest commit

 

History

History
100 lines (77 loc) · 6.7 KB

AGENTS.md

File metadata and controls

100 lines (77 loc) · 6.7 KB

Agent context for dd-trace-java

What is this project?

Datadog Java APM agent (dd-trace-java): a Java agent that auto-instruments JVM applications at runtime via bytecode manipulation. It ships ~120 integrations (~200 instrumentations) for tracing, profiling, AppSec, IAST, CI Visibility, USM, and LLM Observability.

Project layout

See ARCHITECTURE.md for detailed module descriptions.

dd-java-agent/            Main agent (shadow jar, instrumentations, product modules)
dd-trace-api/             Public API & configuration constants
dd-trace-core/            Core tracing engine (spans, propagation, writer)
dd-trace-ot/              Legacy OpenTracing compatibility library
internal-api/             Internal shared API across modules
components/               Shared low-level components (context, environment, json)
products/                 Sub-products (feature flagging, metrics)
communication/            HTTP transport to Datadog Agent
remote-config/            Remote configuration support
telemetry/                Agent telemetry
utils/                    Shared utility modules (config, time, socket, test, etc.)
dd-smoke-tests/           Smoke tests (real apps + agent)
docs/                     Developer documentation (see below)

Key documentation (read on demand, don't load upfront)

Topic File
Architecture & design ARCHITECTURE.md
Building from source BUILDING.md
Contributing & PR guidelines CONTRIBUTING.md
How instrumentations work docs/how_instrumentations_work.md
Adding a new instrumentation docs/add_new_instrumentation.md
Adding a new configuration docs/add_new_configurations.md
Testing guide (6 test types) docs/how_to_test.md
Writing JUnit tests docs/how_to_test_with_junit.md
Writing a smoke test docs/how_to_smoke_test.md
Working with Gradle docs/how_to_work_with_gradle.md
Bootstrap/premain constraints docs/bootstrap_design_guidelines.md
Instrumentation/advice constraints docs/instrumentation_design_guidelines.md
CI/CD workflows .github/workflows/README.md

When working on a topic above, read the linked file first — they are the source of truth maintained by humans.

Build quick reference

./gradlew clean assemble                  # Build without tests
./gradlew :dd-java-agent:shadowJar        # Build agent jar only (dd-java-agent/build/libs/)
./gradlew :path:to:module:test            # Run tests for a specific module
./gradlew :path:to:module:test -PtestJvm=11  # Test on a specific JVM version
./gradlew spotlessApply                   # Auto-format code (google-java-format)
./gradlew spotlessCheck                   # Verify formatting

Code conventions

  • Formatting: google-java-format enforced via Spotless. Run ./gradlew spotlessApply before committing.
  • Static imports: Prefer static imports over class-qualified calls for call-style helpers, in both test (Assertions.assertEquals, Mockito.mock) and production code (Collections.emptyList). Wildcard imports disallowed — see CONTRIBUTING.md.
  • Documentation: Use concise Javadoc comments (/** ... */) for class, method, and field documentation.
  • Instrumentation layout: dd-java-agent/instrumentation/{framework}/{framework}-{minVersion}/
  • Instrumentation pattern: Type matching → Method matching → Advice class (bytecode advice, not AOP)
  • Test frameworks: Always use JUnit 5 for unit tests. Only use Groovy / Spock tests for instrumentation and smoke tests.
  • Parameterized tests: Prefer @TableTest for multi-column literal data, with named scenarios and aligned columns. Prefer a simple @TypeConverter over switching to @MethodSource when it can turn table values into the required arguments. Use @MethodSource for cases requiring complex object construction, builders, or mocks. See the JUnit testing guide.
  • Forked tests: Use ForkedTest suffix when tests need a separate JVM
  • Flaky tests: Annotate with @Flaky — they are skipped in CI by default

PR conventions

  • Title: imperative verb sentence describing user-visible change (e.g. "Fix span sampling rule parsing")
  • Labels: always add tag: ai generated and at least one comp: or inst: label + one type: label
  • Use tag: no release notes for internal/refactoring changes
  • Open as draft first, convert to ready when reviewable
  • Dependency changes: when adding, updating, or removing dependencies, regenerate all affected gradle.lockfile files and include them in the same PR. See lockfile updates.

Review Guidelines

  • Technical debt: run /techdebt over branch changes before marking a PR ready to catch code duplication, unnecessary complexity, and dead code (refactor-only, never changes behavior) — see .agents/skills/techdebt/SKILL.md.
  • Performance: run /perf-review over branch changes before marking a PR ready (advisory, not a merge gate) — see .agents/skills/perf-review/SKILL.md.

CI scripts

Every curl that runs in CI (.gitlab-ci.yml, .gitlab/, GitHub Actions, the scripts they call, and the Dockerfiles they build) should:

  • Fail on HTTP errors: pass -f/--fail. Without it, a 4xx/5xx exits 0 and the error page is used as if it were the real response (e.g. piped into bash or jq).
  • Retry transient errors: pass --retry 5 --retry-delay 2 (add --retry-connrefused for remote endpoints).
  • Propagate the failure: the job must stop when curl fails. Never pipe curl straight into bash/sh: download to a file with -f, then run it.

Example: curl -fsSL --retry 5 --retry-delay 2 --retry-connrefused -o out.tar.gz "$url"

Exception: a script that checks the HTTP status itself (-w "%{http_code}", e.g. .gitlab/check_test_agent_results.sh) may skip --fail, but still needs --retry.

Critical constraints