-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dynamic attribute injection in transform processor #28573
Comments
Pinging code owners:
See Adding Labels via Comments if you do not have permissions to add labels yourself. |
Can you expand more on what you mean by
At the moment the transformprocessor has a static list of functions. Although we are open to more functions, we currently have no way to inject functions at runtime: #16098 That said, I feel OTTL does fit this use case, and you are free to use OTTL in a custom component. |
Our local store is a local key-value map in memory, but I understand that custom functions could open a hole. So, maybe we would have to consider a more controlled solution perhaps like building the storage internally, but I'm concerned that we would be tied to a specific implementation.
Pardon my ignorance (I did not look into the implementation details; we are still in the phase of deciding what to do) but how are the functions mapped internally? Since config is read at runtime, I imagine you have something like a map built using reflection from function name to the actual function. If so, maybe you could add more entries to that map based on the provided options?
We already have a working pipeline in the PROD environments with this custom processor (and other custom modules) and it's working well. We just wish to contribute to the OpenTelemetry community. We are not tied to any particular processor. We are still in the process to understand where our proposal would fit best and your input is invaluable. So far, it looks like the |
In memory as in the pdata payload? Or somewhere else? Components that use OTTL must, as part of startup, provide OTTL a map of function names (strings) and function implementations. OTTL uses this map to match incoming statements to functions. |
In a global variable initialised by an extension.
Correct me if I'm wrong, but this looks like it's similar to what
|
@xvilaca-te but how would you pass in the actual Go implementation of the function if not during compilation. It looks like the kafkareceiver provides access to pre-determined functions like OTTL does. Can you provide an example configuration that you're imagining for this usecase? |
I did not explain myself well. What we do in the func NewFactory(options ...transformprocessor.FactoryOption) processor.Factory {
opt := transformprocessor.WithCustomFunctions(dynamicAttributes...)
return transformprocessor.NewFactory(opt...),
} This is where we would reference our extension of the processors:
- import: "github.com/thousandeyes/otel-collector/processors/transform"
gomod: "github.com/thousandeyes/otel-collector master" The configuration then uses the name of the function as if it were statically defined. It's not as easy as just configuring the processor, but we don't have to implement our own logic either. I believe the authors of |
Here is a link to where in |
@TylerHelmuth Are the examples above clear? |
@xvilaca-te if you are already implementing a custom receiver then I don't believe we need to get the transformprocessor involved. OTTL is a standalone package and can be used in your receiver. If your receiver defines custom functions then they can be used in your receiver's implementation of OTTL. |
This issue has been inactive for 60 days. It will be closed in 60 days if there is no activity. To ping code owners by adding a component label, see Adding Labels via Comments, or if you are unsure of which component this issue relates to, please ping Pinging code owners:
See Adding Labels via Comments if you do not have permissions to add labels yourself. |
This issue has been closed as inactive because it has been stale for 120 days with no activity. |
Component(s)
processor/transform
Is your feature request related to a problem? Please describe.
In our work at ThousandEyes, we developed an OpenTelemetry collector pipeline where we had to dynamically inject attributes with values retrieved from a local storage. Specifically, we needed to:
test.id
in the receivertest.id
from every data point, retrieve a matching slice of pairs(key,[val])
from a local store, and inject those pairs as attributes with keys of type string and values of type array of stringstest.id
attributeUnfortunately, we could not find a processor that would allow us to do this, so we opted to develop our own custom processor to do this dynamic attribute injection.
Describe the solution you'd like
We would like to extend the
transformprocessor
with the ability to dynamically inject attributes and use this extension in our pipelines. We are open to discussion regarding how to do this, but after studying thetransformprocessor
we had some initial thoughts to start the discussion:transformprocessor
is very generic, we think it makes more sense to provide a custom function that returns the slice of dynamically injected attributes so that the implementation lies on the user sideset
editor to allow for the injection of multiple attributes in the same statementSo, to summarise, our initial idea would be to support custom functions in the factory like the following example inspired by the
kafkareceiver
:I'm assuming here that there is a
KeyValue
type (it's just an hypothetical type for the injected attributes; we can reuse) and that error handling on the processor side, but maybe it can be done on the user side if needed. (Still learning abouttransformprocessor
, so I'm not sure of how to handle errors yet.)Then, we would be able to build a statement like the following that would do the dynamic injection with the hypothetical
add
editor:Eventually, we could call our custom function in a variety statements like in the following example:
I'm assuming here that there is a
toString
that converts the slice to a string, that I can call two functions in the same statement, and that we provided a custom functiondynamicSource
that returns a single string to be set as the value of attributetest.id
. We may find better examples if the above assumptions do not apply.Describe alternatives you've considered
We first considered the possibility of extending the
attributesprocessor
for this purpose, but after talking with the code owner, we realised that thetransformprocessor
would be the most suited processor.Additional context
In our team capacity planning, we have some room for contributing to OpenTelemetry, so we are more than happy to help with the implementation once we reach an agreement regarding what should be done.
The text was updated successfully, but these errors were encountered: