From dd89cf6137573038046315555df9177130fd275c Mon Sep 17 00:00:00 2001 From: Roger Coll Date: Tue, 28 May 2024 17:40:32 +0200 Subject: [PATCH 01/23] feat: add geoipprovider internal package Includes the GeoIPProvider interface, a configuration type and a factory interface able to generate providers. --- .../internal/provider/geoipprovider.go | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 processor/geoipprocessor/internal/provider/geoipprovider.go diff --git a/processor/geoipprocessor/internal/provider/geoipprovider.go b/processor/geoipprocessor/internal/provider/geoipprovider.go new file mode 100644 index 000000000000..23a2a3965c00 --- /dev/null +++ b/processor/geoipprocessor/internal/provider/geoipprovider.go @@ -0,0 +1,34 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package provider + +import ( + "context" + "net" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/processor" + "go.opentelemetry.io/otel/attribute" +) + +// GeoIPProvider defines methods for obtaining the geographical location based on the provided IP address. +type GeoIPProvider interface { + // Location returns a set of attributes representing the geographical location for the given IP address. It requires a context for managing request lifetime. + Location(context.Context, net.IP) (attribute.Set, error) +} + +// Config is the configuration of a GeoIPProvider. +// It extends the component.ConfigValidator interface to include validation logic. +type Config interface { + component.ConfigValidator +} + +// GeoIPProviderFactory can create GeoIPProvider instances. +type GeoIPProviderFactory interface { + // CreateDefaultConfig creates the default configuration for the GeoIPProvider. + CreateDefaultConfig() Config + + // CreateGeoIPProvider creates a provider based on this config. + CreateGeoIPProvider(ctx context.Context, settings processor.CreateSettings, cfg Config) (GeoIPProvider, error) +} From 18c1d24493f70de18097f401a83fdc0f41f84add Mon Sep 17 00:00:00 2001 From: Roger Coll Date: Tue, 28 May 2024 19:08:25 +0200 Subject: [PATCH 02/23] add providers to configuration --- processor/geoipprocessor/config.go | 18 +++++++++++++++++- processor/geoipprocessor/config_test.go | 15 ++++++++------- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/processor/geoipprocessor/config.go b/processor/geoipprocessor/config.go index 318739c3b360..c0da159bda6c 100644 --- a/processor/geoipprocessor/config.go +++ b/processor/geoipprocessor/config.go @@ -3,9 +3,25 @@ package geoipprocessor // import "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor" +import ( + "errors" + + "go.opentelemetry.io/collector/component" + + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider" +) + // Config holds the configuration for the GeoIP processor. -type Config struct{} +type Config struct { + // Providers specifies the sources to extract geographical information about a given IP. + Providers map[string]provider.Config `mapstructure:"-"` +} + +var _ component.Config = (*Config)(nil) func (cfg *Config) Validate() error { + if len(cfg.Providers) == 0 { + return errors.New("must specify at least one geo IP data provider when using the geoip processor") + } return nil } diff --git a/processor/geoipprocessor/config_test.go b/processor/geoipprocessor/config_test.go index 6f41589941fe..2a4b118aa4d8 100644 --- a/processor/geoipprocessor/config_test.go +++ b/processor/geoipprocessor/config_test.go @@ -19,12 +19,13 @@ func TestLoadConfig(t *testing.T) { t.Parallel() tests := []struct { - id component.ID - expected component.Config + id component.ID + expected component.Config + errorMessage string }{ { - id: component.NewID(metadata.Type), - expected: &Config{}, + id: component.NewID(metadata.Type), + errorMessage: "must specify at least one geo IP data provider when using the geoip processor", }, } @@ -40,11 +41,11 @@ func TestLoadConfig(t *testing.T) { require.NoError(t, err) require.NoError(t, component.UnmarshalConfig(sub, cfg)) - if tt.expected == nil { - err = component.ValidateConfig(cfg) - assert.Error(t, err) + if tt.errorMessage != "" { + assert.EqualError(t, component.ValidateConfig(cfg), tt.errorMessage) return } + assert.NoError(t, component.ValidateConfig(cfg)) assert.Equal(t, tt.expected, cfg) }) From ca50fa165c9fac920f31d953167b49b1b6848d66 Mon Sep 17 00:00:00 2001 From: Roger Coll Date: Wed, 29 May 2024 15:37:13 +0200 Subject: [PATCH 03/23] feat: add unmarshal implementation for geoip providers --- processor/geoipprocessor/config.go | 54 +++++- processor/geoipprocessor/config_test.go | 12 ++ processor/geoipprocessor/factory.go | 11 ++ processor/geoipprocessor/go.mod | 46 ++++- processor/geoipprocessor/go.sum | 173 ++++++++++++++++++ .../testdata/config-invalidProviderKey.yaml | 4 + 6 files changed, 298 insertions(+), 2 deletions(-) create mode 100644 processor/geoipprocessor/testdata/config-invalidProviderKey.yaml diff --git a/processor/geoipprocessor/config.go b/processor/geoipprocessor/config.go index c0da159bda6c..9dbe82437d85 100644 --- a/processor/geoipprocessor/config.go +++ b/processor/geoipprocessor/config.go @@ -5,19 +5,28 @@ package geoipprocessor // import "github.com/open-telemetry/opentelemetry-collec import ( "errors" + "fmt" "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/confmap" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider" ) +const ( + providerKey = "providers" +) + // Config holds the configuration for the GeoIP processor. type Config struct { // Providers specifies the sources to extract geographical information about a given IP. Providers map[string]provider.Config `mapstructure:"-"` } -var _ component.Config = (*Config)(nil) +var ( + _ component.Config = (*Config)(nil) + _ confmap.Unmarshaler = (*Config)(nil) +) func (cfg *Config) Validate() error { if len(cfg.Providers) == 0 { @@ -25,3 +34,46 @@ func (cfg *Config) Validate() error { } return nil } + +// Unmarshal a config.Parser into the config struct. +func (cfg *Config) Unmarshal(componentParser *confmap.Conf) error { + if componentParser == nil { + return nil + } + + // load the non-dynamic config normally + err := componentParser.Unmarshal(cfg, confmap.WithIgnoreUnused()) + if err != nil { + return err + } + + // dynamically load the individual providers configs based on the key name + + cfg.Providers = map[string]provider.Config{} + + providersSection, err := componentParser.Sub(providerKey) + if err != nil { + return err + } + + for key := range providersSection.ToStringMap() { + factory, ok := getProviderFactory(key) + if !ok { + return fmt.Errorf("invalid provider key: %s", key) + } + + providerCfg := factory.CreateDefaultConfig() + providerSection, err := providersSection.Sub(key) + if err != nil { + return err + } + err = providerSection.Unmarshal(providerCfg) + if err != nil { + return fmt.Errorf("error reading settings for provider type %q: %w", key, err) + } + + cfg.Providers[key] = providerCfg + } + + return nil +} diff --git a/processor/geoipprocessor/config_test.go b/processor/geoipprocessor/config_test.go index 2a4b118aa4d8..277066541af6 100644 --- a/processor/geoipprocessor/config_test.go +++ b/processor/geoipprocessor/config_test.go @@ -11,6 +11,7 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/confmap/confmaptest" + "go.opentelemetry.io/collector/otelcol/otelcoltest" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/metadata" ) @@ -51,3 +52,14 @@ func TestLoadConfig(t *testing.T) { }) } } + +func TestLoadInvalidConfig_InvalidProviderKey(t *testing.T) { + factories, err := otelcoltest.NopFactories() + require.NoError(t, err) + + factory := NewFactory() + factories.Processors[metadata.Type] = factory + _, err = otelcoltest.LoadConfigAndValidate(filepath.Join("testdata", "config-invalidProviderKey.yaml"), factories) + + require.Contains(t, err.Error(), "error reading configuration for \"geoip\": invalid provider key: invalidProviderKey") +} diff --git a/processor/geoipprocessor/factory.go b/processor/geoipprocessor/factory.go index ade49bf4accd..fbbd520a0169 100644 --- a/processor/geoipprocessor/factory.go +++ b/processor/geoipprocessor/factory.go @@ -12,16 +12,27 @@ import ( "go.opentelemetry.io/collector/processor/processorhelper" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/metadata" + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider" ) var processorCapabilities = consumer.Capabilities{MutatesData: true} +var providerFactories = map[string]provider.GeoIPProviderFactory{} + // NewFactory creates a new processor factory with default configuration, // and registers the processors for metrics, traces, and logs. func NewFactory() processor.Factory { return processor.NewFactory(metadata.Type, createDefaultConfig, processor.WithMetrics(createMetricsProcessor, metadata.MetricsStability), processor.WithLogs(createLogsProcessor, metadata.LogsStability), processor.WithTraces(createTracesProcessor, metadata.TracesStability)) } +func getProviderFactory(key string) (provider.GeoIPProviderFactory, bool) { + if factory, ok := providerFactories[key]; ok { + return factory, true + } + + return nil, false +} + // createDefaultConfig returns a default configuration for the processor. func createDefaultConfig() component.Config { return &Config{} diff --git a/processor/geoipprocessor/go.mod b/processor/geoipprocessor/go.mod index b8114eb0b098..bf6ffc2e7f50 100644 --- a/processor/geoipprocessor/go.mod +++ b/processor/geoipprocessor/go.mod @@ -9,45 +9,89 @@ require ( go.opentelemetry.io/collector/consumer v0.101.1-0.20240527192838-af4fdd4e342a go.opentelemetry.io/collector/pdata v1.8.1-0.20240527192838-af4fdd4e342a go.opentelemetry.io/collector/processor v0.101.1-0.20240527192838-af4fdd4e342a + go.opentelemetry.io/otel v1.27.0 go.uber.org/goleak v1.3.0 ) require ( github.com/beorn7/perks v1.0.1 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-logr/logr v1.4.1 // indirect 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.0.0-alpha.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/uuid v1.6.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect + github.com/hashicorp/go-version v1.6.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/knadh/koanf/maps v0.1.1 // indirect github.com/knadh/koanf/providers/confmap v0.1.0 // indirect github.com/knadh/koanf/v2 v2.1.1 // indirect + github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.53.0 // indirect github.com/prometheus/procfs v0.15.0 // indirect + github.com/shirou/gopsutil/v3 v3.24.4 // indirect + github.com/shoenig/go-m1cpu v0.1.6 // indirect + github.com/spf13/cobra v1.8.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect + github.com/yusufpapurcu/wmi v1.2.4 // indirect + go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/collector v0.101.1-0.20240527192838-af4fdd4e342a // indirect go.opentelemetry.io/collector/config/configtelemetry v0.101.1-0.20240527192838-af4fdd4e342a // indirect + go.opentelemetry.io/collector/confmap/converter/expandconverter v0.101.0 // indirect + go.opentelemetry.io/collector/confmap/provider/envprovider v0.101.0 // indirect + go.opentelemetry.io/collector/confmap/provider/fileprovider v0.101.0 // indirect + go.opentelemetry.io/collector/confmap/provider/httpprovider v0.101.0 // indirect + go.opentelemetry.io/collector/confmap/provider/httpsprovider v0.101.0 // indirect + go.opentelemetry.io/collector/confmap/provider/yamlprovider v0.101.0 // indirect + go.opentelemetry.io/collector/connector v0.101.0 // indirect + go.opentelemetry.io/collector/exporter v0.101.0 // indirect + go.opentelemetry.io/collector/extension v0.101.0 // indirect + go.opentelemetry.io/collector/featuregate v1.8.0 // indirect + go.opentelemetry.io/collector/otelcol v0.101.0 // indirect go.opentelemetry.io/collector/pdata/testdata v0.101.0 // indirect - go.opentelemetry.io/otel v1.27.0 // indirect + go.opentelemetry.io/collector/receiver v0.101.0 // indirect + go.opentelemetry.io/collector/semconv v0.101.0 // indirect + go.opentelemetry.io/collector/service v0.101.0 // indirect + go.opentelemetry.io/contrib/config v0.6.0 // indirect + go.opentelemetry.io/contrib/propagators/b3 v1.26.0 // indirect + go.opentelemetry.io/otel/bridge/opencensus v1.26.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.26.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.26.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0 // indirect go.opentelemetry.io/otel/exporters/prometheus v0.49.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.26.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0 // indirect go.opentelemetry.io/otel/metric v1.27.0 // indirect go.opentelemetry.io/otel/sdk v1.27.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect + go.opentelemetry.io/proto/otlp v1.2.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect golang.org/x/net v0.24.0 // indirect golang.org/x/sys v0.20.0 // indirect golang.org/x/text v0.14.0 // indirect + gonum.org/v1/gonum v0.15.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect google.golang.org/grpc v1.64.0 // indirect google.golang.org/protobuf v1.34.1 // indirect diff --git a/processor/geoipprocessor/go.sum b/processor/geoipprocessor/go.sum index d02e440b8bb3..77599024c659 100644 --- a/processor/geoipprocessor/go.sum +++ b/processor/geoipprocessor/go.sum @@ -1,24 +1,67 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 h1:TQcrn6Wq+sKGkpyPvppOz99zsMBaUOKXq6HSv655U1c= github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 h1:/c3QmbOGMGTOumP2iT/rCwB7b0QDGLKzqOmktBjT+Is= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1/go.mod h1:5SN9VR2LTsRFsrEC6FHgRbTWrTHu6tqPeKxEQv15giM= +github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= +github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -33,6 +76,8 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= @@ -44,8 +89,11 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE= @@ -54,12 +102,37 @@ github.com/prometheus/procfs v0.15.0 h1:A82kmvXJq2jTu5YUhSGNlYoxh85zLnKgPz4bMZgI github.com/prometheus/procfs v0.15.0/go.mod h1:Y0RJ/Y5g5wJpkTisOtqwDSo4HwhGmLB4VQSw2sQJLHk= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shirou/gopsutil/v3 v3.24.4 h1:dEHgzZXt4LMNm+oYELpzl9YCqV65Yr/6SfrvgRBtXeU= +github.com/shirou/gopsutil/v3 v3.24.4/go.mod h1:lTd2mdiOspcqLgAnr9/nGi71NkeMpWKdmhuxm9GusH8= +github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= +github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= +github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/collector v0.101.1-0.20240527192838-af4fdd4e342a h1:4qJ9yfH6nAwW6PlZfw7V7VwhVgp/UkW8dCw+r6kU7dc= go.opentelemetry.io/collector v0.101.1-0.20240527192838-af4fdd4e342a/go.mod h1:/0r4YF1nBHmTBgaZYi9om171wt/c9zP7AU7Xqqr+a7A= go.opentelemetry.io/collector/component v0.101.1-0.20240527192838-af4fdd4e342a h1:8qOFfwhDNRcAobYZEy6VJ0EFzV8Rbn0jUR7DwYXS0T4= @@ -68,18 +141,66 @@ go.opentelemetry.io/collector/config/configtelemetry v0.101.1-0.20240527192838-a go.opentelemetry.io/collector/config/configtelemetry v0.101.1-0.20240527192838-af4fdd4e342a/go.mod h1:WxWKNVAQJg/Io1nA3xLgn/DWLE/W1QOB2+/Js3ACi40= go.opentelemetry.io/collector/confmap v0.101.1-0.20240527192838-af4fdd4e342a h1:rBVMMiax68gRFxZFA3pP6ZtCJoV6o+sqj/QUVApjbIA= go.opentelemetry.io/collector/confmap v0.101.1-0.20240527192838-af4fdd4e342a/go.mod h1:KgpS7UxH5rkd69CzAzlY2I1heH8Z7eNCZlHmwQBMxNg= +go.opentelemetry.io/collector/confmap/converter/expandconverter v0.101.0 h1:/uUZlzzxO8QknVCslpYVlQGSq5EG3Dzr6l4w2xW4u2A= +go.opentelemetry.io/collector/confmap/converter/expandconverter v0.101.0/go.mod h1:GKgiSuL5+ATJE1lrAQVpfSBFX/3XqGyc2qrfQBKpVd8= +go.opentelemetry.io/collector/confmap/provider/envprovider v0.101.0 h1:I7oSi6hTTaDMbh9k6nxF4YhLqB/t0xXTgrBXGCT53vw= +go.opentelemetry.io/collector/confmap/provider/envprovider v0.101.0/go.mod h1:DxCK400//MGnFyLSnIjme+R7qZwfDQtHYERIQtEt7Cg= +go.opentelemetry.io/collector/confmap/provider/fileprovider v0.101.0 h1:uMjJyxN3q+DaKR+GOJcERuVD8rKEe1PvTOUaMs66gCM= +go.opentelemetry.io/collector/confmap/provider/fileprovider v0.101.0/go.mod h1:3WLJtHisH4/7K/IU//OMoCTJYZ8o96/YfjP6J+Q/kBo= +go.opentelemetry.io/collector/confmap/provider/httpprovider v0.101.0 h1:U+/Mmd1+DHl94R/i+LxTjReEtFh3qV4QJ8XxqhCdezk= +go.opentelemetry.io/collector/confmap/provider/httpprovider v0.101.0/go.mod h1:EJ5t47HWbDGxUjVax+BBJ3ySpHBHQz/Ys689+R6OXis= +go.opentelemetry.io/collector/confmap/provider/httpsprovider v0.101.0 h1:W0Xw+OgRCbdKWJy3VSZKPCcf4fFZlFF6L+mMWleq1LY= +go.opentelemetry.io/collector/confmap/provider/httpsprovider v0.101.0/go.mod h1:0I8UtPWeXbuwe/UMQ+LmoFWoNo6NCxxNocHPrLox0X8= +go.opentelemetry.io/collector/confmap/provider/yamlprovider v0.101.0 h1:N5yNF24hxUOO5Ps5mWwwQaYWyBPcqqSh4h10kULDT3c= +go.opentelemetry.io/collector/confmap/provider/yamlprovider v0.101.0/go.mod h1:sPzwdCKCXYXUR8U7eAHshDZPnfbF7B7I/BFyUWTvvKQ= +go.opentelemetry.io/collector/connector v0.101.0 h1:OedmwrzrxC3wrYkp8Mpfcf30bJmlxC9TuwNLnpj4V8M= +go.opentelemetry.io/collector/connector v0.101.0/go.mod h1:skAILMO4ye4Y3s2DUo7k/8uZFwG22fpwjIYXO/pv/JQ= go.opentelemetry.io/collector/consumer v0.101.1-0.20240527192838-af4fdd4e342a h1:x5XHssVv0qwXx8AB1TqJ32YWiF0vRev5ZHEkJsc5u/M= go.opentelemetry.io/collector/consumer v0.101.1-0.20240527192838-af4fdd4e342a/go.mod h1:qAGuUGoWKKoElRpuoMqybsz5qN8mquLh+C5nxTORZDY= +go.opentelemetry.io/collector/exporter v0.101.0 h1:zAxQBfaWO+PEHL3nDglgMGaWsqLsj1lJHPaBnO8PeDo= +go.opentelemetry.io/collector/exporter v0.101.0/go.mod h1:ZFwUWCmnM2ZbEty71Q13qME9QhvIKMgyYrS3s8vJPM8= +go.opentelemetry.io/collector/extension v0.101.0 h1:A4hq/aci9+/Pxi8sJfyYgbeHjSIL7JFZR81IlSOTla4= +go.opentelemetry.io/collector/extension v0.101.0/go.mod h1:14gQMuybTcppfTTM9AwqeoFrNCLv/ds/c0A4Z0hWuLI= +go.opentelemetry.io/collector/featuregate v1.8.0 h1:p/bAuk5LiSfdYS88yFl/Jzao9bHEYqCh7YvZJ+L+IZg= +go.opentelemetry.io/collector/featuregate v1.8.0/go.mod h1:w7nUODKxEi3FLf1HslCiE6YWtMtOOrMnSwsDam8Mg9w= +go.opentelemetry.io/collector/otelcol v0.101.0 h1:6kF2dcXpu5NjxK2j0ksCRzZhqigxCGrP/u7n57FSMOg= +go.opentelemetry.io/collector/otelcol v0.101.0/go.mod h1:qGrb+hlZXId/hJj0y28vq0YkMd6Xsoz2w7mZkXJOw68= go.opentelemetry.io/collector/pdata v1.8.1-0.20240527192838-af4fdd4e342a h1:ODREkUcnSXEoJz7QzPbnDlVcQQ0qnxSyAgiRciSXWbU= go.opentelemetry.io/collector/pdata v1.8.1-0.20240527192838-af4fdd4e342a/go.mod h1:vk7LrfpyVpGZrRWcpjyy0DDZzL3SZiYMQxfap25551w= go.opentelemetry.io/collector/pdata/testdata v0.101.0 h1:JzeUtg5RN1iIFgY8DakGlqBkGxOTJlkaYlLausnEGKY= go.opentelemetry.io/collector/pdata/testdata v0.101.0/go.mod h1:ZGobfCus4fWo5RduZ7ENI0+HD9BewgKuO6qU2rBVnUg= go.opentelemetry.io/collector/processor v0.101.1-0.20240527192838-af4fdd4e342a h1:+lN1HuYCLqOHIbnoPqFn+hTcz3H1EWxab7P2u/798Xw= go.opentelemetry.io/collector/processor v0.101.1-0.20240527192838-af4fdd4e342a/go.mod h1:gcBmjCuS9NJTceMYGYvpSdvFhkE71iA3fSfjUpzAmr0= +go.opentelemetry.io/collector/receiver v0.101.0 h1:+YJQvcAw5Es15Ub8hYqqZumKbe7D0SMU8XCgGRxc25M= +go.opentelemetry.io/collector/receiver v0.101.0/go.mod h1:JFVHAkIIz9uOk85u9pHsYRcyFj1ZAUpw59ahNZ28+ko= +go.opentelemetry.io/collector/semconv v0.101.0 h1:tOe9iTe9dDCnvz/bqgfNRr4w80kXG8505tQJ5h5v08Q= +go.opentelemetry.io/collector/semconv v0.101.0/go.mod h1:8ElcRZ8Cdw5JnvhTOQOdYizkJaQ10Z2fS+R6djOnj6A= +go.opentelemetry.io/collector/service v0.101.0 h1:My2NrH25WYmJ6vMWwT3csglyiTkf0XP3nPgj0mX1yFw= +go.opentelemetry.io/collector/service v0.101.0/go.mod h1:XowYC9FyNGmWClh0aObztKdTfQNLAr6mubpvh27ee+Q= +go.opentelemetry.io/contrib/config v0.6.0 h1:M1SRD1Z15XHPGk61tMLI1up77XT5FdrqQSRrlH0fYuk= +go.opentelemetry.io/contrib/config v0.6.0/go.mod h1:t+/kzmRWLN7J+4F/dD4fFvlYCmCO63WYwy/B00IC++c= +go.opentelemetry.io/contrib/propagators/b3 v1.26.0 h1:wgFbVA+bK2k+fGVfDOCOG4cfDAoppyr5sI2dVlh8MWM= +go.opentelemetry.io/contrib/propagators/b3 v1.26.0/go.mod h1:DDktFXxA+fyItAAM0Sbl5OBH7KOsCTjvbBdPKtoIf/k= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= +go.opentelemetry.io/otel/bridge/opencensus v1.26.0 h1:DZzxj9QjznMVoehskOJnFP2gsTCWtDTFBDvFhPAY7nc= +go.opentelemetry.io/otel/bridge/opencensus v1.26.0/go.mod h1:rJiX0KrF5m8Tm1XE8jLczpAv5zUaDcvhKecFG0ZoFG4= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.26.0 h1:+hm+I+KigBy3M24/h1p/NHkUx/evbLH0PNcjpMyCHc4= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.26.0/go.mod h1:NjC8142mLvvNT6biDpaMjyz78kyEHIwAJlSX0N9P5KI= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.26.0 h1:HGZWGmCVRCVyAs2GQaiHQPbDHo+ObFWeUEOd+zDnp64= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.26.0/go.mod h1:SaH+v38LSCHddyk7RGlU9uZyQoRrKao6IBnJw6Kbn+c= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 h1:1u/AyyOqAWzy+SkPxDpahCNZParHV8Vid1RnI2clyDE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0/go.mod h1:z46paqbJ9l7c9fIPCXTqTGwhQZ5XoTIsfeFYWboizjs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 h1:Waw9Wfpo/IXzOI8bCB7DIk+0JZcqqsyn1JFnAc+iam8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0/go.mod h1:wnJIG4fOqyynOnnQF/eQb4/16VlX2EJAHhHgqIqWfAo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0 h1:1wp/gyxsuYtuE/JFxsQRtcCDtMrO2qMvlfXALU5wkzI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0/go.mod h1:gbTHmghkGgqxMomVQQMur1Nba4M0MQ8AYThXDUjsJ38= go.opentelemetry.io/otel/exporters/prometheus v0.49.0 h1:Er5I1g/YhfYv9Affk9nJLfH/+qCCVVg1f2R9AbJfqDQ= go.opentelemetry.io/otel/exporters/prometheus v0.49.0/go.mod h1:KfQ1wpjf3zsHjzP149P4LyAwWRupc6c7t1ZJ9eXpKQM= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.26.0 h1:5fnmgteaar1VcAA69huatudPduNFz7guRtCmfZCooZI= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.26.0/go.mod h1:lsPccfZiz1cb1AhBPmicWM2E4F1VynFXEvD8SEBS4TM= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0 h1:0W5o9SzoR15ocYHEQfvfipzcNog1lBxOLfnex91Hk6s= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0/go.mod h1:zVZ8nz+VSggWmnh6tTsJqXQ7rU4xLwRtna1M4x5jq58= go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kTWmI= @@ -88,6 +209,8 @@ go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2N go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw= go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= +go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94= +go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -97,20 +220,40 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -118,6 +261,10 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -125,14 +272,40 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.15.0 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ= +gonum.org/v1/gonum v0.15.0/go.mod h1:xzZVBJBtS+Mz4q0Yl2LJTk+OxOg4jiXZ7qBoM0uISGo= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 h1:RFiFrvy37/mpSpdySBDrUdipW/dHwsRwh3J3+A9VgT4= +google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237/go.mod h1:Z5Iiy3jtmioajWHDGFk7CeugTyHtPvMHA4UTmUkyalE= google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4= google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/processor/geoipprocessor/testdata/config-invalidProviderKey.yaml b/processor/geoipprocessor/testdata/config-invalidProviderKey.yaml new file mode 100644 index 000000000000..5f3aa0a58d41 --- /dev/null +++ b/processor/geoipprocessor/testdata/config-invalidProviderKey.yaml @@ -0,0 +1,4 @@ +processors: + geoip: + providers: + invalidProviderKey: From 49c277bc7cf1e5db7719d5269081235c1c998ffa Mon Sep 17 00:00:00 2001 From: Roger Coll Date: Wed, 29 May 2024 17:59:28 +0200 Subject: [PATCH 04/23] add provider's mock and configuration load test case --- processor/geoipprocessor/go.mod | 2 +- processor/geoipprocessor/go.sum | 13 +++- .../internal/provider/geoipprovider.go | 6 +- processor/geoipprocessor/provider_test.go | 70 +++++++++++++++++++ .../testdata/config-mockProvider.yaml | 17 +++++ 5 files changed, 100 insertions(+), 8 deletions(-) create mode 100644 processor/geoipprocessor/provider_test.go create mode 100644 processor/geoipprocessor/testdata/config-mockProvider.yaml diff --git a/processor/geoipprocessor/go.mod b/processor/geoipprocessor/go.mod index bf6ffc2e7f50..b31c9489c272 100644 --- a/processor/geoipprocessor/go.mod +++ b/processor/geoipprocessor/go.mod @@ -7,6 +7,7 @@ require ( go.opentelemetry.io/collector/component v0.101.1-0.20240527192838-af4fdd4e342a go.opentelemetry.io/collector/confmap v0.101.1-0.20240527192838-af4fdd4e342a go.opentelemetry.io/collector/consumer v0.101.1-0.20240527192838-af4fdd4e342a + go.opentelemetry.io/collector/otelcol v0.101.0 go.opentelemetry.io/collector/pdata v1.8.1-0.20240527192838-af4fdd4e342a go.opentelemetry.io/collector/processor v0.101.1-0.20240527192838-af4fdd4e342a go.opentelemetry.io/otel v1.27.0 @@ -63,7 +64,6 @@ require ( go.opentelemetry.io/collector/exporter v0.101.0 // indirect go.opentelemetry.io/collector/extension v0.101.0 // indirect go.opentelemetry.io/collector/featuregate v1.8.0 // indirect - go.opentelemetry.io/collector/otelcol v0.101.0 // indirect go.opentelemetry.io/collector/pdata/testdata v0.101.0 // indirect go.opentelemetry.io/collector/receiver v0.101.0 // indirect go.opentelemetry.io/collector/semconv v0.101.0 // indirect diff --git a/processor/geoipprocessor/go.sum b/processor/geoipprocessor/go.sum index 77599024c659..e7033e919f34 100644 --- a/processor/geoipprocessor/go.sum +++ b/processor/geoipprocessor/go.sum @@ -100,13 +100,14 @@ github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+a github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= github.com/prometheus/procfs v0.15.0 h1:A82kmvXJq2jTu5YUhSGNlYoxh85zLnKgPz4bMZgI5Ek= github.com/prometheus/procfs v0.15.0/go.mod h1:Y0RJ/Y5g5wJpkTisOtqwDSo4HwhGmLB4VQSw2sQJLHk= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shirou/gopsutil/v3 v3.24.4 h1:dEHgzZXt4LMNm+oYELpzl9YCqV65Yr/6SfrvgRBtXeU= github.com/shirou/gopsutil/v3 v3.24.4/go.mod h1:lTd2mdiOspcqLgAnr9/nGi71NkeMpWKdmhuxm9GusH8= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= @@ -137,6 +138,10 @@ go.opentelemetry.io/collector v0.101.1-0.20240527192838-af4fdd4e342a h1:4qJ9yfH6 go.opentelemetry.io/collector v0.101.1-0.20240527192838-af4fdd4e342a/go.mod h1:/0r4YF1nBHmTBgaZYi9om171wt/c9zP7AU7Xqqr+a7A= go.opentelemetry.io/collector/component v0.101.1-0.20240527192838-af4fdd4e342a h1:8qOFfwhDNRcAobYZEy6VJ0EFzV8Rbn0jUR7DwYXS0T4= go.opentelemetry.io/collector/component v0.101.1-0.20240527192838-af4fdd4e342a/go.mod h1:WBWJoYh8Js5S8e+0twmQxSF/uqR1HHkDb3YNKzgKaWY= +go.opentelemetry.io/collector/config/confignet v0.101.0 h1:Mdb9e/EpCSac4Ccg7w4UchS/o4yY1WoIc9X5o7fTu9E= +go.opentelemetry.io/collector/config/confignet v0.101.0/go.mod h1:3naWoPss70RhDHhYjGACi7xh4NcVRvs9itzIRVWyu1k= +go.opentelemetry.io/collector/config/configretry v0.101.0 h1:5QggLq/lZiZXry1Ut52IOTbrdz1RbGoL29Io/wWdE4g= +go.opentelemetry.io/collector/config/configretry v0.101.0/go.mod h1:uRdmPeCkrW9Zsadh2WEbQ1AGXGYJ02vCfmmT+0g69nY= go.opentelemetry.io/collector/config/configtelemetry v0.101.1-0.20240527192838-af4fdd4e342a h1:EsbDY0mcCilr3LkM7XK5xRuOOZxn2qE6IdECWZ5xeFo= go.opentelemetry.io/collector/config/configtelemetry v0.101.1-0.20240527192838-af4fdd4e342a/go.mod h1:WxWKNVAQJg/Io1nA3xLgn/DWLE/W1QOB2+/Js3ACi40= go.opentelemetry.io/collector/confmap v0.101.1-0.20240527192838-af4fdd4e342a h1:rBVMMiax68gRFxZFA3pP6ZtCJoV6o+sqj/QUVApjbIA= @@ -161,6 +166,8 @@ go.opentelemetry.io/collector/exporter v0.101.0 h1:zAxQBfaWO+PEHL3nDglgMGaWsqLsj go.opentelemetry.io/collector/exporter v0.101.0/go.mod h1:ZFwUWCmnM2ZbEty71Q13qME9QhvIKMgyYrS3s8vJPM8= go.opentelemetry.io/collector/extension v0.101.0 h1:A4hq/aci9+/Pxi8sJfyYgbeHjSIL7JFZR81IlSOTla4= go.opentelemetry.io/collector/extension v0.101.0/go.mod h1:14gQMuybTcppfTTM9AwqeoFrNCLv/ds/c0A4Z0hWuLI= +go.opentelemetry.io/collector/extension/zpagesextension v0.101.0 h1:hZIkGTgKeVvVlqoPw72G/RkIhp0QSqY5PNRjf38mf2k= +go.opentelemetry.io/collector/extension/zpagesextension v0.101.0/go.mod h1:sllOMdEbNg2UnMxTO8jSx2OEfAcYX3ud6smuXhN6pbA= go.opentelemetry.io/collector/featuregate v1.8.0 h1:p/bAuk5LiSfdYS88yFl/Jzao9bHEYqCh7YvZJ+L+IZg= go.opentelemetry.io/collector/featuregate v1.8.0/go.mod h1:w7nUODKxEi3FLf1HslCiE6YWtMtOOrMnSwsDam8Mg9w= go.opentelemetry.io/collector/otelcol v0.101.0 h1:6kF2dcXpu5NjxK2j0ksCRzZhqigxCGrP/u7n57FSMOg= @@ -181,6 +188,8 @@ go.opentelemetry.io/contrib/config v0.6.0 h1:M1SRD1Z15XHPGk61tMLI1up77XT5FdrqQSR go.opentelemetry.io/contrib/config v0.6.0/go.mod h1:t+/kzmRWLN7J+4F/dD4fFvlYCmCO63WYwy/B00IC++c= go.opentelemetry.io/contrib/propagators/b3 v1.26.0 h1:wgFbVA+bK2k+fGVfDOCOG4cfDAoppyr5sI2dVlh8MWM= go.opentelemetry.io/contrib/propagators/b3 v1.26.0/go.mod h1:DDktFXxA+fyItAAM0Sbl5OBH7KOsCTjvbBdPKtoIf/k= +go.opentelemetry.io/contrib/zpages v0.51.0 h1:psVr4JTWd0qtISPj9EA6AODGJ09bvsOxWiuKqiGdSCA= +go.opentelemetry.io/contrib/zpages v0.51.0/go.mod h1:PKtp+NEp1gTTLmFHpynYgYCSkKtisPntOb9S1mQjFKg= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= go.opentelemetry.io/otel/bridge/opencensus v1.26.0 h1:DZzxj9QjznMVoehskOJnFP2gsTCWtDTFBDvFhPAY7nc= diff --git a/processor/geoipprocessor/internal/provider/geoipprovider.go b/processor/geoipprocessor/internal/provider/geoipprovider.go index 23a2a3965c00..2a850617cef4 100644 --- a/processor/geoipprocessor/internal/provider/geoipprovider.go +++ b/processor/geoipprocessor/internal/provider/geoipprovider.go @@ -7,7 +7,6 @@ import ( "context" "net" - "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/processor" "go.opentelemetry.io/otel/attribute" ) @@ -19,10 +18,7 @@ type GeoIPProvider interface { } // Config is the configuration of a GeoIPProvider. -// It extends the component.ConfigValidator interface to include validation logic. -type Config interface { - component.ConfigValidator -} +type Config interface{} // GeoIPProviderFactory can create GeoIPProvider instances. type GeoIPProviderFactory interface { diff --git a/processor/geoipprocessor/provider_test.go b/processor/geoipprocessor/provider_test.go new file mode 100644 index 000000000000..e5ef6addc7e1 --- /dev/null +++ b/processor/geoipprocessor/provider_test.go @@ -0,0 +1,70 @@ +package geoipprocessor + +import ( + "context" + "net" + "path/filepath" + "testing" + + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/metadata" + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/otelcol/otelcoltest" + "go.opentelemetry.io/collector/processor" + "go.opentelemetry.io/otel/attribute" +) + +type ProviderMock struct { + LocationF func(context.Context, net.IP) (attribute.Set, error) +} + +type ProviderFactoryMock struct { + CreateDefaultConfigF func() provider.Config + CreateGeoIPProviderF func(ctx context.Context, settings processor.CreateSettings, cfg provider.Config) (provider.GeoIPProvider, error) +} + +var ( + _ provider.GeoIPProvider = (*ProviderMock)(nil) + _ provider.GeoIPProviderFactory = (*ProviderFactoryMock)(nil) +) + +func (pm *ProviderMock) Location(ctx context.Context, ip net.IP) (attribute.Set, error) { + return pm.LocationF(ctx, ip) +} + +func (fm *ProviderFactoryMock) CreateDefaultConfig() provider.Config { + return fm.CreateDefaultConfigF() +} + +func (fm *ProviderFactoryMock) CreateGeoIPProvider(ctx context.Context, settings processor.CreateSettings, cfg provider.Config) (provider.GeoIPProvider, error) { + return fm.CreateGeoIPProviderF(ctx, settings, cfg) +} + +func TestLoadConfig_MockProvider(t *testing.T) { + mockProvider := ProviderMock{ + LocationF: func(context.Context, net.IP) (attribute.Set, error) { + return attribute.Set{}, nil + }, + } + mockFactory := ProviderFactoryMock{ + CreateDefaultConfigF: func() provider.Config { + type SampleConfig struct { + Database string `mapstructure:"database"` + } + return &SampleConfig{} + }, + CreateGeoIPProviderF: func(ctx context.Context, settings processor.CreateSettings, cfg provider.Config) (provider.GeoIPProvider, error) { + return &mockProvider, nil + }, + } + + factories, err := otelcoltest.NopFactories() + require.NoError(t, err) + + providerFactories["mock"] = &mockFactory + factory := NewFactory() + factories.Processors[metadata.Type] = factory + _, err = otelcoltest.LoadConfigAndValidate(filepath.Join("testdata", "config-mockProvider.yaml"), factories) + assert.NoError(t, err) +} diff --git a/processor/geoipprocessor/testdata/config-mockProvider.yaml b/processor/geoipprocessor/testdata/config-mockProvider.yaml new file mode 100644 index 000000000000..d6107cb3db01 --- /dev/null +++ b/processor/geoipprocessor/testdata/config-mockProvider.yaml @@ -0,0 +1,17 @@ +processors: + geoip: + providers: + mock: + database: "/tmp/geodata.csv" +receivers: + nop: + +exporters: + nop: + +service: + pipelines: + metrics: + receivers: [nop] + processors: [geoip] + exporters: [nop] From 4450aa85e6247183afa523d54a78eec54bee2db1 Mon Sep 17 00:00:00 2001 From: Roger Coll Date: Wed, 29 May 2024 19:28:38 +0200 Subject: [PATCH 05/23] feat: add list of providers to the geoip processor --- processor/geoipprocessor/factory.go | 48 +++++++++++++- processor/geoipprocessor/geoip_processor.go | 14 +++- processor/geoipprocessor/provider_test.go | 72 ++++++++++++++++----- 3 files changed, 112 insertions(+), 22 deletions(-) diff --git a/processor/geoipprocessor/factory.go b/processor/geoipprocessor/factory.go index fbbd520a0169..d6854c887725 100644 --- a/processor/geoipprocessor/factory.go +++ b/processor/geoipprocessor/factory.go @@ -5,6 +5,7 @@ package geoipprocessor // import "github.com/open-telemetry/opentelemetry-collec import ( "context" + "fmt" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/consumer" @@ -38,14 +39,55 @@ func createDefaultConfig() component.Config { return &Config{} } +func createGeoIPProviders( + ctx context.Context, + set processor.CreateSettings, + config *Config, + factories map[string]provider.GeoIPProviderFactory, +) ([]provider.GeoIPProvider, error) { + providers := make([]provider.GeoIPProvider, 0, len(config.Providers)) + + for key, cfg := range config.Providers { + factory := factories[key] + if factory == nil { + return nil, fmt.Errorf("geoIP provider factory not found for key: %q", key) + } + + provider, err := factory.CreateGeoIPProvider(ctx, set, cfg) + if err != nil { + return nil, fmt.Errorf("failed to create provider for key %q: %w", key, err) + } + + providers = append(providers, provider) + + } + + return providers, nil +} + func createMetricsProcessor(ctx context.Context, set processor.CreateSettings, cfg component.Config, nextConsumer consumer.Metrics) (processor.Metrics, error) { - return processorhelper.NewMetricsProcessor(ctx, set, cfg, nextConsumer, newGeoIPProcessor().processMetrics, processorhelper.WithCapabilities(processorCapabilities)) + geoCfg := cfg.(*Config) + providers, err := createGeoIPProviders(ctx, set, geoCfg, providerFactories) + if err != nil { + return nil, err + } + return processorhelper.NewMetricsProcessor(ctx, set, cfg, nextConsumer, newGeoIPProcessor(providers).processMetrics, processorhelper.WithCapabilities(processorCapabilities)) } func createTracesProcessor(ctx context.Context, set processor.CreateSettings, cfg component.Config, nextConsumer consumer.Traces) (processor.Traces, error) { - return processorhelper.NewTracesProcessor(ctx, set, cfg, nextConsumer, newGeoIPProcessor().processTraces, processorhelper.WithCapabilities(processorCapabilities)) + geoCfg := cfg.(*Config) + providers, err := createGeoIPProviders(ctx, set, geoCfg, providerFactories) + if err != nil { + return nil, err + } + return processorhelper.NewTracesProcessor(ctx, set, cfg, nextConsumer, newGeoIPProcessor(providers).processTraces, processorhelper.WithCapabilities(processorCapabilities)) } func createLogsProcessor(ctx context.Context, set processor.CreateSettings, cfg component.Config, nextConsumer consumer.Logs) (processor.Logs, error) { - return processorhelper.NewLogsProcessor(ctx, set, cfg, nextConsumer, newGeoIPProcessor().processLogs, processorhelper.WithCapabilities(processorCapabilities)) + geoCfg := cfg.(*Config) + providers, err := createGeoIPProviders(ctx, set, geoCfg, providerFactories) + if err != nil { + return nil, err + } + return processorhelper.NewLogsProcessor(ctx, set, cfg, nextConsumer, newGeoIPProcessor(providers).processLogs, processorhelper.WithCapabilities(processorCapabilities)) } diff --git a/processor/geoipprocessor/geoip_processor.go b/processor/geoipprocessor/geoip_processor.go index 207e2e1644a9..2657a397dfe6 100644 --- a/processor/geoipprocessor/geoip_processor.go +++ b/processor/geoipprocessor/geoip_processor.go @@ -6,15 +6,23 @@ package geoipprocessor // import "github.com/open-telemetry/opentelemetry-collec import ( "context" + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider" "go.opentelemetry.io/collector/pdata/plog" "go.opentelemetry.io/collector/pdata/pmetric" "go.opentelemetry.io/collector/pdata/ptrace" ) -type geoIPProcessor struct{} +// GeoProviders will be used by the Processor retrieve geographical metadata given an IP address. +type GeoProviders = []provider.GeoIPProvider -func newGeoIPProcessor() *geoIPProcessor { - return &geoIPProcessor{} +type geoIPProcessor struct { + providers GeoProviders +} + +func newGeoIPProcessor(providers GeoProviders) *geoIPProcessor { + return &geoIPProcessor{ + providers, + } } func (g *geoIPProcessor) processMetrics(_ context.Context, ms pmetric.Metrics) (pmetric.Metrics, error) { diff --git a/processor/geoipprocessor/provider_test.go b/processor/geoipprocessor/provider_test.go index e5ef6addc7e1..d3a6d16b8cac 100644 --- a/processor/geoipprocessor/provider_test.go +++ b/processor/geoipprocessor/provider_test.go @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/otelcol/otelcoltest" "go.opentelemetry.io/collector/processor" + "go.opentelemetry.io/collector/processor/processortest" "go.opentelemetry.io/otel/attribute" ) @@ -41,30 +42,69 @@ func (fm *ProviderFactoryMock) CreateGeoIPProvider(ctx context.Context, settings return fm.CreateGeoIPProviderF(ctx, settings, cfg) } +var baseMockProvider = ProviderMock{ + LocationF: func(context.Context, net.IP) (attribute.Set, error) { + return attribute.Set{}, nil + }, +} + +var baseMockFactory = ProviderFactoryMock{ + CreateDefaultConfigF: func() provider.Config { + type emptyConfig struct{} + return &emptyConfig{} + }, + CreateGeoIPProviderF: func(ctx context.Context, settings processor.CreateSettings, cfg provider.Config) (provider.GeoIPProvider, error) { + return &baseMockProvider, nil + }, +} + func TestLoadConfig_MockProvider(t *testing.T) { - mockProvider := ProviderMock{ - LocationF: func(context.Context, net.IP) (attribute.Set, error) { - return attribute.Set{}, nil - }, - } - mockFactory := ProviderFactoryMock{ - CreateDefaultConfigF: func() provider.Config { - type SampleConfig struct { - Database string `mapstructure:"database"` - } - return &SampleConfig{} - }, - CreateGeoIPProviderF: func(ctx context.Context, settings processor.CreateSettings, cfg provider.Config) (provider.GeoIPProvider, error) { - return &mockProvider, nil - }, + baseMockFactory.CreateDefaultConfigF = func() provider.Config { + type SampleConfig struct { + Database string `mapstructure:"database"` + } + return &SampleConfig{} } factories, err := otelcoltest.NopFactories() require.NoError(t, err) - providerFactories["mock"] = &mockFactory + providerFactories["mock"] = &baseMockFactory factory := NewFactory() factories.Processors[metadata.Type] = factory _, err = otelcoltest.LoadConfigAndValidate(filepath.Join("testdata", "config-mockProvider.yaml"), factories) assert.NoError(t, err) } + +func TestGeoProviderLocation(t *testing.T) { + exampleIP := net.IPv4(240, 0, 0, 0) + baseMockProvider.LocationF = func(ctx context.Context, ip net.IP) (attribute.Set, error) { + // dummy provider that only returns data if the IP is 240.0.0.0 + if ip.Equal(exampleIP) { + return attribute.NewSet( + attribute.String("geo.city_name", "Barcelona"), + attribute.String("geo.country_name", "Spain"), + ), nil + } + return attribute.NewSet(), nil + } + factory := NewFactory() + config := factory.CreateDefaultConfig() + geoCfg := config.(*Config) + geoCfg.Providers = make(map[string]provider.Config, 1) + geoCfg.Providers["mock"] = &baseMockFactory + + providers, err := createGeoIPProviders(context.Background(), processortest.NewNopCreateSettings(), geoCfg, providerFactories) + if err != nil { + t.Fatal(err) + } + + processor := newGeoIPProcessor(providers) + assert.Equal(t, 1, len(processor.providers)) + + attributes, err := processor.providers[0].Location(context.Background(), exampleIP) + assert.NoError(t, err) + value, has := attributes.Value("geo.city_name") + require.True(t, has) + require.Equal(t, "Barcelona", value.AsString()) +} From a7381aef0f0d969c629e104c6eb35af44dcb5f02 Mon Sep 17 00:00:00 2001 From: Roger Coll Date: Thu, 30 May 2024 11:37:43 +0200 Subject: [PATCH 06/23] chore: add changelog entry --- .chloggen/geoipprocessor_provider.yaml | 27 ++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .chloggen/geoipprocessor_provider.yaml diff --git a/.chloggen/geoipprocessor_provider.yaml b/.chloggen/geoipprocessor_provider.yaml new file mode 100644 index 000000000000..a8540e71a8df --- /dev/null +++ b/.chloggen/geoipprocessor_provider.yaml @@ -0,0 +1,27 @@ +# 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. filelogreceiver) +component: geoipprocessor + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add providers configuration and metadata retrival abstraction + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [33269] + +# (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: + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# 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: [] From 1d8dad283ec1c0ac6fac570f4e261ce98ed561d4 Mon Sep 17 00:00:00 2001 From: Roger Coll Date: Thu, 30 May 2024 11:38:36 +0200 Subject: [PATCH 07/23] fix format and linter --- processor/geoipprocessor/geoip_processor.go | 3 ++- .../internal/provider/geoipprovider.go | 2 +- processor/geoipprocessor/provider_test.go | 14 +++++++++----- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/processor/geoipprocessor/geoip_processor.go b/processor/geoipprocessor/geoip_processor.go index 2657a397dfe6..d5b7ea385fd9 100644 --- a/processor/geoipprocessor/geoip_processor.go +++ b/processor/geoipprocessor/geoip_processor.go @@ -6,10 +6,11 @@ package geoipprocessor // import "github.com/open-telemetry/opentelemetry-collec import ( "context" - "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider" "go.opentelemetry.io/collector/pdata/plog" "go.opentelemetry.io/collector/pdata/pmetric" "go.opentelemetry.io/collector/pdata/ptrace" + + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider" ) // GeoProviders will be used by the Processor retrieve geographical metadata given an IP address. diff --git a/processor/geoipprocessor/internal/provider/geoipprovider.go b/processor/geoipprocessor/internal/provider/geoipprovider.go index 2a850617cef4..758df501dab9 100644 --- a/processor/geoipprocessor/internal/provider/geoipprovider.go +++ b/processor/geoipprocessor/internal/provider/geoipprovider.go @@ -18,7 +18,7 @@ type GeoIPProvider interface { } // Config is the configuration of a GeoIPProvider. -type Config interface{} +type Config any // GeoIPProviderFactory can create GeoIPProvider instances. type GeoIPProviderFactory interface { diff --git a/processor/geoipprocessor/provider_test.go b/processor/geoipprocessor/provider_test.go index d3a6d16b8cac..5887f1766586 100644 --- a/processor/geoipprocessor/provider_test.go +++ b/processor/geoipprocessor/provider_test.go @@ -1,3 +1,6 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + package geoipprocessor import ( @@ -6,14 +9,15 @@ import ( "path/filepath" "testing" - "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/metadata" - "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/otelcol/otelcoltest" "go.opentelemetry.io/collector/processor" "go.opentelemetry.io/collector/processor/processortest" "go.opentelemetry.io/otel/attribute" + + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/metadata" + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider" ) type ProviderMock struct { @@ -22,7 +26,7 @@ type ProviderMock struct { type ProviderFactoryMock struct { CreateDefaultConfigF func() provider.Config - CreateGeoIPProviderF func(ctx context.Context, settings processor.CreateSettings, cfg provider.Config) (provider.GeoIPProvider, error) + CreateGeoIPProviderF func(context.Context, processor.CreateSettings, provider.Config) (provider.GeoIPProvider, error) } var ( @@ -53,7 +57,7 @@ var baseMockFactory = ProviderFactoryMock{ type emptyConfig struct{} return &emptyConfig{} }, - CreateGeoIPProviderF: func(ctx context.Context, settings processor.CreateSettings, cfg provider.Config) (provider.GeoIPProvider, error) { + CreateGeoIPProviderF: func(context.Context, processor.CreateSettings, provider.Config) (provider.GeoIPProvider, error) { return &baseMockProvider, nil }, } @@ -78,7 +82,7 @@ func TestLoadConfig_MockProvider(t *testing.T) { func TestGeoProviderLocation(t *testing.T) { exampleIP := net.IPv4(240, 0, 0, 0) - baseMockProvider.LocationF = func(ctx context.Context, ip net.IP) (attribute.Set, error) { + baseMockProvider.LocationF = func(_ context.Context, ip net.IP) (attribute.Set, error) { // dummy provider that only returns data if the IP is 240.0.0.0 if ip.Equal(exampleIP) { return attribute.NewSet( From 686b9e7af31476f7993abf852d6cb37b2e93aff3 Mon Sep 17 00:00:00 2001 From: Roger Coll Date: Fri, 31 May 2024 15:03:12 +0200 Subject: [PATCH 08/23] fix .chloggen/geoipprocessor_provider.yaml Co-authored-by: Andrzej Stencel --- .chloggen/geoipprocessor_provider.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.chloggen/geoipprocessor_provider.yaml b/.chloggen/geoipprocessor_provider.yaml index a8540e71a8df..6f86068dd465 100644 --- a/.chloggen/geoipprocessor_provider.yaml +++ b/.chloggen/geoipprocessor_provider.yaml @@ -7,7 +7,7 @@ change_type: 'enhancement' component: geoipprocessor # A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Add providers configuration and metadata retrival abstraction +note: Add providers configuration and metadata retrieval abstraction # Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. issues: [33269] From 9bbfd462e3f7b655f2390cd96af40ee658f5cd5c Mon Sep 17 00:00:00 2001 From: Roger Coll Date: Thu, 27 Jun 2024 16:07:22 +0200 Subject: [PATCH 09/23] chore: replace CreateSettings for Settings --- processor/geoipprocessor/config_test.go | 13 +++++++++++- processor/geoipprocessor/factory.go | 8 +++---- .../internal/provider/geoipprovider.go | 2 +- processor/geoipprocessor/provider_test.go | 21 ++++++++++++++----- 4 files changed, 33 insertions(+), 11 deletions(-) diff --git a/processor/geoipprocessor/config_test.go b/processor/geoipprocessor/config_test.go index acb8f56785d9..d3b73b508145 100644 --- a/processor/geoipprocessor/config_test.go +++ b/processor/geoipprocessor/config_test.go @@ -10,7 +10,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/confmap" "go.opentelemetry.io/collector/confmap/confmaptest" + "go.opentelemetry.io/collector/confmap/provider/fileprovider" + "go.opentelemetry.io/collector/otelcol" "go.opentelemetry.io/collector/otelcol/otelcoltest" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/metadata" @@ -59,7 +62,15 @@ func TestLoadInvalidConfig_InvalidProviderKey(t *testing.T) { factory := NewFactory() factories.Processors[metadata.Type] = factory - _, err = otelcoltest.LoadConfigAndValidate(filepath.Join("testdata", "config-invalidProviderKey.yaml"), factories) + _, err = otelcoltest.LoadConfigAndValidateWithSettings(factories, otelcol.ConfigProviderSettings{ + ResolverSettings: confmap.ResolverSettings{ + URIs: []string{filepath.Join("testdata", "config-invalidProviderKey.yaml")}, + ProviderFactories: []confmap.ProviderFactory{ + fileprovider.NewFactory(), + }, + }, + }, + ) require.Contains(t, err.Error(), "error reading configuration for \"geoip\": invalid provider key: invalidProviderKey") } diff --git a/processor/geoipprocessor/factory.go b/processor/geoipprocessor/factory.go index 9888f23c9c42..cf43611a87cb 100644 --- a/processor/geoipprocessor/factory.go +++ b/processor/geoipprocessor/factory.go @@ -50,7 +50,7 @@ func createDefaultConfig() component.Config { func createGeoIPProviders( ctx context.Context, - set processor.CreateSettings, + set processor.Settings, config *Config, factories map[string]provider.GeoIPProviderFactory, ) ([]provider.GeoIPProvider, error) { @@ -74,7 +74,7 @@ func createGeoIPProviders( return providers, nil } -func createMetricsProcessor(ctx context.Context, set processor.CreateSettings, cfg component.Config, nextConsumer consumer.Metrics) (processor.Metrics, error) { +func createMetricsProcessor(ctx context.Context, set processor.Settings, cfg component.Config, nextConsumer consumer.Metrics) (processor.Metrics, error) { geoCfg := cfg.(*Config) providers, err := createGeoIPProviders(ctx, set, geoCfg, providerFactories) if err != nil { @@ -83,7 +83,7 @@ func createMetricsProcessor(ctx context.Context, set processor.CreateSettings, c return processorhelper.NewMetricsProcessor(ctx, set, cfg, nextConsumer, newGeoIPProcessor(defaultResourceAttributes, providers).processMetrics, processorhelper.WithCapabilities(processorCapabilities)) } -func createTracesProcessor(ctx context.Context, set processor.CreateSettings, cfg component.Config, nextConsumer consumer.Traces) (processor.Traces, error) { +func createTracesProcessor(ctx context.Context, set processor.Settings, cfg component.Config, nextConsumer consumer.Traces) (processor.Traces, error) { geoCfg := cfg.(*Config) providers, err := createGeoIPProviders(ctx, set, geoCfg, providerFactories) if err != nil { @@ -92,7 +92,7 @@ func createTracesProcessor(ctx context.Context, set processor.CreateSettings, cf return processorhelper.NewTracesProcessor(ctx, set, cfg, nextConsumer, newGeoIPProcessor(defaultResourceAttributes, providers).processTraces, processorhelper.WithCapabilities(processorCapabilities)) } -func createLogsProcessor(ctx context.Context, set processor.CreateSettings, cfg component.Config, nextConsumer consumer.Logs) (processor.Logs, error) { +func createLogsProcessor(ctx context.Context, set processor.Settings, cfg component.Config, nextConsumer consumer.Logs) (processor.Logs, error) { geoCfg := cfg.(*Config) providers, err := createGeoIPProviders(ctx, set, geoCfg, providerFactories) if err != nil { diff --git a/processor/geoipprocessor/internal/provider/geoipprovider.go b/processor/geoipprocessor/internal/provider/geoipprovider.go index 819063b1f0da..434f84428b12 100644 --- a/processor/geoipprocessor/internal/provider/geoipprovider.go +++ b/processor/geoipprocessor/internal/provider/geoipprovider.go @@ -29,5 +29,5 @@ type GeoIPProviderFactory interface { CreateDefaultConfig() Config // CreateGeoIPProvider creates a provider based on this config. - CreateGeoIPProvider(ctx context.Context, settings processor.CreateSettings, cfg Config) (GeoIPProvider, error) + CreateGeoIPProvider(ctx context.Context, settings processor.Settings, cfg Config) (GeoIPProvider, error) } diff --git a/processor/geoipprocessor/provider_test.go b/processor/geoipprocessor/provider_test.go index 8829894947cf..545cea0fe670 100644 --- a/processor/geoipprocessor/provider_test.go +++ b/processor/geoipprocessor/provider_test.go @@ -11,6 +11,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/confmap" + "go.opentelemetry.io/collector/confmap/provider/fileprovider" + "go.opentelemetry.io/collector/otelcol" "go.opentelemetry.io/collector/otelcol/otelcoltest" "go.opentelemetry.io/collector/processor" "go.opentelemetry.io/collector/processor/processortest" @@ -26,7 +29,7 @@ type ProviderConfigMock struct { type ProviderFactoryMock struct { CreateDefaultConfigF func() provider.Config - CreateGeoIPProviderF func(context.Context, processor.CreateSettings, provider.Config) (provider.GeoIPProvider, error) + CreateGeoIPProviderF func(context.Context, processor.Settings, provider.Config) (provider.GeoIPProvider, error) } var ( @@ -42,7 +45,7 @@ func (fm *ProviderFactoryMock) CreateDefaultConfig() provider.Config { return fm.CreateDefaultConfigF() } -func (fm *ProviderFactoryMock) CreateGeoIPProvider(ctx context.Context, settings processor.CreateSettings, cfg provider.Config) (provider.GeoIPProvider, error) { +func (fm *ProviderFactoryMock) CreateGeoIPProvider(ctx context.Context, settings processor.Settings, cfg provider.Config) (provider.GeoIPProvider, error) { return fm.CreateGeoIPProviderF(ctx, settings, cfg) } @@ -56,7 +59,7 @@ var baseMockFactory = ProviderFactoryMock{ CreateDefaultConfigF: func() provider.Config { return &ProviderConfigMock{ValidateF: func() error { return nil }} }, - CreateGeoIPProviderF: func(context.Context, processor.CreateSettings, provider.Config) (provider.GeoIPProvider, error) { + CreateGeoIPProviderF: func(context.Context, processor.Settings, provider.Config) (provider.GeoIPProvider, error) { return &baseMockProvider, nil }, } @@ -79,7 +82,15 @@ func TestLoadConfig_MockProvider(t *testing.T) { providerFactories["mock"] = &baseMockFactory factory := NewFactory() factories.Processors[metadata.Type] = factory - _, err = otelcoltest.LoadConfigAndValidate(filepath.Join("testdata", "config-mockProvider.yaml"), factories) + _, err = otelcoltest.LoadConfigAndValidateWithSettings(factories, otelcol.ConfigProviderSettings{ + ResolverSettings: confmap.ResolverSettings{ + URIs: []string{filepath.Join("testdata", "config-mockProvider.yaml")}, + ProviderFactories: []confmap.ProviderFactory{ + fileprovider.NewFactory(), + }, + }, + }, + ) assert.NoError(t, err) } @@ -101,7 +112,7 @@ func TestGeoProviderLocation(t *testing.T) { geoCfg.Providers = make(map[string]provider.Config, 1) geoCfg.Providers["mock"] = baseMockFactory.CreateDefaultConfig() - providers, err := createGeoIPProviders(context.Background(), processortest.NewNopCreateSettings(), geoCfg, providerFactories) + providers, err := createGeoIPProviders(context.Background(), processortest.NewNopSettings(), geoCfg, providerFactories) if err != nil { t.Fatal(err) } From 81137cca9c0c0dffa34650715676803f26893a49 Mon Sep 17 00:00:00 2001 From: Roger Coll Date: Thu, 27 Jun 2024 18:05:29 +0200 Subject: [PATCH 10/23] feat: validate all providers configuration --- processor/geoipprocessor/config.go | 7 + processor/geoipprocessor/config_test.go | 65 ++++++++- processor/geoipprocessor/factory_test.go | 12 ++ .../geoipprocessor/geoip_processor_test.go | 51 ++++++- processor/geoipprocessor/provider_test.go | 128 ------------------ 5 files changed, 129 insertions(+), 134 deletions(-) delete mode 100644 processor/geoipprocessor/provider_test.go diff --git a/processor/geoipprocessor/config.go b/processor/geoipprocessor/config.go index 9dbe82437d85..f52cd47f6038 100644 --- a/processor/geoipprocessor/config.go +++ b/processor/geoipprocessor/config.go @@ -32,6 +32,13 @@ func (cfg *Config) Validate() error { if len(cfg.Providers) == 0 { return errors.New("must specify at least one geo IP data provider when using the geoip processor") } + + // validate all provider's configuration + for providerID, providerConfig := range cfg.Providers { + if err := providerConfig.Validate(); err != nil { + return fmt.Errorf("error validating provider %s: %w", providerID, err) + } + } return nil } diff --git a/processor/geoipprocessor/config_test.go b/processor/geoipprocessor/config_test.go index d3b73b508145..b38093843c02 100644 --- a/processor/geoipprocessor/config_test.go +++ b/processor/geoipprocessor/config_test.go @@ -4,6 +4,7 @@ package geoipprocessor import ( + "errors" "path/filepath" "testing" @@ -17,6 +18,7 @@ import ( "go.opentelemetry.io/collector/otelcol/otelcoltest" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/metadata" + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider" ) func TestLoadConfig(t *testing.T) { @@ -56,7 +58,7 @@ func TestLoadConfig(t *testing.T) { } } -func TestLoadInvalidConfig_InvalidProviderKey(t *testing.T) { +func TestLoadConfig_InvalidProviderKey(t *testing.T) { factories, err := otelcoltest.NopFactories() require.NoError(t, err) @@ -74,3 +76,64 @@ func TestLoadInvalidConfig_InvalidProviderKey(t *testing.T) { require.Contains(t, err.Error(), "error reading configuration for \"geoip\": invalid provider key: invalidProviderKey") } + +func TestLoadConfig_ValidProviderKey(t *testing.T) { + type dbMockConfig struct { + Database string `mapstructure:"database"` + providerConfigMock + } + baseMockFactory.CreateDefaultConfigF = func() provider.Config { + return &dbMockConfig{providerConfigMock: providerConfigMock{func() error { return nil }}} + } + providerFactories["mock"] = &baseMockFactory + + factories, err := otelcoltest.NopFactories() + require.NoError(t, err) + + factory := NewFactory() + factories.Processors[metadata.Type] = factory + collectorConfig, err := otelcoltest.LoadConfigAndValidateWithSettings(factories, otelcol.ConfigProviderSettings{ + ResolverSettings: confmap.ResolverSettings{ + URIs: []string{filepath.Join("testdata", "config-mockProvider.yaml")}, + ProviderFactories: []confmap.ProviderFactory{ + fileprovider.NewFactory(), + }, + }, + }, + ) + + require.NoError(t, err) + actualDbMockConfig := collectorConfig.Processors[component.NewID(metadata.Type)].(*Config).Providers["mock"].(*dbMockConfig) + require.Equal(t, "/tmp/geodata.csv", actualDbMockConfig.Database) +} + +func TestLoadConfig_ProviderValidateError(t *testing.T) { + baseMockFactory.CreateDefaultConfigF = func() provider.Config { + sampleConfig := struct { + Database string `mapstructure:"database"` + providerConfigMock + }{ + "", + providerConfigMock{func() error { return errors.New("error validating mocked config") }}, + } + return &sampleConfig + } + providerFactories["mock"] = &baseMockFactory + + factories, err := otelcoltest.NopFactories() + require.NoError(t, err) + + factory := NewFactory() + factories.Processors[metadata.Type] = factory + _, err = otelcoltest.LoadConfigAndValidateWithSettings(factories, otelcol.ConfigProviderSettings{ + ResolverSettings: confmap.ResolverSettings{ + URIs: []string{filepath.Join("testdata", "config-mockProvider.yaml")}, + ProviderFactories: []confmap.ProviderFactory{ + fileprovider.NewFactory(), + }, + }, + }, + ) + + require.Contains(t, err.Error(), "error validating provider mock") +} diff --git a/processor/geoipprocessor/factory_test.go b/processor/geoipprocessor/factory_test.go index 3305ee8f8aad..8dd26adaa8c2 100644 --- a/processor/geoipprocessor/factory_test.go +++ b/processor/geoipprocessor/factory_test.go @@ -5,8 +5,10 @@ package geoipprocessor import ( "context" + "fmt" "testing" + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider" "github.com/stretchr/testify/assert" "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/consumer/consumertest" @@ -50,3 +52,13 @@ func TestCreateProcessor(t *testing.T) { assert.NotNil(t, lp) assert.NoError(t, err) } + +func TestCreateProcessor_ProcessorKeyConfigError(t *testing.T) { + const errorKey string = "error" + + factory := NewFactory() + cfg := &Config{Providers: map[string]provider.Config{errorKey: &providerConfigMock{}}} + + _, err := factory.CreateMetricsProcessor(context.Background(), processortest.NewNopSettings(), cfg, consumertest.NewNop()) + assert.EqualError(t, err, fmt.Sprintf("geoIP provider factory not found for key: %q", errorKey)) +} diff --git a/processor/geoipprocessor/geoip_processor_test.go b/processor/geoipprocessor/geoip_processor_test.go index a0d1890ad038..d338db976e98 100644 --- a/processor/geoipprocessor/geoip_processor_test.go +++ b/processor/geoipprocessor/geoip_processor_test.go @@ -13,6 +13,7 @@ import ( "go.opentelemetry.io/collector/pdata/plog" "go.opentelemetry.io/collector/pdata/pmetric" "go.opentelemetry.io/collector/pdata/ptrace" + "go.opentelemetry.io/collector/processor" "go.opentelemetry.io/otel/attribute" semconv "go.opentelemetry.io/otel/semconv/v1.25.0" @@ -22,20 +23,60 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider" ) -type ProviderMock struct { +type providerConfigMock struct { + ValidateF func() error +} + +type providerFactoryMock struct { + CreateDefaultConfigF func() provider.Config + CreateGeoIPProviderF func(context.Context, processor.Settings, provider.Config) (provider.GeoIPProvider, error) +} + +type providerMock struct { LocationF func(context.Context, net.IP) (attribute.Set, error) } -var _ provider.GeoIPProvider = (*ProviderMock)(nil) +var ( + _ provider.GeoIPProvider = (*providerMock)(nil) + _ provider.GeoIPProvider = (*providerMock)(nil) + _ provider.GeoIPProviderFactory = (*providerFactoryMock)(nil) +) + +func (cm *providerConfigMock) Validate() error { + return cm.ValidateF() +} + +func (fm *providerFactoryMock) CreateDefaultConfig() provider.Config { + return fm.CreateDefaultConfigF() +} + +func (fm *providerFactoryMock) CreateGeoIPProvider(ctx context.Context, settings processor.Settings, cfg provider.Config) (provider.GeoIPProvider, error) { + return fm.CreateGeoIPProviderF(ctx, settings, cfg) +} + +func (pm *providerMock) Location(ctx context.Context, ip net.IP) (attribute.Set, error) { + return pm.LocationF(ctx, ip) +} -var baseProviderMock = ProviderMock{ +var baseMockProvider = providerMock{ LocationF: func(context.Context, net.IP) (attribute.Set, error) { return attribute.Set{}, nil }, } -func (pm *ProviderMock) Location(ctx context.Context, ip net.IP) (attribute.Set, error) { - return pm.LocationF(ctx, ip) +var baseMockFactory = providerFactoryMock{ + CreateDefaultConfigF: func() provider.Config { + return &providerConfigMock{ValidateF: func() error { return nil }} + }, + CreateGeoIPProviderF: func(context.Context, processor.Settings, provider.Config) (provider.GeoIPProvider, error) { + return &baseMockProvider, nil + }, +} + +var baseProviderMock = providerMock{ + LocationF: func(context.Context, net.IP) (attribute.Set, error) { + return attribute.Set{}, nil + }, } type generateResourceFunc func(res pcommon.Resource) diff --git a/processor/geoipprocessor/provider_test.go b/processor/geoipprocessor/provider_test.go deleted file mode 100644 index 545cea0fe670..000000000000 --- a/processor/geoipprocessor/provider_test.go +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package geoipprocessor - -import ( - "context" - "net" - "path/filepath" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/confmap" - "go.opentelemetry.io/collector/confmap/provider/fileprovider" - "go.opentelemetry.io/collector/otelcol" - "go.opentelemetry.io/collector/otelcol/otelcoltest" - "go.opentelemetry.io/collector/processor" - "go.opentelemetry.io/collector/processor/processortest" - "go.opentelemetry.io/otel/attribute" - - "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/metadata" - "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider" -) - -type ProviderConfigMock struct { - ValidateF func() error -} - -type ProviderFactoryMock struct { - CreateDefaultConfigF func() provider.Config - CreateGeoIPProviderF func(context.Context, processor.Settings, provider.Config) (provider.GeoIPProvider, error) -} - -var ( - _ provider.GeoIPProvider = (*ProviderMock)(nil) - _ provider.GeoIPProviderFactory = (*ProviderFactoryMock)(nil) -) - -func (cm *ProviderConfigMock) Validate() error { - return cm.ValidateF() -} - -func (fm *ProviderFactoryMock) CreateDefaultConfig() provider.Config { - return fm.CreateDefaultConfigF() -} - -func (fm *ProviderFactoryMock) CreateGeoIPProvider(ctx context.Context, settings processor.Settings, cfg provider.Config) (provider.GeoIPProvider, error) { - return fm.CreateGeoIPProviderF(ctx, settings, cfg) -} - -var baseMockProvider = ProviderMock{ - LocationF: func(context.Context, net.IP) (attribute.Set, error) { - return attribute.Set{}, nil - }, -} - -var baseMockFactory = ProviderFactoryMock{ - CreateDefaultConfigF: func() provider.Config { - return &ProviderConfigMock{ValidateF: func() error { return nil }} - }, - CreateGeoIPProviderF: func(context.Context, processor.Settings, provider.Config) (provider.GeoIPProvider, error) { - return &baseMockProvider, nil - }, -} - -func TestLoadConfig_MockProvider(t *testing.T) { - baseMockFactory.CreateDefaultConfigF = func() provider.Config { - dbConfig := struct { - Database string `mapstructure:"database"` - ProviderConfigMock - }{ - "", - ProviderConfigMock{ValidateF: func() error { return nil }}, - } - return &dbConfig - } - - factories, err := otelcoltest.NopFactories() - require.NoError(t, err) - - providerFactories["mock"] = &baseMockFactory - factory := NewFactory() - factories.Processors[metadata.Type] = factory - _, err = otelcoltest.LoadConfigAndValidateWithSettings(factories, otelcol.ConfigProviderSettings{ - ResolverSettings: confmap.ResolverSettings{ - URIs: []string{filepath.Join("testdata", "config-mockProvider.yaml")}, - ProviderFactories: []confmap.ProviderFactory{ - fileprovider.NewFactory(), - }, - }, - }, - ) - assert.NoError(t, err) -} - -func TestGeoProviderLocation(t *testing.T) { - exampleIP := net.IPv4(240, 0, 0, 0) - baseMockProvider.LocationF = func(_ context.Context, ip net.IP) (attribute.Set, error) { - // dummy provider that only returns data if the IP is 240.0.0.0 - if ip.Equal(exampleIP) { - return attribute.NewSet( - attribute.String("geo.city_name", "Barcelona"), - attribute.String("geo.country_name", "Spain"), - ), nil - } - return attribute.NewSet(), nil - } - factory := NewFactory() - config := factory.CreateDefaultConfig() - geoCfg := config.(*Config) - geoCfg.Providers = make(map[string]provider.Config, 1) - geoCfg.Providers["mock"] = baseMockFactory.CreateDefaultConfig() - - providers, err := createGeoIPProviders(context.Background(), processortest.NewNopSettings(), geoCfg, providerFactories) - if err != nil { - t.Fatal(err) - } - - processor := newGeoIPProcessor(defaultResourceAttributes, providers) - assert.Equal(t, 1, len(processor.providers)) - - attributes, err := processor.providers[0].Location(context.Background(), exampleIP) - assert.NoError(t, err) - value, has := attributes.Value("geo.city_name") - require.True(t, has) - require.Equal(t, "Barcelona", value.AsString()) -} From 87b0161f201ff191b741d388927db5da60dbbf47 Mon Sep 17 00:00:00 2001 From: Roger Coll Date: Fri, 28 Jun 2024 10:47:45 +0200 Subject: [PATCH 11/23] feat: add maxmind provider factory --- processor/geoipprocessor/factory.go | 5 +- processor/geoipprocessor/integration_test.go | 90 +++++++++++++++++++ .../internal/provider/geoipprovider.go | 2 +- .../provider/maxmindprovider/factory.go | 32 +++++++ .../provider/maxmindprovider/factory_test.go | 30 +++++++ .../provider/maxmindprovider/provider_test.go | 24 +---- .../maxmindprovider/testdata/generate_db.go | 31 +++++++ 7 files changed, 190 insertions(+), 24 deletions(-) create mode 100644 processor/geoipprocessor/integration_test.go create mode 100644 processor/geoipprocessor/internal/provider/maxmindprovider/factory.go create mode 100644 processor/geoipprocessor/internal/provider/maxmindprovider/factory_test.go create mode 100644 processor/geoipprocessor/internal/provider/maxmindprovider/testdata/generate_db.go diff --git a/processor/geoipprocessor/factory.go b/processor/geoipprocessor/factory.go index cf43611a87cb..dbc14ee72bb5 100644 --- a/processor/geoipprocessor/factory.go +++ b/processor/geoipprocessor/factory.go @@ -16,6 +16,7 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/metadata" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider" + maxmind "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider/maxmindprovider" ) var ( @@ -27,7 +28,9 @@ var ( } ) -var providerFactories = map[string]provider.GeoIPProviderFactory{} +var providerFactories = map[string]provider.GeoIPProviderFactory{ + maxmind.TypeStr: &maxmind.Factory{}, +} // NewFactory creates a new processor factory with default configuration, // and registers the processors for metrics, traces, and logs. diff --git a/processor/geoipprocessor/integration_test.go b/processor/geoipprocessor/integration_test.go new file mode 100644 index 000000000000..bd948b959b31 --- /dev/null +++ b/processor/geoipprocessor/integration_test.go @@ -0,0 +1,90 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package geoipprocessor + +import ( + "context" + "os" + "testing" + + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest/plogtest" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest/pmetrictest" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest/ptracetest" + conventions "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/convention" + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider" + maxmind "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider/maxmindprovider" + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider/maxmindprovider/testdata" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/consumer/consumertest" + "go.opentelemetry.io/collector/processor/processortest" + "go.opentelemetry.io/otel/attribute" + semconv "go.opentelemetry.io/otel/semconv/v1.21.0" +) + +func TestProcessorWithMaxMind(t *testing.T) { + t.Parallel() + + tmpDBfiles := testdata.GenerateLocalDB(t, "./internal/provider/maxmindprovider/testdata/") + defer os.RemoveAll(tmpDBfiles) + + factory := NewFactory() + maxmindConfig := maxmind.Config{} + maxmindConfig.DatabasePath = tmpDBfiles + "/" + "GeoLite2-City-Test.mmdb" + cfg := &Config{Providers: map[string]provider.Config{"maxmind": &maxmindConfig}} + + actualAttributes := withAttributes([]attribute.KeyValue{semconv.SourceAddress("1.2.3.4")}) + expectedAttributes := withAttributes([]attribute.KeyValue{ + semconv.SourceAddress("1.2.3.4"), + attribute.String(conventions.AttributeGeoCityName, "Boxford"), + attribute.String(conventions.AttributeGeoContinentCode, "EU"), + attribute.String(conventions.AttributeGeoContinentName, "Europe"), + attribute.String(conventions.AttributeGeoCountryIsoCode, "GB"), + attribute.String(conventions.AttributeGeoCountryName, "United Kingdom"), + attribute.String(conventions.AttributeGeoTimezone, "Europe/London"), + attribute.String(conventions.AttributeGeoRegionIsoCode, "WBK"), + attribute.String(conventions.AttributeGeoRegionName, "West Berkshire"), + attribute.String(conventions.AttributeGeoPostalCode, "OX1"), + attribute.Float64(conventions.AttributeGeoLocationLat, 1234), + attribute.Float64(conventions.AttributeGeoLocationLon, 5678), + }) + + // verify metrics + nextMetrics := new(consumertest.MetricsSink) + metricsProcessor, err := factory.CreateMetricsProcessor(context.Background(), processortest.NewNopSettings(), cfg, nextMetrics) + require.NoError(t, err) + err = metricsProcessor.ConsumeMetrics(context.Background(), generateMetrics(actualAttributes)) + require.NoError(t, err) + + actualMetrics := nextMetrics.AllMetrics() + require.Equal(t, 1, len(actualMetrics)) + require.NoError(t, pmetrictest.CompareMetrics(generateMetrics(expectedAttributes), actualMetrics[0])) + + // the testing database does not contain metadata for IP 40.0.0.0, see ./internal/provider/maxmindprovider/testdata/GeoLite2-City-Test.json + err = metricsProcessor.ConsumeMetrics(context.Background(), generateMetrics(withAttributes([]attribute.KeyValue{ + semconv.SourceAddress("40.0.0.0"), + }))) + require.Contains(t, err.Error(), "no geo IP metadata found") + + // verify logs + nextLogs := new(consumertest.LogsSink) + logsProcessor, err := factory.CreateLogsProcessor(context.Background(), processortest.NewNopSettings(), cfg, nextLogs) + require.NoError(t, err) + err = logsProcessor.ConsumeLogs(context.Background(), generateLogs(actualAttributes)) + require.NoError(t, err) + + actualLogs := nextLogs.AllLogs() + require.Equal(t, 1, len(actualLogs)) + require.NoError(t, plogtest.CompareLogs(generateLogs(expectedAttributes), actualLogs[0])) + + // verify traces + nextTraces := new(consumertest.TracesSink) + tracesProcessor, err := factory.CreateTracesProcessor(context.Background(), processortest.NewNopSettings(), cfg, nextTraces) + require.NoError(t, err) + err = tracesProcessor.ConsumeTraces(context.Background(), generateTraces(actualAttributes)) + require.NoError(t, err) + + actualTraces := nextTraces.AllTraces() + require.Equal(t, 1, len(actualTraces)) + require.NoError(t, ptracetest.CompareTraces(generateTraces(expectedAttributes), actualTraces[0])) +} diff --git a/processor/geoipprocessor/internal/provider/geoipprovider.go b/processor/geoipprocessor/internal/provider/geoipprovider.go index 434f84428b12..2e29ac48112b 100644 --- a/processor/geoipprocessor/internal/provider/geoipprovider.go +++ b/processor/geoipprocessor/internal/provider/geoipprovider.go @@ -28,6 +28,6 @@ type GeoIPProviderFactory interface { // CreateDefaultConfig creates the default configuration for the GeoIPProvider. CreateDefaultConfig() Config - // CreateGeoIPProvider creates a provider based on this config. + // CreateGeoIPProvider creates a provider based on this config. Processor's settings are provided as an argument to initialize the logger if needed. CreateGeoIPProvider(ctx context.Context, settings processor.Settings, cfg Config) (GeoIPProvider, error) } diff --git a/processor/geoipprocessor/internal/provider/maxmindprovider/factory.go b/processor/geoipprocessor/internal/provider/maxmindprovider/factory.go new file mode 100644 index 000000000000..2538184958cc --- /dev/null +++ b/processor/geoipprocessor/internal/provider/maxmindprovider/factory.go @@ -0,0 +1,32 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package maxmind // import "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider/maxmindprovider" + +import ( + "context" + + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider" + "go.opentelemetry.io/collector/processor" +) // This file implements Factory for the MaxMind provider. + +const ( + // TypeStr the value of "type" key in configuration. + TypeStr = "maxmind" +) + +// Factory is the Factory for scraper. +type Factory struct{} + +var _ provider.GeoIPProviderFactory = (*Factory)(nil) + +// CreateDefaultConfig creates the default configuration for the Provider. +func (f *Factory) CreateDefaultConfig() provider.Config { + return &Config{} +} + +// CreateGeoIPProvider creates a provider based on this config. +func (f *Factory) CreateGeoIPProvider(ctx context.Context, settings processor.Settings, cfg provider.Config) (provider.GeoIPProvider, error) { + maxMindConfig := cfg.(*Config) + return newMaxMindProvider(maxMindConfig) +} diff --git a/processor/geoipprocessor/internal/provider/maxmindprovider/factory_test.go b/processor/geoipprocessor/internal/provider/maxmindprovider/factory_test.go new file mode 100644 index 000000000000..a70bd4bc4267 --- /dev/null +++ b/processor/geoipprocessor/internal/provider/maxmindprovider/factory_test.go @@ -0,0 +1,30 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package maxmind + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "go.opentelemetry.io/collector/processor/processortest" +) + +func TestCreateDefaultConfig(t *testing.T) { + factory := &Factory{} + cfg := factory.CreateDefaultConfig() + assert.IsType(t, &Config{}, cfg) +} + +func TestCreateProvider(t *testing.T) { + factory := &Factory{} + cfg := &Config{ + DatabasePath: "", + } + + provider, err := factory.CreateGeoIPProvider(context.Background(), processortest.NewNopSettings(), cfg) + + assert.Contains(t, err.Error(), "could not open geoip database") + assert.Nil(t, provider) +} diff --git a/processor/geoipprocessor/internal/provider/maxmindprovider/provider_test.go b/processor/geoipprocessor/internal/provider/maxmindprovider/provider_test.go index c9de227a8f6f..c118cc2653c6 100644 --- a/processor/geoipprocessor/internal/provider/maxmindprovider/provider_test.go +++ b/processor/geoipprocessor/internal/provider/maxmindprovider/provider_test.go @@ -9,12 +9,12 @@ import ( "os" "testing" - "github.com/maxmind/MaxMind-DB/pkg/writer" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.opentelemetry.io/otel/attribute" conventions "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/convention" + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider/maxmindprovider/testdata" ) func TestInvalidNewProvider(t *testing.T) { @@ -25,29 +25,9 @@ func TestInvalidNewProvider(t *testing.T) { require.ErrorContains(t, err, "could not open geoip database: open no valid path: no such file or directory") } -// generateLocalDB generates *.mmdb databases files given a source directory data. It uses a the writer functionality provided by MaxMind-Db/pkg/writer -func generateLocalDB(t *testing.T, sourceData string) string { - tmpDir, err := os.MkdirTemp("", "") - if err != nil { - t.Fatal(err) - } - - w, err := writer.New(sourceData, tmpDir) - if err != nil { - t.Fatal(err) - } - - err = w.WriteGeoIP2TestDB() - if err != nil { - t.Fatal(err) - } - - return tmpDir -} - // TestProviderLocation asserts that the MaxMind provider adds the geo location data given an IP. func TestProviderLocation(t *testing.T) { - tmpDBfiles := generateLocalDB(t, "./testdata") + tmpDBfiles := testdata.GenerateLocalDB(t, "./testdata") defer os.RemoveAll(tmpDBfiles) t.Parallel() diff --git a/processor/geoipprocessor/internal/provider/maxmindprovider/testdata/generate_db.go b/processor/geoipprocessor/internal/provider/maxmindprovider/testdata/generate_db.go new file mode 100644 index 000000000000..335713f2deec --- /dev/null +++ b/processor/geoipprocessor/internal/provider/maxmindprovider/testdata/generate_db.go @@ -0,0 +1,31 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package testdata + +import ( + "os" + "testing" + + "github.com/maxmind/MaxMind-DB/pkg/writer" +) + +// GenerateLocalDB generates *.mmdb databases files given a source directory data. It uses a the writer functionality provided by MaxMind-Db/pkg/writer +func GenerateLocalDB(t *testing.T, sourceData string) string { + tmpDir, err := os.MkdirTemp("", "") + if err != nil { + t.Fatal(err) + } + + w, err := writer.New(sourceData, tmpDir) + if err != nil { + t.Fatal(err) + } + + err = w.WriteGeoIP2TestDB() + if err != nil { + t.Fatal(err) + } + + return tmpDir +} From 31ba472d9b825d47023ba481f4997ee55ff86081 Mon Sep 17 00:00:00 2001 From: Roger Coll Date: Fri, 28 Jun 2024 11:42:35 +0200 Subject: [PATCH 12/23] add configuration unmarshal test cases --- processor/geoipprocessor/config_test.go | 52 ++++++++++++++++--- processor/geoipprocessor/factory_test.go | 23 ++++++++ processor/geoipprocessor/testdata/config.yaml | 6 +++ 3 files changed, 74 insertions(+), 7 deletions(-) diff --git a/processor/geoipprocessor/config_test.go b/processor/geoipprocessor/config_test.go index b38093843c02..60e217233320 100644 --- a/processor/geoipprocessor/config_test.go +++ b/processor/geoipprocessor/config_test.go @@ -19,19 +19,33 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/metadata" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider" + maxmind "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider/maxmindprovider" ) func TestLoadConfig(t *testing.T) { t.Parallel() tests := []struct { - id component.ID - expected component.Config - errorMessage string + id component.ID + expected component.Config + validateErrorMessage string + unmarshalErrorMessage string }{ { - id: component.NewID(metadata.Type), - errorMessage: "must specify at least one geo IP data provider when using the geoip processor", + id: component.NewID(metadata.Type), + validateErrorMessage: "must specify at least one geo IP data provider when using the geoip processor", + }, + { + id: component.NewIDWithName(metadata.Type, "maxmind"), + expected: &Config{ + Providers: map[string]provider.Config{ + "maxmind": &maxmind.Config{DatabasePath: "/tmp/db"}, + }, + }, + }, + { + id: component.NewIDWithName(metadata.Type, "invalid_providers_config"), + unmarshalErrorMessage: "unexpected sub-config value kind for key:providers value:this should be a map kind:string)", }, } @@ -45,10 +59,15 @@ func TestLoadConfig(t *testing.T) { sub, err := cm.Sub(tt.id.String()) require.NoError(t, err) + + if tt.unmarshalErrorMessage != "" { + assert.EqualError(t, sub.Unmarshal(cfg), tt.unmarshalErrorMessage) + return + } require.NoError(t, sub.Unmarshal(cfg)) - if tt.errorMessage != "" { - assert.EqualError(t, component.ValidateConfig(cfg), tt.errorMessage) + if tt.validateErrorMessage != "" { + assert.EqualError(t, component.ValidateConfig(cfg), tt.validateErrorMessage) return } @@ -105,6 +124,25 @@ func TestLoadConfig_ValidProviderKey(t *testing.T) { require.NoError(t, err) actualDbMockConfig := collectorConfig.Processors[component.NewID(metadata.Type)].(*Config).Providers["mock"].(*dbMockConfig) require.Equal(t, "/tmp/geodata.csv", actualDbMockConfig.Database) + + // assert provider unmarshall configuration error by removing database field + baseMockFactory.CreateDefaultConfigF = func() provider.Config { + return &providerConfigMock{func() error { return nil }} + } + providerFactories["mock"] = &baseMockFactory + + factories.Processors[metadata.Type] = factory + _, err = otelcoltest.LoadConfigAndValidateWithSettings(factories, otelcol.ConfigProviderSettings{ + ResolverSettings: confmap.ResolverSettings{ + URIs: []string{filepath.Join("testdata", "config-mockProvider.yaml")}, + ProviderFactories: []confmap.ProviderFactory{ + fileprovider.NewFactory(), + }, + }, + }, + ) + + require.ErrorContains(t, err, "has invalid keys: database") } func TestLoadConfig_ProviderValidateError(t *testing.T) { diff --git a/processor/geoipprocessor/factory_test.go b/processor/geoipprocessor/factory_test.go index 8dd26adaa8c2..7e6740f9c813 100644 --- a/processor/geoipprocessor/factory_test.go +++ b/processor/geoipprocessor/factory_test.go @@ -5,6 +5,7 @@ package geoipprocessor import ( "context" + "errors" "fmt" "testing" @@ -12,6 +13,7 @@ import ( "github.com/stretchr/testify/assert" "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/consumer/consumertest" + "go.opentelemetry.io/collector/processor" "go.opentelemetry.io/collector/processor/processortest" ) @@ -61,4 +63,25 @@ func TestCreateProcessor_ProcessorKeyConfigError(t *testing.T) { _, err := factory.CreateMetricsProcessor(context.Background(), processortest.NewNopSettings(), cfg, consumertest.NewNop()) assert.EqualError(t, err, fmt.Sprintf("geoIP provider factory not found for key: %q", errorKey)) + + _, err = factory.CreateLogsProcessor(context.Background(), processortest.NewNopSettings(), cfg, consumertest.NewNop()) + assert.EqualError(t, err, fmt.Sprintf("geoIP provider factory not found for key: %q", errorKey)) + + _, err = factory.CreateTracesProcessor(context.Background(), processortest.NewNopSettings(), cfg, consumertest.NewNop()) + assert.EqualError(t, err, fmt.Sprintf("geoIP provider factory not found for key: %q", errorKey)) +} + +func TestCreateProcessor_FailedProvider(t *testing.T) { + baseMockFactory.CreateGeoIPProviderF = func(context.Context, processor.Settings, provider.Config) (provider.GeoIPProvider, error) { + return nil, errors.New("error creating provider") + } + + const providerKey string = "mock" + providerFactories[providerKey] = &baseMockFactory + + factory := NewFactory() + cfg := &Config{Providers: map[string]provider.Config{providerKey: &providerConfigMock{}}} + + _, err := factory.CreateMetricsProcessor(context.Background(), processortest.NewNopSettings(), cfg, consumertest.NewNop()) + assert.EqualError(t, err, fmt.Errorf("failed to create provider for key %q: %w", providerKey, errors.New("error creating provider")).Error()) } diff --git a/processor/geoipprocessor/testdata/config.yaml b/processor/geoipprocessor/testdata/config.yaml index 870494e36a73..8590afcb2126 100644 --- a/processor/geoipprocessor/testdata/config.yaml +++ b/processor/geoipprocessor/testdata/config.yaml @@ -1 +1,7 @@ geoip: +geoip/maxmind: + providers: + maxmind: + database_path: /tmp/db +geoip/invalid_providers_config: + providers: "this should be a map" From 0cec8472e5b67ff20ca3cc741b821a875ae9d04e Mon Sep 17 00:00:00 2001 From: Roger Coll Date: Fri, 28 Jun 2024 11:51:15 +0200 Subject: [PATCH 13/23] chore: tidy mod files --- processor/geoipprocessor/config_test.go | 2 +- processor/geoipprocessor/go.mod | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/processor/geoipprocessor/config_test.go b/processor/geoipprocessor/config_test.go index 60e217233320..a1e6400cbc02 100644 --- a/processor/geoipprocessor/config_test.go +++ b/processor/geoipprocessor/config_test.go @@ -125,7 +125,7 @@ func TestLoadConfig_ValidProviderKey(t *testing.T) { actualDbMockConfig := collectorConfig.Processors[component.NewID(metadata.Type)].(*Config).Providers["mock"].(*dbMockConfig) require.Equal(t, "/tmp/geodata.csv", actualDbMockConfig.Database) - // assert provider unmarshall configuration error by removing database field + // assert provider unmarshall configuration error by removing the database fieldfrom the configuration struct baseMockFactory.CreateDefaultConfigF = func() provider.Config { return &providerConfigMock{func() error { return nil }} } diff --git a/processor/geoipprocessor/go.mod b/processor/geoipprocessor/go.mod index 326bf251e1d9..85e20d831aa3 100644 --- a/processor/geoipprocessor/go.mod +++ b/processor/geoipprocessor/go.mod @@ -63,7 +63,7 @@ require ( go.opentelemetry.io/collector/config/configtelemetry v0.103.0 // indirect go.opentelemetry.io/collector/confmap/converter/expandconverter v0.103.0 // indirect go.opentelemetry.io/collector/confmap/provider/envprovider v0.103.0 // indirect - go.opentelemetry.io/collector/confmap/provider/fileprovider v0.103.0 // indirect + go.opentelemetry.io/collector/confmap/provider/fileprovider v0.103.0 go.opentelemetry.io/collector/confmap/provider/httpprovider v0.103.0 // indirect go.opentelemetry.io/collector/confmap/provider/httpsprovider v0.103.0 // indirect go.opentelemetry.io/collector/confmap/provider/yamlprovider v0.103.0 // indirect From be9e2dff63b13be3595bc3e3c1047139eab79527 Mon Sep 17 00:00:00 2001 From: Roger Coll Date: Fri, 28 Jun 2024 11:52:49 +0200 Subject: [PATCH 14/23] chore: update changelog to reflect maxmind --- .chloggen/geoipprocessor_provider.yaml | 2 +- .../geoipprocessor/internal/provider/maxmindprovider/factory.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.chloggen/geoipprocessor_provider.yaml b/.chloggen/geoipprocessor_provider.yaml index 6f86068dd465..df17cf4def4a 100644 --- a/.chloggen/geoipprocessor_provider.yaml +++ b/.chloggen/geoipprocessor_provider.yaml @@ -7,7 +7,7 @@ change_type: 'enhancement' component: geoipprocessor # A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). -note: Add providers configuration and metadata retrieval abstraction +note: Add providers configuration and maxmind provider factory # Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. issues: [33269] diff --git a/processor/geoipprocessor/internal/provider/maxmindprovider/factory.go b/processor/geoipprocessor/internal/provider/maxmindprovider/factory.go index 2538184958cc..c4702521f471 100644 --- a/processor/geoipprocessor/internal/provider/maxmindprovider/factory.go +++ b/processor/geoipprocessor/internal/provider/maxmindprovider/factory.go @@ -15,7 +15,7 @@ const ( TypeStr = "maxmind" ) -// Factory is the Factory for scraper. +// Factory is the Factory for the MaxMind GeoIP provider. type Factory struct{} var _ provider.GeoIPProviderFactory = (*Factory)(nil) From 74bde0866c2fb0b62e2a72590b70c0f50398add3 Mon Sep 17 00:00:00 2001 From: Roger Coll Date: Fri, 28 Jun 2024 12:08:54 +0200 Subject: [PATCH 15/23] chore: fix imports order --- processor/geoipprocessor/factory_test.go | 3 ++- processor/geoipprocessor/integration_test.go | 11 ++++++----- .../internal/provider/maxmindprovider/factory.go | 7 ++++--- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/processor/geoipprocessor/factory_test.go b/processor/geoipprocessor/factory_test.go index 7e6740f9c813..eec26135f3ec 100644 --- a/processor/geoipprocessor/factory_test.go +++ b/processor/geoipprocessor/factory_test.go @@ -9,12 +9,13 @@ import ( "fmt" "testing" - "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider" "github.com/stretchr/testify/assert" "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/processor" "go.opentelemetry.io/collector/processor/processortest" + + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider" ) func TestCreateDefaultConfig(t *testing.T) { diff --git a/processor/geoipprocessor/integration_test.go b/processor/geoipprocessor/integration_test.go index bd948b959b31..dc518aff89fe 100644 --- a/processor/geoipprocessor/integration_test.go +++ b/processor/geoipprocessor/integration_test.go @@ -8,6 +8,12 @@ import ( "os" "testing" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/consumer/consumertest" + "go.opentelemetry.io/collector/processor/processortest" + "go.opentelemetry.io/otel/attribute" + semconv "go.opentelemetry.io/otel/semconv/v1.21.0" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest/plogtest" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest/pmetrictest" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest/ptracetest" @@ -15,11 +21,6 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider" maxmind "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider/maxmindprovider" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider/maxmindprovider/testdata" - "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/consumer/consumertest" - "go.opentelemetry.io/collector/processor/processortest" - "go.opentelemetry.io/otel/attribute" - semconv "go.opentelemetry.io/otel/semconv/v1.21.0" ) func TestProcessorWithMaxMind(t *testing.T) { diff --git a/processor/geoipprocessor/internal/provider/maxmindprovider/factory.go b/processor/geoipprocessor/internal/provider/maxmindprovider/factory.go index c4702521f471..061dee9cd1d0 100644 --- a/processor/geoipprocessor/internal/provider/maxmindprovider/factory.go +++ b/processor/geoipprocessor/internal/provider/maxmindprovider/factory.go @@ -6,9 +6,10 @@ package maxmind // import "github.com/open-telemetry/opentelemetry-collector-con import ( "context" - "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider" "go.opentelemetry.io/collector/processor" -) // This file implements Factory for the MaxMind provider. + + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/provider" +) const ( // TypeStr the value of "type" key in configuration. @@ -26,7 +27,7 @@ func (f *Factory) CreateDefaultConfig() provider.Config { } // CreateGeoIPProvider creates a provider based on this config. -func (f *Factory) CreateGeoIPProvider(ctx context.Context, settings processor.Settings, cfg provider.Config) (provider.GeoIPProvider, error) { +func (f *Factory) CreateGeoIPProvider(_ context.Context, _ processor.Settings, cfg provider.Config) (provider.GeoIPProvider, error) { maxMindConfig := cfg.(*Config) return newMaxMindProvider(maxMindConfig) } From 05d0be95b74e9241713c4dbf5d0ccb07a1109172 Mon Sep 17 00:00:00 2001 From: Roger Coll Date: Fri, 28 Jun 2024 12:23:07 +0200 Subject: [PATCH 16/23] docs: add configuration section --- processor/geoipprocessor/README.md | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/processor/geoipprocessor/README.md b/processor/geoipprocessor/README.md index ccf54378872f..d73b67c7a138 100644 --- a/processor/geoipprocessor/README.md +++ b/processor/geoipprocessor/README.md @@ -11,8 +11,24 @@ [development]: https://github.com/open-telemetry/opentelemetry-collector#development -**This processor is currently under development and is presently a NOP (No Operation) processor. Further features and functionalities will be added in upcoming versions.** - ## Description The geoIP processor `geoipprocessor` enhances resource attributes by appending information about the geographical location of an IP address. To add geographical information, the IP address must be included in the resource attributes using the [`source.address` semantic conventions key attribute](https://github.com/open-telemetry/semantic-conventions/blob/v1.26.0/docs/general/attributes.md#source). + +## Configuration + +The following settings must configured: + +- `providers`: A map containing geographical location information providers. These providers are used to search for the geographical location attributes associated with an IP. Available providers: + - [MaxMind](./internal/provider/maxmindprovider/README.md) + +#### Examples + +```yaml +processors: + # processor name: geoip + geoip: + providers: + maxmind: + database_path: /tmp/mygeodb +``` From f20bfc4b8d0eabe2155772c301fbeefd687607ed Mon Sep 17 00:00:00 2001 From: Roger Coll Date: Fri, 28 Jun 2024 12:30:45 +0200 Subject: [PATCH 17/23] chore: add comments to factory methods --- processor/geoipprocessor/config.go | 3 ++- processor/geoipprocessor/factory.go | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/processor/geoipprocessor/config.go b/processor/geoipprocessor/config.go index f52cd47f6038..685052623d68 100644 --- a/processor/geoipprocessor/config.go +++ b/processor/geoipprocessor/config.go @@ -55,14 +55,15 @@ func (cfg *Config) Unmarshal(componentParser *confmap.Conf) error { } // dynamically load the individual providers configs based on the key name - cfg.Providers = map[string]provider.Config{} + // retrieve `providers` configuration section providersSection, err := componentParser.Sub(providerKey) if err != nil { return err } + // loop through all defined providers and load their configuration for key := range providersSection.ToStringMap() { factory, ok := getProviderFactory(key) if !ok { diff --git a/processor/geoipprocessor/factory.go b/processor/geoipprocessor/factory.go index dbc14ee72bb5..2c80c6fe6d5d 100644 --- a/processor/geoipprocessor/factory.go +++ b/processor/geoipprocessor/factory.go @@ -28,6 +28,7 @@ var ( } ) +// providerFactories is a map that stores GeoIPProviderFactory instances, keyed by the provider type. var providerFactories = map[string]provider.GeoIPProviderFactory{ maxmind.TypeStr: &maxmind.Factory{}, } @@ -38,6 +39,8 @@ func NewFactory() processor.Factory { return processor.NewFactory(metadata.Type, createDefaultConfig, processor.WithMetrics(createMetricsProcessor, metadata.MetricsStability), processor.WithLogs(createLogsProcessor, metadata.LogsStability), processor.WithTraces(createTracesProcessor, metadata.TracesStability)) } +// getProviderFactory retrieves the GeoIPProviderFactory for the given key. +// It returns the factory and a boolean indicating whether the factory was found. func getProviderFactory(key string) (provider.GeoIPProviderFactory, bool) { if factory, ok := providerFactories[key]; ok { return factory, true @@ -51,6 +54,7 @@ func createDefaultConfig() component.Config { return &Config{} } +// createGeoIPProviders creates a list of GeoIPProvider instances based on the provided configuration and providers factories. func createGeoIPProviders( ctx context.Context, set processor.Settings, From f7f9902010b23a2e9bf22ede07455318c43b6add Mon Sep 17 00:00:00 2001 From: Roger Coll Date: Fri, 28 Jun 2024 12:50:31 +0200 Subject: [PATCH 18/23] docs: reference added attributes --- processor/geoipprocessor/README.md | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/processor/geoipprocessor/README.md b/processor/geoipprocessor/README.md index d73b67c7a138..10356b89c939 100644 --- a/processor/geoipprocessor/README.md +++ b/processor/geoipprocessor/README.md @@ -15,12 +15,30 @@ The geoIP processor `geoipprocessor` enhances resource attributes by appending information about the geographical location of an IP address. To add geographical information, the IP address must be included in the resource attributes using the [`source.address` semantic conventions key attribute](https://github.com/open-telemetry/semantic-conventions/blob/v1.26.0/docs/general/attributes.md#source). +### Geographical location metadata + +The following [resource attributes](./internal/convention/attributes.go) will be added if the corresponding information is found: + +``` + * geo.city_name + * geo.postal_code + * geo.country_name + * geo.country_iso_code + * geo.continent_name + * geo.continent_code + * geo.region_name + * geo.region_iso_code + * geo.timezone + * geo.location.lat + * geo.location.lon +``` + ## Configuration -The following settings must configured: +The following settings must be configured: -- `providers`: A map containing geographical location information providers. These providers are used to search for the geographical location attributes associated with an IP. Available providers: - - [MaxMind](./internal/provider/maxmindprovider/README.md) +- `providers`: A map containing geographical location information providers. These providers are used to search for the geographical location attributes associated with an IP. Supported providers: + - [maxmind](./internal/provider/maxmindprovider/README.md) #### Examples From f8c2991b9958ddf926748125ba72a9fa77f03819 Mon Sep 17 00:00:00 2001 From: Roger Coll Date: Fri, 28 Jun 2024 12:54:07 +0200 Subject: [PATCH 19/23] chore: remove additional require mod section --- processor/geoipprocessor/go.mod | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/processor/geoipprocessor/go.mod b/processor/geoipprocessor/go.mod index 85e20d831aa3..2642e0f12de3 100644 --- a/processor/geoipprocessor/go.mod +++ b/processor/geoipprocessor/go.mod @@ -3,10 +3,13 @@ module github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoip go 1.21.0 require ( + github.com/maxmind/MaxMind-DB v0.0.0-20240605211347-880f6b4b5eb6 github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest v0.103.0 + github.com/oschwald/geoip2-golang v1.11.0 github.com/stretchr/testify v1.9.0 go.opentelemetry.io/collector/component v0.103.0 go.opentelemetry.io/collector/confmap v0.103.0 + go.opentelemetry.io/collector/confmap/provider/fileprovider v0.103.0 go.opentelemetry.io/collector/consumer v0.103.0 go.opentelemetry.io/collector/otelcol v0.103.0 go.opentelemetry.io/collector/pdata v1.10.0 @@ -15,8 +18,6 @@ require ( go.uber.org/goleak v1.3.0 ) -require github.com/shirou/gopsutil/v4 v4.24.5 // indirect - require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect @@ -37,14 +38,12 @@ require ( github.com/knadh/koanf/providers/confmap v0.1.0 // indirect github.com/knadh/koanf/v2 v2.1.1 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect - github.com/maxmind/MaxMind-DB v0.0.0-20240605211347-880f6b4b5eb6 github.com/maxmind/mmdbwriter v1.0.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.103.0 // indirect - github.com/oschwald/geoip2-golang v1.11.0 github.com/oschwald/maxminddb-golang v1.13.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect @@ -52,6 +51,7 @@ require ( github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.54.0 // indirect github.com/prometheus/procfs v0.15.0 // indirect + github.com/shirou/gopsutil/v4 v4.24.5 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/spf13/cobra v1.8.0 // indirect github.com/spf13/pflag v1.0.5 // indirect @@ -63,7 +63,6 @@ require ( go.opentelemetry.io/collector/config/configtelemetry v0.103.0 // indirect go.opentelemetry.io/collector/confmap/converter/expandconverter v0.103.0 // indirect go.opentelemetry.io/collector/confmap/provider/envprovider v0.103.0 // indirect - go.opentelemetry.io/collector/confmap/provider/fileprovider v0.103.0 go.opentelemetry.io/collector/confmap/provider/httpprovider v0.103.0 // indirect go.opentelemetry.io/collector/confmap/provider/httpsprovider v0.103.0 // indirect go.opentelemetry.io/collector/confmap/provider/yamlprovider v0.103.0 // indirect From bda01e59b28195d0538575e793aec17aa1c11530 Mon Sep 17 00:00:00 2001 From: Roger Coll Date: Fri, 28 Jun 2024 12:56:23 +0200 Subject: [PATCH 20/23] rename providers config key variable --- processor/geoipprocessor/README.md | 22 +++++++++++----------- processor/geoipprocessor/config.go | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/processor/geoipprocessor/README.md b/processor/geoipprocessor/README.md index 10356b89c939..1e04e8f7ed4b 100644 --- a/processor/geoipprocessor/README.md +++ b/processor/geoipprocessor/README.md @@ -20,17 +20,17 @@ The geoIP processor `geoipprocessor` enhances resource attributes by appending i The following [resource attributes](./internal/convention/attributes.go) will be added if the corresponding information is found: ``` - * geo.city_name - * geo.postal_code - * geo.country_name - * geo.country_iso_code - * geo.continent_name - * geo.continent_code - * geo.region_name - * geo.region_iso_code - * geo.timezone - * geo.location.lat - * geo.location.lon + * geo.city_name + * geo.postal_code + * geo.country_name + * geo.country_iso_code + * geo.continent_name + * geo.continent_code + * geo.region_name + * geo.region_iso_code + * geo.timezone + * geo.location.lat + * geo.location.lon ``` ## Configuration diff --git a/processor/geoipprocessor/config.go b/processor/geoipprocessor/config.go index 685052623d68..c45ec2961c17 100644 --- a/processor/geoipprocessor/config.go +++ b/processor/geoipprocessor/config.go @@ -14,7 +14,7 @@ import ( ) const ( - providerKey = "providers" + providersKey = "providers" ) // Config holds the configuration for the GeoIP processor. @@ -58,7 +58,7 @@ func (cfg *Config) Unmarshal(componentParser *confmap.Conf) error { cfg.Providers = map[string]provider.Config{} // retrieve `providers` configuration section - providersSection, err := componentParser.Sub(providerKey) + providersSection, err := componentParser.Sub(providersKey) if err != nil { return err } From cd5293dcf019db98560f2d16afcaf1f59d36f67d Mon Sep 17 00:00:00 2001 From: Roger Coll Date: Tue, 2 Jul 2024 10:41:50 +0200 Subject: [PATCH 21/23] Update processor/geoipprocessor/README.md Co-authored-by: Andrzej Stencel --- processor/geoipprocessor/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/processor/geoipprocessor/README.md b/processor/geoipprocessor/README.md index 1e04e8f7ed4b..c0562f8fe29a 100644 --- a/processor/geoipprocessor/README.md +++ b/processor/geoipprocessor/README.md @@ -40,7 +40,7 @@ The following settings must be configured: - `providers`: A map containing geographical location information providers. These providers are used to search for the geographical location attributes associated with an IP. Supported providers: - [maxmind](./internal/provider/maxmindprovider/README.md) -#### Examples +## Examples ```yaml processors: From bb6ba71b8edaa2c90a83f0ff222a657fff9b85ff Mon Sep 17 00:00:00 2001 From: Roger Coll Date: Tue, 2 Jul 2024 11:52:31 +0200 Subject: [PATCH 22/23] chore: remove deprecated test helpers --- processor/geoipprocessor/config_test.go | 43 +++---------------------- 1 file changed, 4 insertions(+), 39 deletions(-) diff --git a/processor/geoipprocessor/config_test.go b/processor/geoipprocessor/config_test.go index a1e6400cbc02..0440177cc08a 100644 --- a/processor/geoipprocessor/config_test.go +++ b/processor/geoipprocessor/config_test.go @@ -11,10 +11,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/component" - "go.opentelemetry.io/collector/confmap" "go.opentelemetry.io/collector/confmap/confmaptest" - "go.opentelemetry.io/collector/confmap/provider/fileprovider" - "go.opentelemetry.io/collector/otelcol" "go.opentelemetry.io/collector/otelcol/otelcoltest" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/geoipprocessor/internal/metadata" @@ -83,15 +80,7 @@ func TestLoadConfig_InvalidProviderKey(t *testing.T) { factory := NewFactory() factories.Processors[metadata.Type] = factory - _, err = otelcoltest.LoadConfigAndValidateWithSettings(factories, otelcol.ConfigProviderSettings{ - ResolverSettings: confmap.ResolverSettings{ - URIs: []string{filepath.Join("testdata", "config-invalidProviderKey.yaml")}, - ProviderFactories: []confmap.ProviderFactory{ - fileprovider.NewFactory(), - }, - }, - }, - ) + _, err = otelcoltest.LoadConfigAndValidate(filepath.Join("testdata", "config-invalidProviderKey.yaml"), factories) require.Contains(t, err.Error(), "error reading configuration for \"geoip\": invalid provider key: invalidProviderKey") } @@ -111,15 +100,7 @@ func TestLoadConfig_ValidProviderKey(t *testing.T) { factory := NewFactory() factories.Processors[metadata.Type] = factory - collectorConfig, err := otelcoltest.LoadConfigAndValidateWithSettings(factories, otelcol.ConfigProviderSettings{ - ResolverSettings: confmap.ResolverSettings{ - URIs: []string{filepath.Join("testdata", "config-mockProvider.yaml")}, - ProviderFactories: []confmap.ProviderFactory{ - fileprovider.NewFactory(), - }, - }, - }, - ) + collectorConfig, err := otelcoltest.LoadConfigAndValidate(filepath.Join("testdata", "config-mockProvider.yaml"), factories) require.NoError(t, err) actualDbMockConfig := collectorConfig.Processors[component.NewID(metadata.Type)].(*Config).Providers["mock"].(*dbMockConfig) @@ -132,15 +113,7 @@ func TestLoadConfig_ValidProviderKey(t *testing.T) { providerFactories["mock"] = &baseMockFactory factories.Processors[metadata.Type] = factory - _, err = otelcoltest.LoadConfigAndValidateWithSettings(factories, otelcol.ConfigProviderSettings{ - ResolverSettings: confmap.ResolverSettings{ - URIs: []string{filepath.Join("testdata", "config-mockProvider.yaml")}, - ProviderFactories: []confmap.ProviderFactory{ - fileprovider.NewFactory(), - }, - }, - }, - ) + _, err = otelcoltest.LoadConfigAndValidate(filepath.Join("testdata", "config-mockProvider.yaml"), factories) require.ErrorContains(t, err, "has invalid keys: database") } @@ -163,15 +136,7 @@ func TestLoadConfig_ProviderValidateError(t *testing.T) { factory := NewFactory() factories.Processors[metadata.Type] = factory - _, err = otelcoltest.LoadConfigAndValidateWithSettings(factories, otelcol.ConfigProviderSettings{ - ResolverSettings: confmap.ResolverSettings{ - URIs: []string{filepath.Join("testdata", "config-mockProvider.yaml")}, - ProviderFactories: []confmap.ProviderFactory{ - fileprovider.NewFactory(), - }, - }, - }, - ) + _, err = otelcoltest.LoadConfigAndValidate(filepath.Join("testdata", "config-mockProvider.yaml"), factories) require.Contains(t, err.Error(), "error validating provider mock") } From e3923791f8f9d0457a263b65d2b60554ae126e2d Mon Sep 17 00:00:00 2001 From: Roger Coll Date: Tue, 2 Jul 2024 12:08:13 +0200 Subject: [PATCH 23/23] chore: tidy indirect deps --- processor/geoipprocessor/go.mod | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/processor/geoipprocessor/go.mod b/processor/geoipprocessor/go.mod index 722bfa38b7ff..dd2475feef87 100644 --- a/processor/geoipprocessor/go.mod +++ b/processor/geoipprocessor/go.mod @@ -9,9 +9,7 @@ require ( github.com/stretchr/testify v1.9.0 go.opentelemetry.io/collector/component v0.104.0 go.opentelemetry.io/collector/confmap v0.104.0 - go.opentelemetry.io/collector/confmap/provider/fileprovider v0.104.0 go.opentelemetry.io/collector/consumer v0.104.0 - go.opentelemetry.io/collector/otelcol v0.104.0 go.opentelemetry.io/collector/otelcol/otelcoltest v0.104.0 go.opentelemetry.io/collector/pdata v1.11.0 go.opentelemetry.io/collector/processor v0.104.0 @@ -66,12 +64,14 @@ require ( go.opentelemetry.io/collector/config/configtelemetry v0.104.0 // indirect go.opentelemetry.io/collector/confmap/converter/expandconverter v0.104.0 // indirect go.opentelemetry.io/collector/confmap/provider/envprovider v0.104.0 // indirect + go.opentelemetry.io/collector/confmap/provider/fileprovider v0.104.0 // indirect go.opentelemetry.io/collector/confmap/provider/httpprovider v0.104.0 // indirect go.opentelemetry.io/collector/confmap/provider/yamlprovider v0.104.0 // indirect go.opentelemetry.io/collector/connector v0.104.0 // indirect go.opentelemetry.io/collector/exporter v0.104.0 // indirect go.opentelemetry.io/collector/extension v0.104.0 // indirect go.opentelemetry.io/collector/featuregate v1.11.0 // indirect + go.opentelemetry.io/collector/otelcol v0.104.0 // indirect go.opentelemetry.io/collector/pdata/testdata v0.104.0 // indirect go.opentelemetry.io/collector/receiver v0.104.0 // indirect go.opentelemetry.io/collector/semconv v0.104.0 // indirect