open-telemetry / opentelemetry-collector-contrib

Contrib repository for the OpenTelemetry Collector
https://opentelemetry.io
Apache License 2.0
2.92k stars 2.28k forks source link

[pkg/ottl] Function which converts slice into map #35256

Open djaglowski opened 4 days ago

djaglowski commented 4 days ago

Component(s)

pkg/ottl

Is your feature request related to a problem? Please describe.

I often hear from users that it's difficult to work with slices in OTTL and/or backends. Issues such as https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/29289 may alleviate this to some extent, but I believe in many cases users would prefer to work around slices by converting them to maps. This obviously comes with some assumptions, but I think there may be a reasonable way to provide this functionality.

Describe the solution you'd like

A new function called Associate, which requires two parameters:

  1. A path to an array.
  2. A "sub-path", defined by a slice of strings, which traverses to the desired key in each element.

e.g. Given a log record with the following attributes:

attributes:
  hello: world
  things:
    - name: foo
      value: 2
    - name: bar
      value: 5

A user could write something like Associate(attributes["things"], ["name"]) and expect the following output:

attributes:
  hello: world
  things:
    foo:
      name: foo
      value: 2
    bar:
      name: bar
      value: 5

A slightly more complicated example highlights the notion of a sub-path. I'm not sure if OTTL has a mechanism for this, but if the array contains more complicated values, it may be necessary to drill further into the object to find its key.

attributes:
  hello: world
  things:
    - value: 2
      details:
        name: foo
    - value: 5
      details:
        name: bar

In the above case, Associate(attributes["things"], ["details", "name"]) would produce:

attributes:
  hello: world
  things:
    foo:
      value: 2
      details:
        name: foo
    bar:
      value: 5
      details:
        name: bar

It may make sense for users to specify, using an optional boolean, whether they wish to delete the key field, since it becomes redundant. (Or maybe this is just the default/only behavior.) Using the previous example, we'd expect:

attributes:
  hello: world
  things:
    foo:
      value: 2
      details: {}
    bar:
      value: 5
      details: {}

Finally, this comes with some caveats about uniqueness of keys. I think since arrays are ordered it is simple enough to say that in the case of duplicates, the first or last one wins.

Describe alternatives you've considered

No response

Additional context

No response

github-actions[bot] commented 4 days ago

Pinging code owners:

djaglowski commented 4 days ago

Another option would be useful as well, to allow the value to simultaneously be specified via a sub-path.

attributes:
  hello: world
  things:
    - name: foo
      details:
        value: 2
    - name: bar
      details:
        value: 5

Associate(attributes["things"], ["name"], ["details", "value"] ) would produce:

attributes:
  hello: world
  things:
    foo: 2
    bar: 5
bacherfl commented 3 days ago

I would gladly work on a PR if this function should be added