Skip to content

[processor/transform] Create WithAdditional*Funcs factory options and Validate*Statements to provide additional OTTL funcs programatically. #39966

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

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

franciscovalentecastro
Copy link

@franciscovalentecastro franciscovalentecastro commented May 9, 2025

Description

Create WithAdditionalMetricFunctions, WithAdditionalSpanFunctions and WithAdditionalLogFunctions factory options to add custom OTTL functions for logs, metrics or traces to the resulting processor. Also created the Config methods ValidateMetricStatements, ValidateLogStatements and ValidateSpanStatements to enable users to validate configs with the additional OTTL functions.

Some details about the solution :

  • To create a custom transform processor the user needs to create a NewFactory and Config.Validate functions providing the additional OTTL functions.
  • Since, as far as i understand, the collector design doesn't let the Config to access processor Factory, the Config.Validate method can't access the additional OTTL functions from the Factory. I circumvented this issue by creating the Validate*Statements helper functions which can be used to create a custom Config.Validate method to validate with the additional ottl functions.
  • This is a result of the discussion in this thread : [processor/transform] Create Additional*Funcs config properties to provide additional OTTL funcs programatically. #39641 (comment)
  • This is intended for developers of Opentelemetry Collector Distributions.

Link to tracking issue

Note : There is a similar followup proposed update for the processor/filter.

Testing

  • Added unit tests for the modified methods and functions.

Documentation

  • Added Additional OTTL Functions section to README.

Comment on lines +37 to +50
// defaultAdditionalMetricFunctions returns an empty slice of ottl function factories.
func defaultAdditionalMetricFunctions() []ottl.Factory[ottlmetric.TransformContext] {
return []ottl.Factory[ottlmetric.TransformContext]{}
}

// defaultAdditionalLogFunctions returns an empty slice of ottl function factories.
func defaultAdditionalLogFunctions() []ottl.Factory[ottllog.TransformContext] {
return []ottl.Factory[ottllog.TransformContext]{}
}

// defaultAdditionalSpanFunctions returns an empty slice of ottl function factories.
func defaultAdditionalSpanFunctions() []ottl.Factory[ottlspan.TransformContext] {
return []ottl.Factory[ottlspan.TransformContext]{}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This is equivalent to the zero value for these fields, so there's no need for these functions to exist.

@@ -726,6 +726,9 @@ transform:

The configuration can be used also with `delete_matching_keys()` to copy the attributes that do not match the regular expression.

## Additional OTTL Functions
The Factory Options `WithAdditionalMetricFunctions`, `WithAdditionalSpanFunctions` and `WithAdditionalLogFunctions` can be set in the transform processor `NewFactory` to add additional OTTL functions to the resulting processor. The `Config` methods `ValidateMetricStatements`, `ValidateSpanStatements` and `ValidateLogStatements` to receive the additional OTTL functions to validate the context statements. By setting a custom `NewFactory` and a custom `Config`, the user can create custom `transform` processor with any additional OTTL functions.
Copy link
Contributor

Choose a reason for hiding this comment

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

s/set in/set when calling/

I don't think there's any need to document the change to the Validate* methods in the README.

What is the "custom Config" you're referring to?

func (c *Config) Validate() error {
var errors error

if len(c.TraceStatements) > 0 {
pc, err := common.NewTraceParserCollection(component.TelemetrySettings{Logger: zap.NewNop()}, common.WithSpanParser(traces.SpanFunctions()), common.WithSpanEventParser(traces.SpanEventFunctions()))
err := c.ValidateTraceStatements()
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't you need to pass the new functions as arguments to the new methods you've defined here?

@@ -129,45 +132,72 @@ func (c *Config) Unmarshal(conf *confmap.Conf) error {

var _ component.Config = (*Config)(nil)

func (c *Config) ValidateTraceStatements(additionalSpanFuncs ...ottl.Factory[ottlspan.TransformContext]) error {
var errors error
pc, err := common.NewTraceParserCollection(component.TelemetrySettings{Logger: zap.NewNop()}, common.WithSpanParser(traces.SpanFunctions(additionalSpanFuncs)), common.WithSpanEventParser(traces.SpanEventFunctions()))
Copy link
Contributor

Choose a reason for hiding this comment

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

Aside from the first line, these functions are all iterating over a common.ContextStatements object and doing the same thing. You can refactor this into a single shared helper function.

Comment on lines +52 to +71
// WithAdditionalMetricFunctions adds ottl metric functions to resulting processor
func WithAdditionalMetricFunctions(metricFunctions []ottl.Factory[ottlmetric.TransformContext]) FactoryOption {
return func(factory *transformProcessorFactory) {
factory.additionalMetricFunctions = metricFunctions
}
}

// WithAdditionalLogFunctions adds ottl log functions to resulting processor
func WithAdditionalLogFunctions(logFunctions []ottl.Factory[ottllog.TransformContext]) FactoryOption {
return func(factory *transformProcessorFactory) {
factory.additionalLogFunctions = logFunctions
}
}

// WithAdditionalSpanFunctions adds ottl span functions to resulting processor
func WithAdditionalSpanFunctions(spanFunctions []ottl.Factory[ottlspan.TransformContext]) FactoryOption {
return func(factory *transformProcessorFactory) {
factory.additionalSpanFunctions = spanFunctions
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

These options should probably live in pkg/ottl so they can be shared by multiple processors, instead of having to be duplicated in each processor that uses OTTL.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
processor/transform Transform processor
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants