Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[exporter/datadog] Add ECS Fargate source provider #11030

Merged
merged 7 commits into from
Jun 21, 2022
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions exporter/datadogexporter/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,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 @@ -44,16 +44,16 @@ const (
type factory struct {
onceMetadata sync.Once

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

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
}

// NewFactory creates a Datadog exporter factory
Expand Down Expand Up @@ -168,7 +168,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 @@ -232,7 +232,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.33
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.2.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.

36 changes: 25 additions & 11 deletions exporter/datadogexporter/internal/metadata/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,30 @@ 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"
)

// UsePreviewHostnameLogic decides whether to use the preview hostname logic or not.
const UsePreviewHostnameLogic = false

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 @@ -67,16 +74,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 @@ -86,7 +94,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 @@ -100,15 +108,15 @@ 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) {
if UsePreviewHostnameLogic {
return buildPreviewProvider(set, configHostname)
}

return buildCurrentProvider(set, configHostname)
}

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

type currentProvider struct {
logger *zap.Logger
Expand All @@ -123,13 +131,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 @@ -138,9 +146,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 @@ -151,5 +161,9 @@ 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
}
12 changes: 6 additions & 6 deletions exporter/datadogexporter/internal/metadata/host_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,26 +33,26 @@ func TestHost(t *testing.T) {

p, err := buildCurrentProvider(componenttest.NewNopTelemetrySettings(), "test-host")
require.NoError(t, err)
host, err := p.Hostname(context.Background())
src, err := p.Source(context.Background())
require.NoError(t, err)
assert.Equal(t, host, "test-host")
assert.Equal(t, src.Identifier, "test-host")

// config.Config.Hostname does not get stored in the cache
p, err = buildCurrentProvider(componenttest.NewNopTelemetrySettings(), "test-host-2")
require.NoError(t, err)
host, err = p.Hostname(context.Background())
src, err = p.Source(context.Background())
require.NoError(t, err)
assert.Equal(t, host, "test-host-2")
assert.Equal(t, src.Identifier, "test-host-2")

// Disable EC2 Metadata service to prevent fetching hostname from there,
// in case the test is running on an EC2 instance
t.Setenv("AWS_EC2_METADATA_DISABLED", "true")

p, err = buildCurrentProvider(componenttest.NewNopTelemetrySettings(), "")
require.NoError(t, err)
host, err = p.Hostname(context.Background())
src, err = p.Source(context.Background())
require.NoError(t, err)
osHostname, err := os.Hostname()
require.NoError(t, err)
assert.Contains(t, host, osHostname)
assert.Contains(t, src.Identifier, osHostname)
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,26 @@ import (
"strings"

"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/internal/metadataproviders/azure"
)

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

type Provider struct {
detector azure.Provider
}

// Hostname returns the Azure cloud integration hostname.
func (p *Provider) Hostname(ctx context.Context) (string, error) {
func (p *Provider) Source(ctx context.Context) (source.Source, error) {
metadata, err := p.detector.Metadata(ctx)
if err != nil {
return "", err
return source.Source{}, err
}

return metadata.VMID, nil
return source.Source{Kind: source.HostnameKind, Identifier: metadata.VMID}, nil
}

// ClusterName gets the AKS cluster name from the resource group name.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"context"
"testing"

"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/datadogexporter/internal/model/source"
"github.com/open-telemetry/opentelemetry-collector-contrib/internal/metadataproviders/azure"

"github.com/stretchr/testify/assert"
Expand All @@ -37,9 +38,10 @@ func TestProvider(t *testing.T) {
}, nil)

provider := &Provider{detector: mp}
hostname, err := provider.Hostname(context.Background())
src, err := provider.Source(context.Background())
require.NoError(t, err)
assert.Equal(t, "vmID", hostname)
assert.Equal(t, source.HostnameKind, src.Kind)
assert.Equal(t, "vmID", src.Identifier)

clusterName, err := provider.ClusterName(context.Background())
require.NoError(t, err)
Expand Down
Loading