Skip to content
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

[service] Add omitempty tag to config fields #12501

Merged
merged 1 commit into from
Feb 27, 2025
Merged
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/service-omitempty.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: service

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Add the `omitempty` mapstructure tag to struct fields

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

# (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: This results in unset fields not being rendered when marshaling.

# 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: [api]
2 changes: 1 addition & 1 deletion service/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type Config struct {
Telemetry telemetry.Config `mapstructure:"telemetry"`

// Extensions are the ordered list of extensions configured for the service.
Extensions extensions.Config `mapstructure:"extensions"`
Extensions extensions.Config `mapstructure:"extensions,omitempty"`

// Pipelines are the set of data pipelines configured for the service.
Pipelines pipelines.Config `mapstructure:"pipelines"`
Expand Down
51 changes: 51 additions & 0 deletions service/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ package service
import (
"errors"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
config "go.opentelemetry.io/contrib/config/v0.3.0"
"go.uber.org/zap/zapcore"

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config/configtelemetry"
"go.opentelemetry.io/collector/confmap"
"go.opentelemetry.io/collector/confmap/xconfmap"
"go.opentelemetry.io/collector/pipeline"
"go.opentelemetry.io/collector/service/extensions"
Expand Down Expand Up @@ -88,6 +91,54 @@ func TestConfigValidate(t *testing.T) {
}
}

func TestConfmapMarshalConfig(t *testing.T) {
telFactory := telemetry.NewFactory()
defaultTelConfig := *telFactory.CreateDefaultConfig().(*telemetry.Config)
conf := confmap.New()

require.NoError(t, conf.Marshal(Config{
Telemetry: defaultTelConfig,
}))
assert.Equal(t, map[string]any{
"pipelines": map[string]any{},
"telemetry": map[string]any{
"logs": map[string]any{
"encoding": "console",
"level": "info",
"error_output_paths": []any{"stderr"},
"output_paths": []any{"stderr"},
"sampling": map[string]any{
"enabled": true,
"initial": 10,
"thereafter": 100,
"tick": 10 * time.Second,
},
},
"metrics": map[string]any{
"level": "Normal",
"readers": []any{
map[string]any{
"pull": map[string]any{
"exporter": map[string]any{
"prometheus": map[string]any{
"host": "localhost",
"port": 8888,
"with_resource_constant_labels": map[string]any{
"included": []any(nil),
},
"without_scope_info": true,
"without_type_suffix": true,
"without_units": true,
},
},
},
},
},
},
},
}, conf.ToStringMap())
}

func generateConfig() *Config {
return &Config{
Telemetry: telemetry.Config{
Expand Down
4 changes: 2 additions & 2 deletions service/telemetry/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ var disableAddressFieldForInternalTelemetryFeatureGate = featuregate.GlobalRegis
type Config struct {
Logs LogsConfig `mapstructure:"logs"`
Metrics MetricsConfig `mapstructure:"metrics"`
Comment on lines 31 to 32
Copy link
Member

Choose a reason for hiding this comment

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

Do these need omitempty too?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I probably should have included this in the PR description, my bad. I only added omitempty to fields where the zero value is also the default. Otherwise the zero value won't be emitted during serialization and it would be impossible to generate configs that set the zero value.

For these fields, we have default configurations for both the Logs and Metrics fields, so I didn't add omitempty so they can be unset if need be.

Traces TracesConfig `mapstructure:"traces"`
Traces TracesConfig `mapstructure:"traces,omitempty"`

// Resource specifies user-defined attributes to include with all emitted telemetry.
// Note that some attributes are added automatically (e.g. service.version) even
// if they are not specified here. In order to suppress such attributes the
// attribute must be specified in this map with null YAML value (nil string pointer).
Resource map[string]*string `mapstructure:"resource"`
Resource map[string]*string `mapstructure:"resource,omitempty"`
}

// LogsConfig defines the configurable settings for service telemetry logs.
Expand Down
14 changes: 7 additions & 7 deletions service/telemetry/internal/migration/v0.3.0.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ type MetricsConfigV030 struct {
Level configtelemetry.Level `mapstructure:"level"`

// Deprecated: [v0.111.0] use readers configuration.
Address string `mapstructure:"address"`
Address string `mapstructure:"address,omitempty"`

// Readers allow configuration of metric readers to emit metrics to
// any number of supported backends.
Expand Down Expand Up @@ -110,7 +110,7 @@ type LogsConfigV030 struct {
// Development puts the logger in development mode, which changes the
// behavior of DPanicLevel and takes stacktraces more liberally.
// (default = false)
Development bool `mapstructure:"development"`
Development bool `mapstructure:"development,omitempty"`

// Encoding sets the logger's encoding.
// Example values are "json", "console".
Expand All @@ -119,13 +119,13 @@ type LogsConfigV030 struct {
// DisableCaller stops annotating logs with the calling function's file
// name and line number. By default, all logs are annotated.
// (default = false)
DisableCaller bool `mapstructure:"disable_caller"`
DisableCaller bool `mapstructure:"disable_caller,omitempty"`

// DisableStacktrace completely disables automatic stacktrace capturing. By
// default, stacktraces are captured for WarnLevel and above logs in
// development and ErrorLevel and above in production.
// (default = false)
DisableStacktrace bool `mapstructure:"disable_stacktrace"`
DisableStacktrace bool `mapstructure:"disable_stacktrace,omitempty"`

// Sampling sets a sampling policy.
// Default:
Expand Down Expand Up @@ -164,11 +164,11 @@ type LogsConfigV030 struct {
// foo: "bar"
//
// By default, there is no initial field.
InitialFields map[string]any `mapstructure:"initial_fields"`
InitialFields map[string]any `mapstructure:"initial_fields,omitempty"`

// Processors allow configuration of log record processors to emit logs to
// any number of suported backends.
Processors []config.LogRecordProcessor `mapstructure:"processors"`
// any number of supported backends.
Processors []config.LogRecordProcessor `mapstructure:"processors,omitempty"`
}

// LogsSamplingConfig sets a sampling strategy for the logger. Sampling caps the
Expand Down
Loading