Skip to content

Commit 780ec50

Browse files
fix: correctly handle viper env var overrides for slice fields (#143)
### Description OB-40043: Correctly handle viper env var overrides for slice fields. We need this to specify host log overrides via env vars. This example works now but errored prior to this change: ``` $ env HOST_MONITORING::LOGS::INCLUDE='/test/file.txt,/file.log' ./observe-agent config # ======== computed agent config cloud_resource_detectors: - ec2 self_monitoring: enabled: true host_monitoring: enabled: true logs: enabled: true include: - /test/file.txt - /file.log metrics: host: enabled: true ``` ### Checklist - [ ] Created tests which fail without the change (if possible) - [ ] Extended the README / documentation, if necessary
1 parent 7b7eb8e commit 780ec50

File tree

4 files changed

+28
-43
lines changed

4 files changed

+28
-43
lines changed

internal/commands/config/config.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010

1111
"github.com/observeinc/observe-agent/internal/commands/start"
1212
logger "github.com/observeinc/observe-agent/internal/commands/util"
13+
"github.com/observeinc/observe-agent/internal/config"
1314
"github.com/observeinc/observe-agent/internal/root"
1415
"github.com/spf13/cobra"
1516
"github.com/spf13/viper"
@@ -30,19 +31,19 @@ OTEL configuration.`,
3031
if cleanup != nil {
3132
defer cleanup()
3233
}
33-
var viperConfig map[string]any
34-
if err := viper.Unmarshal(&viperConfig); err != nil {
34+
agentConfig, err := config.AgentConfigFromViper(viper.GetViper())
35+
if err != nil {
3536
return err
3637
}
37-
viperConfigYaml, err := yaml.Marshal(viperConfig)
38+
agentConfigYaml, err := yaml.Marshal(agentConfig)
3839
if err != nil {
3940
return err
4041
}
4142
fmt.Printf("# ======== computed agent config\n")
42-
fmt.Println(string(viperConfigYaml) + "\n")
43-
agentConfig := viper.ConfigFileUsed()
44-
if agentConfig != "" {
45-
configFilePaths = append([]string{agentConfig}, configFilePaths...)
43+
fmt.Println(string(agentConfigYaml) + "\n")
44+
agentConfigFile := viper.ConfigFileUsed()
45+
if agentConfigFile != "" {
46+
configFilePaths = append([]string{agentConfigFile}, configFilePaths...)
4647
}
4748
for _, filePath := range configFilePaths {
4849
file, err := os.ReadFile(filePath)

internal/config/configschema.go

Lines changed: 17 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,64 +7,48 @@ import (
77
"strings"
88

99
"github.com/spf13/viper"
10-
"gopkg.in/yaml.v3"
1110
)
1211

1312
type HostMonitoringLogsConfig struct {
14-
Enabled bool `yaml:"enabled"`
15-
Include []string `yaml:"include,omitempty"`
13+
Enabled bool `yaml:"enabled" mapstructure:"enabled"`
14+
Include []string `yaml:"include,omitempty" mapstructure:"include"`
1615
}
1716

1817
type HostMonitoringHostMetricsConfig struct {
19-
Enabled bool `yaml:"enabled"`
18+
Enabled bool `yaml:"enabled" mapstructure:"enabled"`
2019
}
2120

2221
type HostMonitoringProcessMetricsConfig struct {
23-
Enabled bool `yaml:"enabled"`
22+
Enabled bool `yaml:"enabled" mapstructure:"enabled"`
2423
}
2524

2625
type HostMonitoringMetricsConfig struct {
27-
Host HostMonitoringHostMetricsConfig `yaml:"host,omitempty"`
28-
Process HostMonitoringProcessMetricsConfig `yaml:"process,omitempty"`
26+
Host HostMonitoringHostMetricsConfig `yaml:"host,omitempty" mapstructure:"host"`
27+
Process HostMonitoringProcessMetricsConfig `yaml:"process,omitempty" mapstructure:"process"`
2928
}
3029

3130
type HostMonitoringConfig struct {
32-
Enabled bool `yaml:"enabled"`
33-
Logs HostMonitoringLogsConfig `yaml:"logs,omitempty"`
34-
Metrics HostMonitoringMetricsConfig `yaml:"metrics,omitempty"`
31+
Enabled bool `yaml:"enabled" mapstructure:"enabled"`
32+
Logs HostMonitoringLogsConfig `yaml:"logs,omitempty" mapstructure:"logs"`
33+
Metrics HostMonitoringMetricsConfig `yaml:"metrics,omitempty" mapstructure:"metrics"`
3534
}
3635

3736
type SelfMonitoringConfig struct {
38-
Enabled bool `yaml:"enabled"`
37+
Enabled bool `yaml:"enabled" mapstructure:"enabled"`
3938
}
4039

4140
type AgentConfig struct {
42-
Token string `yaml:"token"`
43-
ObserveURL string `yaml:"observe_url"`
44-
CloudResourceDetectors []string `yaml:"cloud_resource_detectors,omitempty"`
45-
SelfMonitoring SelfMonitoringConfig `yaml:"self_monitoring,omitempty"`
46-
HostMonitoring HostMonitoringConfig `yaml:"host_monitoring,omitempty"`
47-
OtelConfigOverrides map[string]any `yaml:"otel_config_overrides,omitempty"`
48-
}
49-
50-
func UnmarshalViperThroughYaml(v *viper.Viper, out any) error {
51-
// First unmarshal viper into a map
52-
var viperConfig map[string]any
53-
if err := viper.Unmarshal(&viperConfig); err != nil {
54-
return err
55-
}
56-
// Next convert the map into yaml bytes
57-
viperConfigYaml, err := yaml.Marshal(viperConfig)
58-
if err != nil {
59-
return err
60-
}
61-
// Finally unmarshal the yaml bytes into the out struct
62-
return yaml.Unmarshal(viperConfigYaml, out)
41+
Token string `yaml:"token" mapstructure:"token"`
42+
ObserveURL string `yaml:"observe_url" mapstructure:"observe_url"`
43+
CloudResourceDetectors []string `yaml:"cloud_resource_detectors,omitempty" mapstructure:"cloud_resource_detectors"`
44+
SelfMonitoring SelfMonitoringConfig `yaml:"self_monitoring,omitempty" mapstructure:"self_monitoring"`
45+
HostMonitoring HostMonitoringConfig `yaml:"host_monitoring,omitempty" mapstructure:"host_monitoring"`
46+
OtelConfigOverrides map[string]any `yaml:"otel_config_overrides,omitempty" mapstructure:"otel_config_overrides"`
6347
}
6448

6549
func AgentConfigFromViper(v *viper.Viper) (*AgentConfig, error) {
6650
var config AgentConfig
67-
err := UnmarshalViperThroughYaml(v, &config)
51+
err := v.Unmarshal(&config)
6852
if err != nil {
6953
return nil, err
7054
}

internal/connections/connections.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ func (c *ConnectionType) GetConfigFilePaths(ctx context.Context, tmpDir string)
8686
switch c.Type {
8787
case SelfMonitoringConnectionTypeName:
8888
conf := &config.SelfMonitoringConfig{}
89-
err := config.UnmarshalViperThroughYaml(rawConnConfig, conf)
89+
err := rawConnConfig.Unmarshal(conf)
9090
if err != nil {
9191
logger.FromCtx(ctx).Error("failed to unmarshal config", zap.String("connection", c.Name))
9292
return nil, err
@@ -97,7 +97,7 @@ func (c *ConnectionType) GetConfigFilePaths(ctx context.Context, tmpDir string)
9797
}
9898
case HostMonitoringConnectionTypeName:
9999
conf := &config.HostMonitoringConfig{}
100-
err := config.UnmarshalViperThroughYaml(rawConnConfig, conf)
100+
err := rawConnConfig.Unmarshal(conf)
101101
if err != nil {
102102
logger.FromCtx(ctx).Error("failed to unmarshal config", zap.String("connection", c.Name))
103103
return nil, err

packaging/docker/observe-agent/connections/host_monitoring/logs.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ receivers:
77
{{- end }}
88
{{- else }}
99
- /hostfs/var/log/**/*.log
10-
- /hostfs/var/log/syslog]
10+
- /hostfs/var/log/syslog
1111
{{- end }}
1212
include_file_path: true
1313
storage: file_storage

0 commit comments

Comments
 (0)