Skip to content

Unify directional HTTP route policies in config v2#2680

Merged
MrAlias merged 12 commits into
open-telemetry:mainfrom
MrAlias:agent/unify-v2-route-policies
Jul 24, 2026
Merged

Unify directional HTTP route policies in config v2#2680
MrAlias merged 12 commits into
open-telemetry:mainfrom
MrAlias:agent/unify-v2-route-policies

Conversation

@MrAlias

@MrAlias MrAlias commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Closes #747.

Summary

  • define one direction-scoped HTTP route policy for global and per-service config v2 settings
  • make ignored patterns, ignore mode, unmatched routes, wildcard selection, and cardinality available at both scopes
  • preserve the v1 configuration surface while mapping flat global settings into both v2 directions
  • update the v2 schema, default example, migration guidance, and parity checks

Configuration semantics

Per-service route policies override global policies field by field. Omitted fields inherit the global value, while explicitly configured arrays replace the inherited array, including an empty array that clears it. Route evaluation applies ignored patterns first, then configured or discovered routes, then unmatched-route behavior.

Validation

  • make generate
  • make check-config-schema
  • make check-config-v2-artifacts
  • make lint-markdown
  • python3 devdocs/config/version-2.0/validate_example.py
  • go test -race ./...
  • focused tests for config conversion, discovery, and route transformation
  • golangci-lint across every modified Go package

@codecov

codecov Bot commented Jul 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 76.60944% with 109 lines in your changes missing coverage. Please review.
✅ Project coverage is 69.74%. Comparing base (27fbfa6) to head (97194b2).

Files with missing lines Patch % Lines
pkg/transform/routes.go 61.41% 60 Missing and 11 partials ⚠️
pkg/appolly/services/custom_routes.go 71.73% 12 Missing and 1 partial ⚠️
internal/config/convert/import.go 91.07% 7 Missing and 3 partials ⚠️
pkg/appolly/discover/typer.go 76.92% 8 Missing and 1 partial ⚠️
pkg/appolly/app/svc/svc.go 73.68% 4 Missing and 1 partial ⚠️
pkg/internal/transform/route/clusterurl/trie.go 75.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2680      +/-   ##
==========================================
- Coverage   69.88%   69.74%   -0.14%     
==========================================
  Files         359      360       +1     
  Lines       51142    51535     +393     
