Skip to content

Commit

Permalink
[exporter/datadog] Add ECS Fargate source provider (#11030)
Browse files Browse the repository at this point in the history
* [exporter/datadog] Add ECS Fargate hostname provider

* Fix linter issues

* More linter fixes

* [exporter/datadog] Fix `errors.As` check

The correct way is to build the zero value of an error and pass its pointer

* [exporter/datadog] Address changes
  • Loading branch information
mx-psi authored Jun 21, 2022
1 parent 24fbed7 commit 9aec3dc
Show file tree
Hide file tree
Showing 33 changed files with 602 additions and 296 deletions.
18 changes: 9 additions & 9 deletions exporter/datadogexporter/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import (

ddconfig "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/datadogexporter/config"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/datadogexporter/internal/metadata"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/datadogexporter/internal/metadata/provider"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/datadogexporter/internal/model/source"
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/resourcetotelemetry"
)

Expand All @@ -45,18 +45,18 @@ const (
type factory struct {
onceMetadata sync.Once

onceProvider sync.Once
hostProvider provider.HostnameProvider
providerErr error
onceProvider sync.Once
sourceProvider source.Provider
providerErr error

registry *featuregate.Registry
}

func (f *factory) HostnameProvider(set component.TelemetrySettings, configHostname string) (provider.HostnameProvider, error) {
func (f *factory) SourceProvider(set component.TelemetrySettings, configHostname string) (source.Provider, error) {
f.onceProvider.Do(func() {
f.hostProvider, f.providerErr = metadata.GetHostnameProvider(set, configHostname)
f.sourceProvider, f.providerErr = metadata.GetSourceProvider(set, configHostname)
})
return f.hostProvider, f.providerErr
return f.sourceProvider, f.providerErr
}

func newFactoryWithRegistry(registry *featuregate.Registry) component.ExporterFactory {
Expand Down Expand Up @@ -180,7 +180,7 @@ func (f *factory) createMetricsExporter(
return nil, err
}

hostProvider, err := f.HostnameProvider(set.TelemetrySettings, cfg.Hostname)
hostProvider, err := f.SourceProvider(set.TelemetrySettings, cfg.Hostname)
if err != nil {
return nil, fmt.Errorf("failed to build hostname provider: %w", err)
}
Expand Down Expand Up @@ -244,7 +244,7 @@ func (f *factory) createTracesExporter(
return nil, err
}

hostProvider, err := f.HostnameProvider(set.TelemetrySettings, cfg.Hostname)
hostProvider, err := f.SourceProvider(set.TelemetrySettings, cfg.Hostname)
if err != nil {
return nil, fmt.Errorf("failed to build hostname provider: %w", err)
}
Expand Down
12 changes: 12 additions & 0 deletions exporter/datadogexporter/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
github.com/aws/aws-sdk-go v1.44.38
github.com/cenkalti/backoff/v4 v4.1.3
github.com/gogo/protobuf v1.3.2
github.com/open-telemetry/opentelemetry-collector-contrib/internal/aws/ecsutil v0.53.0
github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.53.0
github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8sconfig v0.53.0
github.com/open-telemetry/opentelemetry-collector-contrib/internal/metadataproviders v0.53.0
Expand Down Expand Up @@ -48,19 +49,23 @@ require (
github.com/docker/go-units v0.4.0 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/emicklei/go-restful v2.9.5+incompatible // indirect
github.com/felixge/httpsnoop v1.0.2 // indirect
github.com/go-logr/logr v1.2.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.19.5 // indirect
github.com/go-openapi/swag v0.19.14 // indirect
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/gnostic v0.5.7-v3refs // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/imdario/mergo v0.3.11 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.15.6 // indirect
github.com/knadh/koanf v1.4.1 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
Expand All @@ -69,20 +74,23 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.53.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.2 // indirect
github.com/openshift/api v0.0.0-20210521075222-e273a339932a // indirect
github.com/openshift/client-go v0.0.0-20210521082421-73d9475a9142 // indirect
github.com/philhofer/fwd v1.1.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rs/cors v1.8.2 // indirect
github.com/shirou/gopsutil v2.20.9+incompatible // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/objx v0.4.0 // indirect
github.com/tinylib/msgp v1.1.2 // indirect
github.com/zorkian/go-datadog-api v2.30.0+incompatible // indirect
go.opencensus.io v0.23.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0 // indirect
go.opentelemetry.io/otel v1.7.0 // indirect
go.opentelemetry.io/otel/metric v0.30.0 // indirect
go.opentelemetry.io/otel/trace v1.7.0 // indirect
Expand Down Expand Up @@ -117,6 +125,10 @@ replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/metad

replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/resourcetotelemetry => ../../pkg/resourcetotelemetry

replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/aws/ecsutil => ../../internal/aws/ecsutil

replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/common => ../../internal/common

// see https://github.com/go-chi/chi/issues/713
// see https://github.com/DataDog/dd-trace-go/issues/1220
replace github.com/go-chi/chi/v4 => github.com/go-chi/chi v4.0.0+incompatible
12 changes: 11 additions & 1 deletion exporter/datadogexporter/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 36 additions & 22 deletions exporter/datadogexporter/internal/metadata/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ import (
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/datadogexporter/internal/metadata/internal/azure"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/datadogexporter/internal/metadata/internal/docker"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/datadogexporter/internal/metadata/internal/ec2"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/datadogexporter/internal/metadata/internal/ecs"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/datadogexporter/internal/metadata/internal/gcp"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/datadogexporter/internal/metadata/internal/k8s"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/datadogexporter/internal/metadata/internal/system"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/datadogexporter/internal/metadata/provider"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/datadogexporter/internal/metadata/valid"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/datadogexporter/internal/model/source"
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/datadogexporter/internal/utils/cache"
)

Expand All @@ -48,12 +50,17 @@ func init() {
})
}

func buildPreviewProvider(set component.TelemetrySettings, configHostname string) (provider.HostnameProvider, error) {
func buildPreviewProvider(set component.TelemetrySettings, configHostname string) (source.Provider, error) {
dockerProvider, err := docker.NewProvider()
if err != nil {
return nil, err
}

ecs, err := ecs.NewProvider(set)
if err != nil {
return nil, fmt.Errorf("failed to build ECS Fargate provider: %w", err)
}

azureProvider := azure.NewProvider()
ec2Provider, err := ec2.NewProvider(set.Logger)
if err != nil {
Expand All @@ -80,16 +87,17 @@ func buildPreviewProvider(set component.TelemetrySettings, configHostname string

chain, err := provider.Chain(
set.Logger,
map[string]provider.HostnameProvider{
map[string]source.Provider{
"config": provider.Config(configHostname),
"azure": azureProvider,
"ecs": ecs,
"ec2": ec2Provider,
"gcp": gcpProvider,
"kubernetes": k8sProvider,
"docker": dockerProvider,
"system": system.NewProvider(set.Logger),
},
[]string{"config", "azure", "ec2", "gcp", "kubernetes", "docker", "system"},
[]string{"config", "azure", "ecs", "ec2", "gcp", "kubernetes", "docker", "system"},
)

if err != nil {
Expand All @@ -99,7 +107,7 @@ func buildPreviewProvider(set component.TelemetrySettings, configHostname string
return provider.Once(chain), nil
}

func buildCurrentProvider(set component.TelemetrySettings, configHostname string) (provider.HostnameProvider, error) {
func buildCurrentProvider(set component.TelemetrySettings, configHostname string) (source.Provider, error) {
ec2Provider, err := ec2.NewProvider(set.Logger)
if err != nil {
return nil, fmt.Errorf("failed to build EC2 provider: %w", err)
Expand All @@ -113,7 +121,7 @@ func buildCurrentProvider(set component.TelemetrySettings, configHostname string
}, nil
}

func GetHostnameProvider(set component.TelemetrySettings, configHostname string) (provider.HostnameProvider, error) {
func GetSourceProvider(set component.TelemetrySettings, configHostname string) (source.Provider, error) {
previewProvider, err := buildPreviewProvider(set, configHostname)
if err != nil {
return nil, err
Expand All @@ -133,7 +141,7 @@ func GetHostnameProvider(set component.TelemetrySettings, configHostname string)
}, nil
}

var _ provider.HostnameProvider = (*currentProvider)(nil)
var _ source.Provider = (*currentProvider)(nil)

type currentProvider struct {
logger *zap.Logger
Expand All @@ -148,13 +156,13 @@ type currentProvider struct {
// 2. Cache
// 3. EC2 instance metadata
// 4. System
func (c *currentProvider) Hostname(ctx context.Context) (string, error) {
func (c *currentProvider) hostname(ctx context.Context) string {
if c.configHostname != "" {
return c.configHostname, nil
return c.configHostname
}

if cacheVal, ok := cache.Cache.Get(cache.CanonicalHostnameKey); ok {
return cacheVal.(string), nil
return cacheVal.(string)
}

ec2Info := c.ec2Provider.HostInfo()
Expand All @@ -163,9 +171,11 @@ func (c *currentProvider) Hostname(ctx context.Context) (string, error) {
if hostname == "" {
// Get system hostname
var err error
hostname, err = c.systemProvider.Hostname(ctx)
src, err := c.systemProvider.Source(ctx)
if err != nil {
c.logger.Debug("system provider is unavailable", zap.Error(err))
} else {
hostname = src.Identifier
}
}

Expand All @@ -176,39 +186,43 @@ func (c *currentProvider) Hostname(ctx context.Context) (string, error) {

c.logger.Debug("Canonical hostname automatically set", zap.String("hostname", hostname))
cache.Cache.Set(cache.CanonicalHostnameKey, hostname, cache.NoExpiration)
return hostname, nil
return hostname
}

func (c *currentProvider) Source(ctx context.Context) (source.Source, error) {
return source.Source{Kind: source.HostnameKind, Identifier: c.hostname(ctx)}, nil
}

var _ provider.HostnameProvider = (*warnProvider)(nil)
var _ source.Provider = (*warnProvider)(nil)

type warnProvider struct {
onceDefaultChanged sync.Once
oncePreviewHostnameFailed sync.Once

logger *zap.Logger
curProvider provider.HostnameProvider
previewProvider provider.HostnameProvider
curProvider source.Provider
previewProvider source.Provider
}

func (p *warnProvider) Hostname(ctx context.Context) (string, error) {
curHostname, err := p.curProvider.Hostname(ctx)
func (p *warnProvider) Source(ctx context.Context) (source.Source, error) {
curSrc, err := p.curProvider.Source(ctx)
if err != nil {
return "", err
return source.Source{}, err
}

previewHostname, err := p.previewProvider.Hostname(ctx)
previewSrc, err := p.previewProvider.Source(ctx)
if err != nil {
p.oncePreviewHostnameFailed.Do(func() {
p.logger.Warn(previewHostnameFailedLogMessage, zap.Error(err))
})
} else if curHostname != previewHostname {
} else if curSrc != previewSrc {
p.onceDefaultChanged.Do(func() {
p.logger.Warn(defaultHostnameChangeLogMessage,
zap.String("current default hostname", curHostname),
zap.String("future default hostname", previewHostname),
zap.Any("current default source", curSrc),
zap.Any("future default source", previewSrc),
)
})
}

return curHostname, nil
return curSrc, nil
}
Loading

0 comments on commit 9aec3dc

Please sign in to comment.