Skip to content

Commit 3715910

Browse files
refactor: split main otel config into multiple connections, add tests
1 parent e519ab0 commit 3715910

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+895
-368
lines changed

.goreleaser.yaml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,10 @@ archives:
7474
{{- else }}{{ .Arch }}{{ end }}
7575
{{- if .Arm }}v{{ .Arm }}{{ end }}
7676
files:
77-
- src: "packaging/windows/config/otel-collector.yaml"
78-
dst: "otel-collector.yaml"
7977
- src: "packaging/windows/observe-agent.yaml"
8078
dst: "observe-agent.yaml"
81-
- src: "packaging/windows/connections/host_monitoring/*"
82-
dst: "connections/host_monitoring"
83-
- src: "packaging/windows/connections/self_monitoring/*"
84-
dst: "connections/self_monitoring"
79+
- src: "packaging/windows/connections/*"
80+
dst: "connections"
8581

8682
- id: macos
8783
formats: ["zip"]

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.23.7
55
require (
66
github.com/go-viper/mapstructure/v2 v2.2.1
77
github.com/jarcoal/httpmock v1.3.1
8+
github.com/mcuadros/go-defaults v1.2.0
89
github.com/observeinc/observe-agent/observecol v0.0.0-00010101000000-000000000000
910
github.com/prometheus/client_model v0.6.1
1011
github.com/prometheus/common v0.62.0

integration/scripts/install_windows.ps1

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ $temp_dir="C:\temp"
1818
#Create directories for temp & observe-agent installation ls
1919
New-Item -ItemType Directory -Force -Path $temp_dir
2020
New-Item -ItemType Directory -Force -Path $observeagent_install_dir
21-
New-Item -ItemType Directory -Force -Path $observeagent_install_dir\config
21+
New-Item -ItemType Directory -Force -Path $observeagent_install_dir\connections
2222
New-Item -ItemType Directory -Force -Path $program_data_filestorage
2323

2424
# Stop the observe agent if its running so that we can copy the new .exe
@@ -36,7 +36,6 @@ Expand-Archive -Force -LiteralPath $local_installer -DestinationPath "$temp_dir
3636
Write-Output "Copying files from $temp_dir\observe-agent_extract to $observeagent_install_dir"
3737
Copy-Item -Force -Path $temp_dir\observe-agent_extract\observe-agent.exe -Destination $observeagent_install_dir
3838
Copy-Item -Force -Path $temp_dir\observe-agent_extract\observe-agent.yaml -Destination $observeagent_install_dir
39-
Copy-Item -Force -Path $temp_dir\observe-agent_extract\otel-collector.yaml -Destination $observeagent_install_dir\config\otel-collector.yaml
4039
Copy-Item -Force -Path $temp_dir\observe-agent_extract\connections\ -Destination $observeagent_install_dir\connections -Recurse
4140

4241

internal/commands/config/config.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ func printAllConfigsIndividually(configFilePaths []string) error {
8989
}
9090

9191
func printShortOtelConfig(ctx context.Context, configFilePaths []string) error {
92+
if len(configFilePaths) == 0 {
93+
return nil
94+
}
9295
settings := observecol.ConfigProviderSettings(configFilePaths)
9396
resolver, err := confmap.NewResolver(settings.ResolverSettings)
9497
if err != nil {
@@ -107,6 +110,9 @@ func printShortOtelConfig(ctx context.Context, configFilePaths []string) error {
107110
}
108111

109112
func printFullOtelConfig(configFilePaths []string) error {
113+
if len(configFilePaths) == 0 {
114+
return nil
115+
}
110116
colSettings := observecol.GenerateCollectorSettingsWithConfigFiles(configFilePaths)
111117
factories, err := colSettings.Factories()
112118
if err != nil {

internal/commands/initconfig/initconfig_test.go

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import (
44
"os"
55
"testing"
66

7+
"github.com/go-viper/mapstructure/v2"
78
"github.com/observeinc/observe-agent/internal/config"
89
"github.com/spf13/viper"
910
"github.com/stretchr/testify/assert"
10-
"gopkg.in/yaml.v2"
11+
"gopkg.in/yaml.v3"
1112
)
1213

1314
func Test_InitConfigCommand(t *testing.T) {
@@ -77,17 +78,31 @@ func Test_InitConfigCommand(t *testing.T) {
7778
if err != nil {
7879
if tc.expectErr == "" {
7980
t.Errorf("Expected no error, got %v", err)
81+
} else {
82+
assert.ErrorContains(t, err, tc.expectErr)
8083
}
8184
}
82-
var config config.AgentConfig
83-
configFile, err := os.ReadFile("./test-config.yaml")
84-
if err != nil {
85-
t.Errorf("Expected no error, got %v", err)
86-
}
87-
err = yaml.Unmarshal(configFile, &config)
88-
if err != nil {
89-
t.Errorf("Expected no error, got %v", err)
90-
}
91-
assert.Equal(t, tc.expectedConfig, config)
85+
86+
var configYaml, configMapstructure config.AgentConfig
87+
88+
// Decode via mapstrucutre (which is how viper does it)
89+
configFileContents, err := os.ReadFile("./test-config.yaml")
90+
assert.NoError(t, err)
91+
var yamlMap map[string]any
92+
err = yaml.Unmarshal(configFileContents, &yamlMap)
93+
assert.NoError(t, err)
94+
err = mapstructure.Decode(yamlMap, &configMapstructure)
95+
assert.NoError(t, err)
96+
assert.Equal(t, tc.expectedConfig, configMapstructure)
97+
98+
// Decode via yaml in order to do strict field checks
99+
configFile, err := os.Open("./test-config.yaml")
100+
assert.NoError(t, err)
101+
decoder := yaml.NewDecoder(configFile)
102+
// Ensure that all fields in the output yaml are present in our struct
103+
decoder.KnownFields(true)
104+
err = decoder.Decode(&configYaml)
105+
assert.NoError(t, err)
106+
assert.Equal(t, tc.expectedConfig, configYaml)
92107
}
93108
}

internal/config/configschema.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"net/url"
77
"strings"
88

9+
"github.com/mcuadros/go-defaults"
910
"github.com/spf13/viper"
1011
)
1112

@@ -38,17 +39,29 @@ type SelfMonitoringConfig struct {
3839
Enabled bool `yaml:"enabled" mapstructure:"enabled"`
3940
}
4041

42+
type HealthCheckConfig struct {
43+
Enabled bool `yaml:"enabled" mapstructure:"enabled" default:"true"`
44+
}
45+
46+
type ForwardingConfig struct {
47+
Enabled bool `yaml:"enabled" mapstructure:"enabled" default:"true"`
48+
}
49+
4150
type AgentConfig struct {
4251
Token string `yaml:"token" mapstructure:"token"`
4352
ObserveURL string `yaml:"observe_url" mapstructure:"observe_url"`
4453
CloudResourceDetectors []string `yaml:"cloud_resource_detectors,omitempty" mapstructure:"cloud_resource_detectors"`
54+
Debug bool `yaml:"debug,omitempty" mapstructure:"debug"`
55+
HealthCheck HealthCheckConfig `yaml:"health_check" mapstructure:"health_check"`
56+
Forwarding ForwardingConfig `yaml:"forwarding" mapstructure:"forwarding"`
4557
SelfMonitoring SelfMonitoringConfig `yaml:"self_monitoring,omitempty" mapstructure:"self_monitoring"`
4658
HostMonitoring HostMonitoringConfig `yaml:"host_monitoring,omitempty" mapstructure:"host_monitoring"`
4759
OtelConfigOverrides map[string]any `yaml:"otel_config_overrides,omitempty" mapstructure:"otel_config_overrides"`
4860
}
4961

5062
func AgentConfigFromViper(v *viper.Viper) (*AgentConfig, error) {
5163
var config AgentConfig
64+
defaults.SetDefaults(&config)
5265
err := v.Unmarshal(&config)
5366
if err != nil {
5467
return nil, err

internal/config/configschema_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package config
33
import (
44
"testing"
55

6+
"github.com/spf13/viper"
67
"github.com/stretchr/testify/assert"
78
)
89

@@ -43,3 +44,26 @@ func TestAgentConfigValidate(t *testing.T) {
4344
}
4445
assert.ErrorContains(t, invalidTokenConfig.Validate(), "invalid Token")
4546
}
47+
48+
func TestAgentConfigFromViper(t *testing.T) {
49+
v := viper.NewWithOptions(viper.KeyDelimiter("::"))
50+
v.Set("token", "some:token")
51+
v.Set("observe_url", "https://observeinc.com")
52+
v.Set("host_monitoring::enabled", true)
53+
config, err := AgentConfigFromViper(v)
54+
assert.NoError(t, err)
55+
assert.Equal(t, "some:token", config.Token)
56+
assert.Equal(t, "https://observeinc.com", config.ObserveURL)
57+
assert.Equal(t, true, config.HostMonitoring.Enabled)
58+
59+
// Validate that defaults are set when the value is not in the viper config
60+
assert.Equal(t, true, config.HealthCheck.Enabled)
61+
assert.Equal(t, true, config.Forwarding.Enabled)
62+
63+
// Validate that defaults are overridden by present values
64+
v.Set("health_check::enabled", false)
65+
config, err = AgentConfigFromViper(v)
66+
assert.NoError(t, err)
67+
assert.Equal(t, false, config.HealthCheck.Enabled)
68+
assert.Equal(t, true, config.Forwarding.Enabled)
69+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package connections
2+
3+
import "github.com/observeinc/observe-agent/internal/config"
4+
5+
var AllConnectionTypes = []*ConnectionType{
6+
// NB: whenever a new connection type is added here, it's enable check
7+
// should be reflected in the base fragment enable check.
8+
CommonConnectionType,
9+
HostMonitoringConnectionType,
10+
SelfMonitoringConnectionType,
11+
}
12+
13+
var CommonConnectionType = MakeConnectionType(
14+
"common",
15+
func(_ *config.AgentConfig) bool {
16+
return true
17+
},
18+
[]CollectorConfigFragment{
19+
{
20+
enabledCheck: func(agentConfig *config.AgentConfig) bool {
21+
return (agentConfig.Forwarding.Enabled ||
22+
agentConfig.HealthCheck.Enabled ||
23+
agentConfig.SelfMonitoring.Enabled ||
24+
agentConfig.HostMonitoring.Enabled)
25+
},
26+
colConfigFilePath: "base.yaml.tmpl",
27+
},
28+
{
29+
enabledCheck: func(agentConfig *config.AgentConfig) bool {
30+
return agentConfig.Forwarding.Enabled
31+
},
32+
colConfigFilePath: "forward.yaml.tmpl",
33+
},
34+
{
35+
enabledCheck: func(agentConfig *config.AgentConfig) bool {
36+
return agentConfig.HealthCheck.Enabled
37+
},
38+
colConfigFilePath: "health_check.yaml.tmpl",
39+
},
40+
},
41+
)
42+
43+
var HostMonitoringConnectionType = MakeConnectionType(
44+
"host_monitoring",
45+
func(agentConfig *config.AgentConfig) bool {
46+
return agentConfig.HostMonitoring.Enabled
47+
},
48+
[]CollectorConfigFragment{
49+
{
50+
enabledCheck: func(agentConfig *config.AgentConfig) bool {
51+
return agentConfig.HostMonitoring.Enabled
52+
},
53+
colConfigFilePath: "host.yaml.tmpl",
54+
},
55+
{
56+
enabledCheck: func(agentConfig *config.AgentConfig) bool {
57+
return agentConfig.HostMonitoring.Metrics.Host.Enabled
58+
},
59+
colConfigFilePath: "host_metrics.yaml.tmpl",
60+
},
61+
{
62+
enabledCheck: func(agentConfig *config.AgentConfig) bool {
63+
return agentConfig.HostMonitoring.Metrics.Process.Enabled
64+
},
65+
colConfigFilePath: "process_metrics.yaml.tmpl",
66+
},
67+
{
68+
enabledCheck: func(agentConfig *config.AgentConfig) bool {
69+
return agentConfig.HostMonitoring.Logs.Enabled
70+
},
71+
colConfigFilePath: "logs.yaml.tmpl",
72+
},
73+
},
74+
)
75+
76+
var SelfMonitoringConnectionType = MakeConnectionType(
77+
"self_monitoring",
78+
func(agentConfig *config.AgentConfig) bool {
79+
return agentConfig.SelfMonitoring.Enabled
80+
},
81+
[]CollectorConfigFragment{
82+
{
83+
enabledCheck: func(agentConfig *config.AgentConfig) bool {
84+
return agentConfig.SelfMonitoring.Enabled
85+
},
86+
colConfigFilePath: "logs_and_metrics.yaml.tmpl",
87+
},
88+
},
89+
)

internal/connections/confighandler.go

Lines changed: 8 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,28 +20,17 @@ const (
2020

2121
func GetAllOtelConfigFilePaths(ctx context.Context, tmpDir string) ([]string, error) {
2222
configFilePaths := []string{}
23-
// If the default otel-collector.yaml exists, add it to the list of config files
24-
defaultOtelConfigPath := filepath.Join(GetDefaultConfigFolder(), "otel-collector.yaml")
25-
if _, err := os.Stat(defaultOtelConfigPath); err == nil {
26-
agentConf, err := config.AgentConfigFromViper(viper.GetViper())
27-
if err != nil {
28-
return nil, err
29-
}
30-
otelConfigRendered, err := RenderConfigTemplate(ctx, tmpDir, defaultOtelConfigPath, agentConf)
31-
if err != nil {
32-
return nil, err
33-
}
34-
configFilePaths = append(configFilePaths, otelConfigRendered)
35-
}
3623
// Get additional config paths based on connection configs
24+
agentConfig, err := config.AgentConfigFromViper(viper.GetViper())
25+
if err != nil {
26+
return nil, err
27+
}
3728
for _, conn := range AllConnectionTypes {
38-
if viper.IsSet(conn.Name) {
39-
connectionPaths, err := conn.GetConfigFilePaths(ctx, tmpDir)
40-
if err != nil {
41-
return nil, err
42-
}
43-
configFilePaths = append(configFilePaths, connectionPaths...)
29+
connectionPaths, err := conn.GetConfigFilePaths(ctx, tmpDir, agentConfig)
30+
if err != nil {
31+
return nil, err
4432
}
33+
configFilePaths = append(configFilePaths, connectionPaths...)
4534
}
4635
// Generate override file and include path if overrides provided
4736
if viper.IsSet(OTEL_OVERRIDE_YAML_KEY) {
@@ -119,19 +108,6 @@ func GetOverrideConfigFile(tmpDir string, data map[string]any) (string, error) {
119108
return f.Name(), nil
120109
}
121110

122-
func GetDefaultConfigFolder() string {
123-
switch currOS := runtime.GOOS; currOS {
124-
case "darwin":
125-
return filepath.Join(GetDefaultAgentPath(), "config")
126-
case "windows":
127-
return filepath.Join(GetDefaultAgentPath(), "config")
128-
case "linux":
129-
return GetDefaultAgentPath()
130-
default:
131-
return GetDefaultAgentPath()
132-
}
133-
}
134-
135111
func GetConfigFragmentFolderPath() string {
136112
return filepath.Join(GetDefaultAgentPath(), "connections")
137113
}

0 commit comments

Comments
 (0)