==========================================
+ Hits        35739    35945     +206     
- Misses      13172    13341     +169     
- Partials     2231     2249      +18     
Flag Coverage Δ
integration-test 49.95% <5.93%> (-0.48%) ⬇️
integration-test-arm 26.01% <5.44%> (-0.10%) ⬇️
integration-test-vm-5.15-lts ?
integration-test-vm-6.18-lts ?
k8s-integration-test 33.76% <5.93%> (-0.50%) ⬇️
oats-test 34.38% <5.93%> (-0.21%) ⬇️
unittests 68.02% <86.51%> (+0.17%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@MrAlias
MrAlias marked this pull request as ready for review July 17, 2026 15:03
@MrAlias
MrAlias requested a review from a team as a code owner July 17, 2026 15:03

@mariomac mariomac left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! I wonder if there is a way to simplify the code:

  • Remove the code from old, non-directional route decorator (provideRoutes) and keep only the directional route decorator provideDirectionalRoutes
  • If the user defines the non-directional routing patterns, copy them to both Incoming and Outgoing configuration so the directional routing code will behave as the old, global, non-directional route decorator.

MrAlias and others added 9 commits July 20, 2026 17:01
Give global and per-service HTTP route settings one directional policy
shape so incoming and outgoing traffic can configure patterns, ignored
routes, and unmatched behavior consistently.

Preserve the v1 configuration surface while translating its flat global
policy into both v2 directions. Document inheritance and migration
semantics and cover conversion and runtime precedence with tests.
Turn valid include-rule route refinements into an active directional
route configuration even when global policies are omitted. This allows
per-service route and ignore settings to reach request processing while
leaving complete configurations without global policies inactive.

Cover partial and complete v2 inputs to preserve inherited defaults and
the explicit unset baseline.
Directional route policies belong to the HTTP configuration surface.
Applying them to every protocol allowed broad ignored patterns to suppress
unrelated gRPC and database telemetry.

Return before policy selection for non-HTTP events and cover incoming and
outgoing protocols with regression assertions.
Rule-only v2 route refinements need a baseline for inheritance without
turning that baseline into a global policy. Treating the baseline as global
allowed harvested routes to appear on unrelated services and directions.

Record the rule-only state through conversion, attach compiled policies only
where overrides exist, and preserve the absence of global policies during
export.
Complete v2 imports now build global policies without inheriting v1
runtime defaults. They also retain direction presence so omitted policies
stay inactive through service discovery, routing, and v2 export.

Per-service refinements can still activate a direction without a global
policy, preserving the intended override behavior.
Rule policy activation previously rebuilt the runtime route config and
discarded which global directions were present. An omitted direction then
became active whenever any per-service route refinement existed.

Retain the existing config while installing the directional baseline so
global absence survives discovery, routing, and v2 export.
Treat a zero maximum as disabling trie-based collapsing, matching the
documented configuration contract.

Cover both the trie itself and directional route processing so future
policy changes preserve uncapped routes.
Keep global matchers on the router and attach compiled policies only when
a service rule overrides that direction.

Retain independent mutable tries for enabled low-cardinality policies so
one service cannot consume another service's cardinality budget.
Require empty or one nonzero ASCII byte in both converter validation and
the published schema, matching the byte-based route classifier.

Reject Unicode and NUL values before policy construction and document
the supported surface.
@MrAlias
MrAlias force-pushed the agent/unify-v2-route-policies branch from 91793c4 to ca8e20a Compare July 20, 2026 17:03
@MrAlias

MrAlias commented Jul 20, 2026

Copy link
Copy Markdown
Contributor Author

Thanks, Mario. I agree that a single directional path would be a cleaner end state.

I’m hesitant to take it in this PR. The non-directional decorator exists solely for config v1 compatibility, and the plan is to retire that surface once v2 has proven stable. Converting legacy configuration into the directional representation now would add a transient compatibility layer and broaden this into a v1 behavioral-parity exercise—particularly around service-level routing precedence—only to remove it with the v1 path.

I’d keep this PR focused on making v2 correct and stable, then delete the non-directional implementation as part of the v1 sunset. If you think it is worth retaining the idea, I’m happy to open a follow-up issue so we can revisit it if the v1 support horizon changes or the duplicate logic causes a concrete maintenance issue. Let me know what you think.

@mariomac

Copy link
Copy Markdown
Contributor

Ok @MrAlias your strategy sounds reasonable to me.

Bring the pull request onto the current base so it includes the receiver
test correction and all intervening repository changes. This creates a
fresh pull request revision for CI instead of rerunning the stale merge.
Comment thread pkg/appolly/services/custom_routes.go
Comment thread internal/config/convert/import.go
MrAlias added 2 commits July 23, 2026 19:23
Bring this pull request up to date with the latest base branch changes so it can be tested and reviewed against the current codebase.
Use the unset unmatched-route baseline for every direction without a
global v2 policy. This prevents pattern-only service refinements from
falling back to the legacy wildcard behavior.

Cover the mixed global and per-service case so partial directional
configuration stays consistent with rule-only routing.

@grcevski grcevski left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@MrAlias

MrAlias commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

Ok @MrAlias your strategy sounds reasonable to me.

#2780

@MrAlias
MrAlias merged commit 9e83dd4 into open-telemetry:main Jul 24, 2026
101 checks passed
@MrAlias
MrAlias deleted the agent/unify-v2-route-policies branch July 24, 2026 15:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cleaner per-service and routing config

3 participants