Enable standalone Config v2 runtime loading#2682
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #2682 +/- ##
==========================================
- Coverage 69.88% 69.04% -0.85%
==========================================
Files 359 361 +2
Lines 51142 52269 +1127
==========================================
+ Hits 35739 36087 +348
- Misses 13172 13873 +701
- Partials 2231 2309 +78
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Blocked by #2700 |
Load standalone configuration through the v2 schema and full-document runtime converter before considering the legacy parser. Fall back only when detection explicitly reports that the input is not v2, so malformed or unsupported v2 documents fail startup instead of being misread as v1. Keep untouched input bytes for the v1 path to preserve its existing environment-substitution and defaulting behavior. Report the selected version and cover both paths, standalone-only sections, defaults, and failure modes in startup tests.
Copy the internal Config v2 schema and conversion packages into the production Docker builder so the standalone binary can compile in release images. The startup path now imports these packages directly, while the previous narrow build context omitted them. Update the converter documentation to reflect that it now participates in standalone runtime loading.
Copy the internal Config v2 packages into each Docker build context that compiles the OBI binary. This keeps debug and integration images aligned with the production image and prevents missing-package build failures.
Launch the integration image with a representative Config v2 document and verify that OBI detects v2, instruments the selected process, and exposes HTTP telemetry through its configured Prometheus reader. This closes the runtime coverage gap where only configuration conversion was exercised without starting standalone OBI.
Parsed Config v2 documents must distinguish omitted fields from explicit false and zero values. Without that distinction, partial documents cannot disable default-on features or request zero-valued limits. Retain each parsed extension source and overlay it onto the canonical Config v2 defaults before conversion. Programmatically constructed partial schemas keep their existing compatibility behavior.
The published Config v2 schema disallows extra properties, but the YAML decoder silently ignored misspelled OBI settings. A typo could therefore leave a default active without any configuration error. Decode OBI-owned sections with known-field checks while leaving the wider OpenTelemetry declarative document extensible. Apply the same validation to standalone extensions and receiver-embedded configuration.
Runtime and log annotation filters are published, but no equivalent selection mechanism exists in the current runtime configuration. Accepting non-empty filters would broaden injection or log mutation beyond the requested scope. Fail closed with a field-specific error until those mappings exist. Continue accepting empty filter objects used by the documented default configuration.
Parsed Config v2 documents are overlaid on generated runtime defaults. A shallow copy left nested maps shared with obi.DefaultConfig, allowing one conversion to alter defaults observed by later configurations. Deep-copy the extension before decoding the source overlay. Preserve the existing merge behavior and verify that merged resource labels do not mutate their source defaults.
Strict known-field decoding serializes extracted YAML nodes before decoding them again. Aliases that referenced top-level anchors lost their definitions when only the OBI subtree was serialized. Expand aliases into cloned nodes before serialization while retaining cycle and unresolved-alias errors. Valid declarative documents can now share anchored values with the OBI extension.
Honor default inclusion with a catch-all selector and accept rule orders only when they preserve the runtime's exclusion-first behavior. Reject selector combinations and rule shapes that the legacy matcher cannot represent so Config v2 loading never silently drops capture intent.
Fail Config v2 loading when extensible enrichment objects contain fields that the runtime converter cannot apply. This prevents accepted DNS and rule-based enrichment settings from becoming silent no-ops. Keep the published default example limited to supported service-name and attribute controls so its documented behavior matches runtime behavior.
Honor capture match order when multiple include rules refine exports or HTTP routes. Validate OTLP exporter ports before mapping them into runtime discovery settings.
Require protocol and signal filters to agree when they map to one runtime filter. Divergent application, network, and stats filters now fail with their source path instead of being ignored or widened.
Fail conversion when extensible network capture or stats objects contain properties without a runtime representation. This prevents accepted Config v2 settings from becoming silent no-ops.
Validate every declarative SDK and exporter field before conversion so standalone startup cannot silently substitute runtime defaults for the requested behavior. Import OTLP/HTTP, headers, transport selection, resource identity, and declarative exporter defaults where OBI has equivalent runtime settings. Return path-specific errors for unsupported provider, processor, and TLS options.
f85a4f7 to
4b1ccba
Compare
grcevski
left a comment
There was a problem hiding this comment.
Looks great generally, I left a few comments/questions.
| if encoding == nil || *encoding == otelconfx.OTLPHttpEncodingProtobuf { | ||
| return otelcfg.ProtocolHTTPProtobuf, nil | ||
| } | ||
| if *encoding == otelconfx.OTLPHttpEncodingJson { |
There was a problem hiding this comment.
I think this may not work, since we rely on the env variable to be picked up by the OTel exporters, we don't explicitly set the protocol in traces.go and exporter.go.
There was a problem hiding this comment.
The conversion assigns the runtime protocol directly for both signal paths: TracesProtocol is set for OTLP/gRPC and OTLP/HTTP, and MetricsProtocol is set the same way. TestDocumentToRuntimeImportsOTLPHTTPExporters covers JSON traces and protobuf metrics, while the default exporter test covers gRPC, so this path does not rely on the exporter environment lookup.
Parse declarative OTLP header lists with the OpenTelemetry baggage parser so escaped values and invalid input follow the published schema. Make the receiver selection test explicit about excluding unmatched processes and restore gofumpt formatting required by CI.
Expect the declarative include-by-default policy to add its catch-all selector alongside the explicit open-port selector. This keeps the branch test consistent with current main and prevents the synthetic PR merge from asserting contradictory policy behavior.
Compose cleanup previously removed only services that had already stopped. A hung OBI container could abort shutdown and leave the rest of the stack running, causing later integration tests to collide on ports. Request that Compose stop services during removal so cleanup deletes every service in the test stack.
Unit shard 0 failed twice in GitHub Actions while the exact synthetic merge passed all 1,975 shard tests locally with race detection and coverage. Create a new head SHA so GitHub reruns the check suite after the validated Compose cleanup change.
Bring this pull request up to date with the latest base branch changes so it can be tested and reviewed against the current codebase.
Summary
NotV2Error, while preserving the original input for v1 environment handling and defaultsWhy
Standalone OBI currently routes every configuration document through the legacy v1 loader. That prevents valid v2 documents from reaching the existing schema and conversion path, and an unconditional fallback could hide invalid v2 configuration by interpreting it as v1.
This change makes version detection authoritative: valid v2 documents use the complete v2 conversion path, explicit non-v2 input retains the established v1 behavior, and recognized but invalid v2 input fails startup with its v2 diagnostic.
Runtime impact
Existing v1 configuration remains supported, including legacy environment-variable precedence and escaping. V2 defaulting and environment substitution run once, standalone-only sections are accepted, and startup logs identify only the selected configuration version without printing configuration values.
Verification
go test -race ./cmd/obi ./internal/config/schema ./internal/config/convertgo vet ./cmd/obigolangci-lint run ./cmd/obi --timeout=6mmake check-config-v2-artifactsmake license-header-checkmake compileThis is part of the Config v2 release gate and should ship together with the Collector receiver work, migration documentation, and published v2 artifacts tracked from #2251.
Closes #2535