[pkg/ottl] Add Coalesce converter for first-non-nil value selection#46862
Conversation
0e265d2 to
bd8a602
Compare
|
/rerun |
f5265bb to
05aab32
Compare
There was a problem hiding this comment.
I don't know how file .chloggen/fix_gcp_snake_case.yaml started to give error, as it was added when i fixed issue #46588 where component name googlecloudlogentry_encoding was correct, now i guess it's name has been changed to google_cloud_logentry_encoding.
#46588 changes: https://github.com/open-telemetry/opentelemetry-collector-contrib/pull/46588/changes
MohamedElDegwi
left a comment
There was a problem hiding this comment.
Hi @57Ajay, thanks for working on this. I've few questions I'd appreciate if you could clarify.
Isn't having multiple statements for different semconvs a migration problem not an ottl one? If understand this correctly, the growth of ottl statements is intended as alert of migration needed, so If I have 3 statements to cover canonical.user this is an indication that I need to sync/update my setup?
Do you have any use-case that require this function? From what I see, set + where is explicit, readable, and capable enough. See PR#46443 as an example.
Sorry If I've been bit skeptical haha :)
Thanks @MohamedElDegwi, fair question. |
512123f to
fd72454
Compare
|
This PR was marked stale due to lack of activity. It will be closed in 14 days. |
Signed-off-by: 57Ajay <57ajay.u@gmail.com>
e6143a9 to
832a1d3
Compare
57Ajay
left a comment
There was a problem hiding this comment.
fixed with @edmocosta suggestions
|
Thank you for your contribution @57Ajay! 🎉 We would like to hear from you about your experience contributing to OpenTelemetry by taking a few minutes to fill out this survey. If you are getting started contributing, you can also join the CNCF Slack channel #opentelemetry-new-contributors to ask for guidance and get help. |
…pen-telemetry#46862) fixes open-telemetry#46847 ### Description Adds a `Coalesce` converter to OTTL that returns the first non-nil value from a list of arguments. OTTL currently has no way to express "use the first non-nil value from a set of candidates" in a single statement. Users who need to resolve a canonical attribute from multiple possible sources must write multiple chained `set` statements with increasingly complex `where` clauses. This is verbose, ordering-dependent, and scales poorly. `Coalesce` solves this: ```yaml # Before: 3 statements, fragile ordering - set(attributes["user"], attributes["user.id"]) where attributes["user.id"] != nil - set(attributes["user"], attributes["enduser.id"]) where attributes["user"] == nil and attributes["enduser.id"] != nil - set(attributes["user"], "unknown") where attributes["user"] == nil # After: 1 statement - set(attributes["user"], Coalesce([attributes["user.id"], attributes["enduser.id"], "unknown"])) ``` ### Implementation - Registered as a standard OTTL Converter with `[]ottl.Getter[K]` parameter (same pattern as `Format`). - Iterates getters left to right, returns the first non-nil result. - Returns nil if all values are nil. - No side effects, pure function, bounded execution — consistent with OTTL function design principles. - No grammar or parser changes. ### Testing **Unit tests** (`func_coalesce_test.go`): 13 test cases covering first-value-wins, nil-skip-to-second, nil-skip-to-third, all-nil, single-arg, int/bool/float type preservation, short-circuit evaluation (does not call getters past the first non-nil), getter error propagation, and factory validation (empty args, wrong type). **E2e tests** (`e2e/e2e_test.go`): 3 test cases exercising `Coalesce` through the real OTTL parser — first-arg-wins, skip-nil-pick-second, all-nil-pick-literal. **Live collector test**: Built `otelcontribcol`, ran the transform processor with 5 Coalesce statements against a real OTLP/HTTP log request. All 5 produced correct output: ``` -> test1: Str(alice) # first arg non-nil -> test2: Str(bob-legacy) # first nil, second non-nil -> test3: Str(fallback) # all paths nil, literal wins -> test4: Str(alice) # single arg -> test5: Int(42) # first nil, int value wins ``` Signed-off-by: 57Ajay <57ajay.u@gmail.com>
…pen-telemetry#46862) fixes open-telemetry#46847 ### Description Adds a `Coalesce` converter to OTTL that returns the first non-nil value from a list of arguments. OTTL currently has no way to express "use the first non-nil value from a set of candidates" in a single statement. Users who need to resolve a canonical attribute from multiple possible sources must write multiple chained `set` statements with increasingly complex `where` clauses. This is verbose, ordering-dependent, and scales poorly. `Coalesce` solves this: ```yaml # Before: 3 statements, fragile ordering - set(attributes["user"], attributes["user.id"]) where attributes["user.id"] != nil - set(attributes["user"], attributes["enduser.id"]) where attributes["user"] == nil and attributes["enduser.id"] != nil - set(attributes["user"], "unknown") where attributes["user"] == nil # After: 1 statement - set(attributes["user"], Coalesce([attributes["user.id"], attributes["enduser.id"], "unknown"])) ``` ### Implementation - Registered as a standard OTTL Converter with `[]ottl.Getter[K]` parameter (same pattern as `Format`). - Iterates getters left to right, returns the first non-nil result. - Returns nil if all values are nil. - No side effects, pure function, bounded execution — consistent with OTTL function design principles. - No grammar or parser changes. ### Testing **Unit tests** (`func_coalesce_test.go`): 13 test cases covering first-value-wins, nil-skip-to-second, nil-skip-to-third, all-nil, single-arg, int/bool/float type preservation, short-circuit evaluation (does not call getters past the first non-nil), getter error propagation, and factory validation (empty args, wrong type). **E2e tests** (`e2e/e2e_test.go`): 3 test cases exercising `Coalesce` through the real OTTL parser — first-arg-wins, skip-nil-pick-second, all-nil-pick-literal. **Live collector test**: Built `otelcontribcol`, ran the transform processor with 5 Coalesce statements against a real OTLP/HTTP log request. All 5 produced correct output: ``` -> test1: Str(alice) # first arg non-nil -> test2: Str(bob-legacy) # first nil, second non-nil -> test3: Str(fallback) # all paths nil, literal wins -> test4: Str(alice) # single arg -> test5: Int(42) # first nil, int value wins ``` Signed-off-by: 57Ajay <57ajay.u@gmail.com>
fixes #46847
Description
Adds a
Coalesceconverter to OTTL that returns the first non-nil value from a list of arguments.OTTL currently has no way to express "use the first non-nil value from a set of candidates" in a single statement. Users who need to resolve a canonical attribute from multiple possible sources must write multiple chained
setstatements with increasingly complexwhereclauses. This is verbose, ordering-dependent, and scales poorly.Coalescesolves this:Implementation
[]ottl.Getter[K]parameter (same pattern asFormat).Testing
Unit tests (
func_coalesce_test.go): 13 test cases covering first-value-wins, nil-skip-to-second, nil-skip-to-third, all-nil, single-arg, int/bool/float type preservation, short-circuit evaluation (does not call getters past the first non-nil), getter error propagation, and factory validation (empty args, wrong type).E2e tests (
e2e/e2e_test.go): 3 test cases exercisingCoalescethrough the real OTTL parser — first-arg-wins, skip-nil-pick-second, all-nil-pick-literal.Live collector test: Built
otelcontribcol, ran the transform processor with 5 Coalesce statements against a real OTLP/HTTP log request. All 5 produced correct output: