Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .chloggen/13256.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Use this changelog template to create an entry for release notes.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver)
component: pkg/confmap

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Add YAML tag based list merging strategy.

# One or more tracking issues or pull requests related to the change
issues: [8754]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:

# Optional: The change log or logs in which this entry should be included.
# e.g. '[user]' or '[user, api]'
# Include 'user' if the change is relevant to end users.
# Include 'api' if there is a change to a library API.
# Default: '[user]'
change_logs: []
1 change: 0 additions & 1 deletion cmd/mdatagen/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ require (
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
Expand Down
2 changes: 0 additions & 2 deletions cmd/mdatagen/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion cmd/otelcorecol/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ require (
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/snappy v1.0.0 // indirect
github.com/google/go-tpm v0.9.6 // indirect
Expand Down
2 changes: 0 additions & 2 deletions cmd/otelcorecol/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion config/configgrpc/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ require (
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/go-tpm v0.9.6 // indirect
Expand Down
2 changes: 0 additions & 2 deletions config/configgrpc/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion config/confighttp/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ require (
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/go-tpm v0.9.6 // indirect
github.com/google/uuid v1.6.0 // indirect
Expand Down
2 changes: 0 additions & 2 deletions config/confighttp/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion config/confighttp/xconfighttp/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ require (
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/snappy v1.0.0 // indirect
github.com/google/go-tpm v0.9.6 // indirect
Expand Down
2 changes: 0 additions & 2 deletions config/confighttp/xconfighttp/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion config/configoptional/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ require (
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
github.com/knadh/koanf/maps v0.1.2 // indirect
github.com/knadh/koanf/providers/confmap v1.0.0 // indirect
Expand Down
2 changes: 0 additions & 2 deletions config/configoptional/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion config/configtls/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ require (
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/google/go-tpm-tools v0.4.4 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
github.com/knadh/koanf/maps v0.1.2 // indirect
Expand Down
2 changes: 0 additions & 2 deletions config/configtls/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 30 additions & 13 deletions confmap/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,32 @@ The `Resolve` method proceeds in the following steps:
#### (Experimental) Append merging strategy for lists

You can opt-in to experimentally combine slices instead of discarding the existing ones by enabling the `confmap.enableMergeAppendOption` feature flag. Lists are appended in the order in which they appear in their configuration sources.
This will **not** become the default in the future, we are still deciding how this should be configured and want your feedback on [this issue](https://github.com/open-telemetry/opentelemetry-collector/issues/8754).
This lets you combine slices from multiple configuration sources, with control over ordering, duplicates, and targeted merge paths using YAML tags or URI query parameters.

#### How It Works

Annotate any list in your YAML config with a custom tag (URI-style parameters) to specify how it should be merged.

**Tag format:**
`!mode=append&duplicates=false`

**Options:**
- `mode`: `append` (default)
Copy link
Member

Choose a reason for hiding this comment

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

This is a bit confusing, what does it mean for this to be the default? I guess this is the "default for annotated lists"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. I'll make this verbose to remove the ambiguity.

- `duplicates`: `true` or `false` (default: `false`)
- Setting this to `true` allows duplicate entries in the final list.
Comment on lines +110 to +111
Copy link
Member

Choose a reason for hiding this comment

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

Is this something that we could add later or is it required from the start?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can add this later. For now, we can say that we "skip duplicates"


> [!WARNING]
> Specifying incorrect values in YAML tags will result in fallback to the default behavior.
Comment on lines +113 to +114
Copy link
Member

Choose a reason for hiding this comment

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

Is there any way to fail fast in this case instead of falling back to the default behavior?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. I'll update the function to validate tags and return error if invalid options are specified.


#### Default Behavior (Override)

If you do **NOT** specify any merge options or tags, lists are merged using the default override behavior (the last config wins).

##### Example
Consider the following configs,

Suppose you have the following configurations:

**main.yaml**
```yaml
# main.yaml
receivers:
Expand All @@ -126,24 +147,20 @@ service:
extensions: [ file_storage ]
```


**extra_extension.yaml**
```yaml
# extra_extension.yaml
extensions:
healthcheckv2:

service:
extensions: [ healthcheckv2 ]
pipelines:
traces:
extensions: !mode=append [healthcheckv2]
```

If you run the Collector with following command,
```
If you run the Collector with:
```bash
otelcol --config=main.yaml --config=extra_extension.yaml --feature-gates=confmap.enableMergeAppendOption
```
then the final configuration after config resolution will look like following:

The result after merging will be:
```yaml
# main.yaml
receivers:
Expand All @@ -169,10 +186,10 @@ service:
extensions: [ file_storage, healthcheckv2 ]
```

Notice that the `service::extensions` list is a combination of both configurations. By default, the value of the last configuration source passed, `extra_extension`, would be used, so the extensions list would be: `service::extensions: [healthcheckv2]`.
Notice how the `service::extensions` list is a combination of both configurations, preserving both values.

> [!NOTE]
> By enabling this feature gate, all the lists in the given configuration will be merged.
> By enabling this feature gate, only the lists annotated with YAML merge tags will be merged according to your specified strategy. Unannotated lists will continue to use the default override behavior (last list wins).

### Watching for Updates
After the configuration was processed, the `Resolver` can be used as a single point to watch for updates in the
Expand Down
1 change: 0 additions & 1 deletion confmap/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ go 1.24.0

require (
github.com/go-viper/mapstructure/v2 v2.4.0
github.com/gobwas/glob v0.2.3
github.com/knadh/koanf/maps v0.1.2
github.com/knadh/koanf/providers/confmap v1.0.0
github.com/knadh/koanf/v2 v2.3.0
Expand Down
2 changes: 0 additions & 2 deletions confmap/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion confmap/internal/conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ type Conf struct {
// isNil is true if this Conf was created from a nil field, as opposed to an empty map.
// AllKeys must return an empty slice if this is true.
isNil bool

mergeOpts map[string]*MergeOptions
}

// New creates a new empty confmap.Conf instance.
Expand All @@ -51,6 +53,11 @@ func NewFromStringMap(data map[string]any) *Conf {
return p
}

func (l *Conf) WithMergeOptions(opt map[string]*MergeOptions) *Conf {
l.mergeOpts = opt
return l
}

// Unmarshal unmarshalls the config into a struct using the given options.
// Tags on the fields of the structure must be properly set.
func (l *Conf) Unmarshal(result any, opts ...UnmarshalOption) error {
Expand Down Expand Up @@ -122,7 +129,7 @@ func (l *Conf) Delete(key string) bool {
// For example, if listA = [extension1, extension2] and listB = [extension1, extension3],
// the resulting list will be [extension1, extension2, extension3].
func (l *Conf) mergeAppend(in *Conf) error {
err := l.k.Load(confmap.Provider(in.ToStringMap(), ""), nil, koanf.WithMergeFunc(mergeAppend))
err := l.k.Load(confmap.Provider(in.ToStringMap(), ""), nil, koanf.WithMergeFunc(mergeAppend(in.mergeOpts)))
if err != nil {
return err
}
Expand Down
1 change: 0 additions & 1 deletion confmap/internal/e2e/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ require (
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
github.com/knadh/koanf/maps v0.1.2 // indirect
github.com/knadh/koanf/providers/confmap v1.0.0 // indirect
Expand Down
2 changes: 0 additions & 2 deletions confmap/internal/e2e/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading