feat(feign-10.8): toolkit-generated feign HTTP client instrumentation#11709
feat(feign-10.8): toolkit-generated feign HTTP client instrumentation#11709jordan-wong wants to merge 4 commits into
Conversation
Toolkit-generated greenfield instrumentation for Feign HTTP client v10.8+. Run details: - Branch (toolkit): eval/java @ 757979b9 - Branch (worktree): eval/feign-blind-attempt1-20260623 in /Users/jordan.wong/dd-trace-java-eval-feign - Workflow: new_integration, completed 2026-06-23 - Cost: $26.95, 78min, reviewer approved=True - Maven coordinates: io.github.openfeign:feign-core:10.8 Generated module: dd-java-agent/instrumentation/feign/feign-10.8-generated/ - FeignClientInstrumentation (sync Client.execute) - FeignAsyncClientInstrumentation (async AsyncClient.execute) - FeignClientDecorator (HttpClientDecorator) - RequestHeaderInjectAdapter (header injection for distributed tracing) - SpanFinishingCallback (async future completion) - Java tests (FeignClientTest, FeignAsyncClientTest) per R20 Supersedes #10855 (Feign 8.0, stale) and closed #10980 (Feign 10.8, never independently verified). ## Research integrity note `metadata/supported-configurations.json` (4 entries: DD_TRACE_FEIGN_10_8_ENABLED, DD_TRACE_FEIGN_ANALYTICS_ENABLED, DD_TRACE_FEIGN_ANALYTICS_SAMPLE_RATE, DD_TRACE_FEIGN_ENABLED) was **hand-added** by the human operator AFTER the toolkit run; the toolkit's R29 rule was added later in the same session (see commit 757979b9 on eval/java). This is documented in docs/eval-research/generated/feign-20260623/caveats.md. `settings.gradle.kts` line addition is a faithful replay of what the toolkit produced in the eval worktree. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
🟢 Java Benchmark SLOs — All performance SLOs passed
PR vs. master results
Commit: Load and DaCapo benchmarks can be triggered manually in the GitLab pipeline. Results will appear in the Benchmarking Platform UI after completion. |
… name The checkDecoratorAnalyticsConfigurations task requires ANALYTICS entries for each instrumentation name returned by Decorator.instrumentationNames(), not just the shared name. FeignClientDecorator returns ['feign', 'feign-10.8']; the 'feign' analytics keys were already added, but 'feign-10.8' was missing. Adds: - DD_TRACE_FEIGN_10_8_ANALYTICS_ENABLED - DD_TRACE_FEIGN_10_8_ANALYTICS_SAMPLE_RATE (type: decimal) Locally verified ./gradlew checkConfigurations BUILD SUCCESSFUL. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
R31 — drop assertInverse from muzzle: versions = '[10.8,)' with assertInverse = true was failing because feign 10.6.0 actually passes muzzle (FeignClientInstrumentation sync class doesn't need 10.8 features; only FeignAsyncClientInstrumentation does). assertInverse asserts inverse versions FAIL muzzle — but 10.6.0 PASSES, so the auto-test failed. Conservative omission of assertInverse is correct here. The min version remains 10.8 (compileOnly + muzzle pass range). Fixes: muzzle: [2/8] CI failure (muzzle-AssertFail-io.github.openfeign-feign-core-10.6.0). R32 — '-generated' exclusion: Added 'feign-10.8-generated' to instrumentationNaming.exclusions in dd-java-agent/instrumentation/build.gradle. Fixes check-instrumentation-naming. Local verification: ./gradlew :dd-java-agent:instrumentation:feign:feign-10.8-generated:muzzle BUILD SUCCESSFUL ./gradlew checkInstrumentationNaming BUILD SUCCESSFUL Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Spotless moved the trailing comment 'org-json does not use semver' to its own line. Fixes dd-gitlab/spotless CI failure introduced by the R32 edit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Only fails CI check dd-gitlab/validate_supported_configurations_v2_local_file because of config keys arent registered as this is a completely new instrumentation. We can assume CI checks are passing |
|
Hi! 👋 Thanks for your pull request! 🎉 To help us review it, please make sure to:
If you need help, please check our contributing guidelines. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1a6fd6d284
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } | ||
|
|
||
| if (future != null) { | ||
| future = future.whenComplete(new SpanFinishingCallback(span)); |
There was a problem hiding this comment.
Preserve cancellation on async Feign futures
When an AsyncClient implementation returns a cancellable CompletableFuture (for example Feign's async clients use cancellation to abort in-flight requests), replacing it with the dependent stage from whenComplete breaks that contract: cancelling the future returned to user code only cancels the dependent stage and leaves the original request running. Register the callback without assigning it back, or otherwise propagate cancellation to the original future.
Useful? React with 👍 / 👎.
| implements Instrumenter.ForTypeHierarchy, Instrumenter.HasMethodAdvice { | ||
|
|
||
| public FeignClientInstrumentation() { | ||
| super("feign", "feign-10.8"); |
There was a problem hiding this comment.
Keep generated Feign instrumentation opt-in
This generated/eval module is documented in the new metadata as disabled by default, but InstrumenterModule.Tracing uses defaultEnabled() from the base class unless it is overridden, so this constructor enables the sync and async Feign instrumentations for every Feign 10.8+ application by default. If this module is meant to be opt-in, override defaultEnabled() in both instrumentation classes; otherwise the metadata default is misleading and users will get spans unless they explicitly opt out.
Useful? React with 👍 / 👎.
Summary
Toolkit-generated greenfield instrumentation for Feign HTTP client (io.github.openfeign:feign-core 10.8+). Part of the dd-trace-java APM toolkit eval program.⚠️ DO NOT MERGE. Open for review;
reviewer feedback feeds back into toolkit R-rules.
Wins from prior reviewer feedback
@mcculls reviewed the prior toolkit feign attempt on #10579 (CLOSED). This regeneration addresses three of his key concerns:
## Regressions / concerns vs prior review and master conventions
asked for the ReactorCoreModule pattern explicitly on DRAFT: APM AI TOOLKIT New Integration: Feign Client Instrumentation #10579.
keys → two HTTP spans per request. Tests assert this rather than fix it. Use a shared sentinel.
What was structurally correct
HttpClientDecorator<Request, Response> shape matches master HTTP-client conventions. Module path dd-java-agent/instrumentation/feign/feign-10.8-generated/ follows version-suffix + parent-dir
naming.
CI
All substantive jobs pass (build, instrumentationTest, latestDepTest, muzzle 8/8, smokeTest, profiling). Only failing check is dd-gitlab/validate_supported_configurations_v2_local_file —
external registry validator requires DD_TRACE_FEIGN_* keys to be pre-registered out-of-band. Not a code issue.
What reviewers should do
Related
Prior toolkit attempts: #10579 (review from @mcculls), #10980, #10855. Sibling eval PRs: #11708 (sparkjava), #11717 (commons-httpclient).
🤖 Generated with Claude Code