Skip to content

Commit

Permalink
[chore] Refactor hostmetrics receiver to use component.Type
Browse files Browse the repository at this point in the history
Signed-off-by: Bogdan Drutu <[email protected]>
  • Loading branch information
bogdandrutu committed Dec 20, 2024
1 parent e2601fb commit 896373f
Show file tree
Hide file tree
Showing 17 changed files with 134 additions and 174 deletions.
44 changes: 21 additions & 23 deletions receiver/hostmetricsreceiver/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,14 @@ import (
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal"
)

const (
scrapersKey = "scrapers"
)

// Config defines configuration for HostMetrics receiver.
type Config struct {
scraperhelper.ControllerConfig `mapstructure:",squash"`
Scrapers map[string]internal.Config `mapstructure:"-"`
// RootPath is the host's root directory (linux only).
RootPath string `mapstructure:"root_path"`

Scrapers map[component.Type]internal.Config `mapstructure:"-"`

// Collection interval for metadata.
// Metadata of the particular entity is collected when the entity changes.
// In addition metadata of all entities is collected periodically even if no changes happen.
Expand All @@ -36,18 +33,17 @@ type Config struct {
}

var (
_ component.Config = (*Config)(nil)
_ confmap.Unmarshaler = (*Config)(nil)
_ component.ConfigValidator = (*Config)(nil)
_ confmap.Unmarshaler = (*Config)(nil)
)

// Validate checks the receiver configuration is valid
func (cfg *Config) Validate() error {
var err error
if len(cfg.Scrapers) == 0 {
err = multierr.Append(err, errors.New("must specify at least one scraper when using hostmetrics receiver"))
err = errors.New("must specify at least one scraper when using hostmetrics receiver")
}
err = multierr.Append(err, validateRootPath(cfg.RootPath))
return err
return multierr.Append(err, validateRootPath(cfg.RootPath))
}

// Unmarshal a config.Parser into the config struct.
Expand All @@ -57,41 +53,43 @@ func (cfg *Config) Unmarshal(componentParser *confmap.Conf) error {
}

// load the non-dynamic config normally
err := componentParser.Unmarshal(cfg, confmap.WithIgnoreUnused())
if err != nil {
if err := componentParser.Unmarshal(cfg, confmap.WithIgnoreUnused()); err != nil {
return err
}

// dynamically load the individual collector configs based on the key name

cfg.Scrapers = map[string]internal.Config{}
cfg.Scrapers = map[component.Type]internal.Config{}

scrapersSection, err := componentParser.Sub(scrapersKey)
scrapersSection, err := componentParser.Sub("scrapers")
if err != nil {
return err
}

for key := range scrapersSection.ToStringMap() {
factory, ok := getScraperFactory(key)
for keyStr := range scrapersSection.ToStringMap() {
key, err := component.NewType(keyStr)
if err != nil {
return fmt.Errorf("invalid scraper key name: %s", key)
}
factory, ok := scraperFactories[key]
if !ok {
return fmt.Errorf("invalid scraper key: %s", key)
}

collectorCfg := factory.CreateDefaultConfig()
collectorViperSection, err := scrapersSection.Sub(key)
scraperSection, err := scrapersSection.Sub(keyStr)
if err != nil {
return err
}
err = collectorViperSection.Unmarshal(collectorCfg)
if err != nil {
scraperCfg := factory.CreateDefaultConfig()
if err = scraperSection.Unmarshal(scraperCfg); err != nil {
return fmt.Errorf("error reading settings for scraper type %q: %w", key, err)
}

collectorCfg.SetRootPath(cfg.RootPath)
scraperCfg.SetRootPath(cfg.RootPath)
envMap := setGoPsutilEnvVars(cfg.RootPath, &osEnv{})
collectorCfg.SetEnvMap(envMap)
scraperCfg.SetEnvMap(envMap)

cfg.Scrapers[key] = collectorCfg
cfg.Scrapers[key] = scraperCfg
}

return nil
Expand Down
26 changes: 13 additions & 13 deletions receiver/hostmetricsreceiver/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ func TestLoadConfig(t *testing.T) {
id: component.NewID(metadata.Type),
expected: func() component.Config {
cfg := createDefaultConfig().(*Config)
cfg.Scrapers = map[string]internal.Config{
cpuscraper.TypeStr: func() internal.Config {
cfg.Scrapers = map[component.Type]internal.Config{
cpuscraper.Type: func() internal.Config {
cfg := (&cpuscraper.Factory{}).CreateDefaultConfig()
cfg.SetEnvMap(common.EnvMap{})
return cfg
Expand All @@ -62,34 +62,34 @@ func TestLoadConfig(t *testing.T) {
CollectionInterval: 30 * time.Second,
InitialDelay: time.Second,
},
Scrapers: map[string]internal.Config{
cpuscraper.TypeStr: func() internal.Config {
Scrapers: map[component.Type]internal.Config{
cpuscraper.Type: func() internal.Config {
cfg := (&cpuscraper.Factory{}).CreateDefaultConfig()
cfg.SetEnvMap(common.EnvMap{})
return cfg
}(),
diskscraper.TypeStr: func() internal.Config {
diskscraper.Type: func() internal.Config {
cfg := (&diskscraper.Factory{}).CreateDefaultConfig()
cfg.SetEnvMap(common.EnvMap{})
return cfg
}(),
loadscraper.TypeStr: (func() internal.Config {
loadscraper.Type: (func() internal.Config {
cfg := (&loadscraper.Factory{}).CreateDefaultConfig()
cfg.(*loadscraper.Config).CPUAverage = true
cfg.SetEnvMap(common.EnvMap{})
return cfg
})(),
filesystemscraper.TypeStr: func() internal.Config {
filesystemscraper.Type: func() internal.Config {
cfg := (&filesystemscraper.Factory{}).CreateDefaultConfig()
cfg.SetEnvMap(common.EnvMap{})
return cfg
}(),
memoryscraper.TypeStr: func() internal.Config {
memoryscraper.Type: func() internal.Config {
cfg := (&memoryscraper.Factory{}).CreateDefaultConfig()
cfg.SetEnvMap(common.EnvMap{})
return cfg
}(),
networkscraper.TypeStr: (func() internal.Config {
networkscraper.Type: (func() internal.Config {
cfg := (&networkscraper.Factory{}).CreateDefaultConfig()
cfg.(*networkscraper.Config).Include = networkscraper.MatchConfig{
Interfaces: []string{"test1"},
Expand All @@ -98,17 +98,17 @@ func TestLoadConfig(t *testing.T) {
cfg.SetEnvMap(common.EnvMap{})
return cfg
})(),
processesscraper.TypeStr: func() internal.Config {
processesscraper.Type: func() internal.Config {
cfg := (&processesscraper.Factory{}).CreateDefaultConfig()
cfg.SetEnvMap(common.EnvMap{})
return cfg
}(),
pagingscraper.TypeStr: func() internal.Config {
pagingscraper.Type: func() internal.Config {
cfg := (&pagingscraper.Factory{}).CreateDefaultConfig()
cfg.SetEnvMap(common.EnvMap{})
return cfg
}(),
processscraper.TypeStr: (func() internal.Config {
processscraper.Type: (func() internal.Config {
cfg := (&processscraper.Factory{}).CreateDefaultConfig()
cfg.(*processscraper.Config).Include = processscraper.MatchConfig{
Names: []string{"test2", "test3"},
Expand All @@ -117,7 +117,7 @@ func TestLoadConfig(t *testing.T) {
cfg.SetEnvMap(common.EnvMap{})
return cfg
})(),
systemscraper.TypeStr: (func() internal.Config {
systemscraper.Type: (func() internal.Config {
cfg := (&systemscraper.Factory{}).CreateDefaultConfig()
cfg.SetEnvMap(common.EnvMap{})
return cfg
Expand Down
34 changes: 13 additions & 21 deletions receiver/hostmetricsreceiver/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,17 @@ const (

// This file implements Factory for HostMetrics receiver.
var (
scraperFactories = map[string]internal.ScraperFactory{
cpuscraper.TypeStr: &cpuscraper.Factory{},
diskscraper.TypeStr: &diskscraper.Factory{},
loadscraper.TypeStr: &loadscraper.Factory{},
filesystemscraper.TypeStr: &filesystemscraper.Factory{},
memoryscraper.TypeStr: &memoryscraper.Factory{},
networkscraper.TypeStr: &networkscraper.Factory{},
pagingscraper.TypeStr: &pagingscraper.Factory{},
processesscraper.TypeStr: &processesscraper.Factory{},
processscraper.TypeStr: &processscraper.Factory{},
systemscraper.TypeStr: &systemscraper.Factory{},
scraperFactories = map[component.Type]internal.ScraperFactory{
cpuscraper.Type: &cpuscraper.Factory{},
diskscraper.Type: &diskscraper.Factory{},
filesystemscraper.Type: &filesystemscraper.Factory{},
loadscraper.Type: &loadscraper.Factory{},
memoryscraper.Type: &memoryscraper.Factory{},
networkscraper.Type: &networkscraper.Factory{},
pagingscraper.Type: &pagingscraper.Factory{},
processesscraper.Type: &processesscraper.Factory{},
processscraper.Type: &processscraper.Factory{},
systemscraper.Type: &systemscraper.Factory{},
}
)

Expand All @@ -60,14 +60,6 @@ func NewFactory() receiver.Factory {
receiver.WithLogs(createLogsReceiver, metadata.LogsStability))
}

func getScraperFactory(key string) (internal.ScraperFactory, bool) {
if factory, ok := scraperFactories[key]; ok {
return factory, true
}

return nil, false
}

// createDefaultConfig creates the default configuration for receiver.
func createDefaultConfig() component.Config {
return &Config{
Expand Down Expand Up @@ -115,7 +107,7 @@ func createAddScraperOptions(
ctx context.Context,
set receiver.Settings,
config *Config,
factories map[string]internal.ScraperFactory,
factories map[component.Type]internal.ScraperFactory,
) ([]scraperhelper.ScraperControllerOption, error) {
scraperControllerOptions := make([]scraperhelper.ScraperControllerOption, 0, len(config.Scrapers))

Expand All @@ -136,7 +128,7 @@ func createAddScraperOptions(
return scraperControllerOptions, nil
}

func createHostMetricsScraper(ctx context.Context, set receiver.Settings, key string, cfg internal.Config, factories map[string]internal.ScraperFactory) (s scraper.Metrics, ok bool, err error) {
func createHostMetricsScraper(ctx context.Context, set receiver.Settings, key component.Type, cfg internal.Config, factories map[component.Type]internal.ScraperFactory) (s scraper.Metrics, ok bool, err error) {
factory := factories[key]
if factory == nil {
ok = false
Expand Down
3 changes: 2 additions & 1 deletion receiver/hostmetricsreceiver/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/component/componenttest"
"go.opentelemetry.io/collector/consumer/consumertest"
"go.opentelemetry.io/collector/pipeline"
Expand Down Expand Up @@ -47,7 +48,7 @@ func TestCreateReceiver_ScraperKeyConfigError(t *testing.T) {
const errorKey string = "error"

factory := NewFactory()
cfg := &Config{Scrapers: map[string]internal.Config{errorKey: &mockConfig{}}}
cfg := &Config{Scrapers: map[component.Type]internal.Config{component.MustNewType(errorKey): &mockConfig{}}}

_, err := factory.CreateMetrics(context.Background(), creationSet, cfg, consumertest.NewNop())
assert.EqualError(t, err, fmt.Sprintf("host metrics scraper factory not found for key: %q", errorKey))
Expand Down
2 changes: 1 addition & 1 deletion receiver/hostmetricsreceiver/hostmetrics_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func TestLoadConfigRootPath(t *testing.T) {
common.HostSysEnvKey: "testdata/sys",
common.HostVarEnvKey: "testdata/var",
})
expectedConfig.Scrapers = map[string]internal.Config{cpuscraper.TypeStr: cpuScraperCfg}
expectedConfig.Scrapers = map[component.Type]internal.Config{cpuscraper.Type: cpuScraperCfg}

assert.Equal(t, expectedConfig, cfg)
}
Expand Down
Loading

0 comments on commit 896373f

Please sign in to comment.