From 6d4a5770bc9d15bbe5a3fe9424b78894b2f0338d Mon Sep 17 00:00:00 2001 From: Pablo Baeyens Date: Tue, 29 Mar 2022 15:54:11 -0400 Subject: [PATCH 1/4] [exporter/datadog] Add `host_metadata` section --- exporter/datadogexporter/README.md | 4 +- exporter/datadogexporter/config/config.go | 72 +++++++++++++++++-- .../datadogexporter/config/config_test.go | 48 ++++++++++--- .../datadogexporter/config/warn_envvars.go | 4 ++ .../config/warning_deprecated.go | 31 ++++++++ exporter/datadogexporter/example/config.yaml | 52 +++++++++++++- exporter/datadogexporter/factory.go | 5 ++ exporter/datadogexporter/factory_test.go | 46 +++++++++--- exporter/datadogexporter/hostmetadata.go | 14 ++-- exporter/datadogexporter/hostmetadata_test.go | 62 +++++++++------- exporter/datadogexporter/metrics_exporter.go | 2 +- .../datadogexporter/metrics_exporter_test.go | 4 +- exporter/datadogexporter/testdata/config.yaml | 15 +++- exporter/datadogexporter/traces_exporter.go | 2 +- .../datadogexporter/traces_exporter_test.go | 7 +- 15 files changed, 302 insertions(+), 66 deletions(-) diff --git a/exporter/datadogexporter/README.md b/exporter/datadogexporter/README.md index efc5a2a5e780..22a3e9107dcb 100644 --- a/exporter/datadogexporter/README.md +++ b/exporter/datadogexporter/README.md @@ -70,8 +70,8 @@ exporters: hostname: customhostname env: prod - tags: - - example:tag + host_metadata: + tags: [example:tag] api: key: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/exporter/datadogexporter/config/config.go b/exporter/datadogexporter/config/config.go index 54da9b35c6ef..8e95fc3d5f7d 100644 --- a/exporter/datadogexporter/config/config.go +++ b/exporter/datadogexporter/config/config.go @@ -31,7 +31,7 @@ import ( var ( errUnsetAPIKey = errors.New("api.key is not set") - errNoMetadata = errors.New("only_metadata can't be enabled when send_metadata or use_resource_metadata is disabled") + errNoMetadata = errors.New("only_metadata can't be enabled when host_metadata::enabled = false or hostname_source != first_resource") ) // TODO: Import these from translator when we eliminate cyclic dependency. @@ -226,10 +226,11 @@ type TagsConfig struct { // Superseded by Tags if the latter is set. // Should not be set in the user-provided config. // - // Deprecated: [v0.47.0] Use Tags instead. + // Deprecated: [v0.47.0] Use `host_metadata::tags` HostMetadataConfig.Tags instead. EnvVarTags string `mapstructure:"envvartags"` // Tags is the list of default tags to add to every metric or trace. + // Deprecated: [v0.49.0] Use `host_metadata::tags` (HostMetadataConfig.Tags) Tags []string `mapstructure:"tags"` } @@ -248,6 +249,64 @@ func (t *TagsConfig) GetHostTags() []string { return tags } +// HostnameSource is the source for the hostname of host metadata. +type HostnameSource string + +const ( + // HostnameSourceFirstResource picks the host metadata hostname from the resource + // attributes on the first OTLP payload that gets to the exporter. If it is lacking any + // hostname-like attributes, it will fallback to system data (see below). + // + // Do not use this hostname source if receiving data from multiple hosts. + HostnameSourceFirstResource HostnameSource = "first_resource" + + // HostnameSourceConfigOrSystem picks the host metadata hostname from the 'hostname' setting, + // and if this is empty, from available system APIs and cloud provider endpoints. + HostnameSourceConfigOrSystem HostnameSource = "config_or_system" +) + +var _ encoding.TextUnmarshaler = (*HostnameSource)(nil) + +// UnmarshalText implements the encoding.TextUnmarshaler interface. +func (sm *HostnameSource) UnmarshalText(in []byte) error { + switch mode := HostnameSource(in); mode { + case HostnameSourceFirstResource, + HostnameSourceConfigOrSystem: + *sm = mode + return nil + default: + return fmt.Errorf("invalid host metadata hostname source %q", mode) + } +} + +// HostMetadataConfig defines the host metadata related configuration. +// Host metadata is the information used for populating the infrastructure list, +// the host map and providing host tags functionality. +// +// The exporter will send host metadata for a single host, whose name is chosen +// according to `host_metadata::hostname_source`. +type HostMetadataConfig struct { + // Enabled enables the host metadata functionality. + Enabled bool `mapstructure:"enabled"` + + // HostnameSource is the source for the hostname of host metadata. + // Valid values are 'first_resource' and 'config_or_system': + // - 'first_resource' picks the host metadata hostname from the resource + // attributes on the first OTLP payload that gets to the exporter. + // If the first payload lacks hostname-like attributes, it will fallback to 'config_or_system'. + // Do not use this hostname source if receiving data from multiple hosts. + // - 'config_or_system' picks the host metadata hostname from the 'hostname' setting, + // If this is empty it will use available system APIs and cloud provider endpoints. + // + // The current default if 'first_resource'. + HostnameSource HostnameSource `mapstructure:"hostname_source"` + + // Tags is a list of host tags. + // These tags will be attached to telemetry signals that have the host metadata hostname. + // To attach tags to telemetry signals regardless of the host, use a processor instead. + Tags []string `mapstructure:"tags"` +} + // LimitedTLSClientSetting is a subset of TLSClientSetting, see LimitedHTTPClientSettings for more details type LimitedTLSClientSettings struct { // InsecureSkipVerify controls whether a client verifies the server's @@ -279,10 +338,14 @@ type Config struct { // Traces defines the Traces exporter specific configuration Traces TracesConfig `mapstructure:"traces"` + // HostMetadata defines the host metadata specific configuration + HostMetadata HostMetadataConfig `mapstructure:"host_metadata"` + // SendMetadata defines whether to send host metadata // This is undocumented and only used for unit testing. // // This can't be disabled if `only_metadata` is true. + // Deprecated: [v0.49.0] Use `host_metadata::enabled` (HostMetadata.Enabled) instead. SendMetadata bool `mapstructure:"send_metadata"` // OnlyMetadata defines whether to only send metadata @@ -290,7 +353,7 @@ type Config struct { // metadata about a host is sent to the backend even // when telemetry data is reported via a different host. // - // This flag is incompatible with disabling `send_metadata` + // This flag is incompatible with disabling host metadata // or `use_resource_metadata`. OnlyMetadata bool `mapstructure:"only_metadata"` @@ -300,6 +363,7 @@ type Config struct { // By default this is true: the first resource attribute getting to // the exporter will be used for host metadata. // Disable this in the Collector if you are using an agent-collector setup. + // Deprecated: [v0.49.0] Use `host_metadata::hostname_source` (HostMetadata.HostnameSource) instead. UseResourceMetadata bool `mapstructure:"use_resource_metadata"` // warnings stores non-fatal configuration errors. @@ -312,7 +376,7 @@ func (c *Config) Sanitize(logger *zap.Logger) error { c.TagsConfig.Env = "none" } - if c.OnlyMetadata && (!c.SendMetadata || !c.UseResourceMetadata) { + if c.OnlyMetadata && (!c.HostMetadata.Enabled || c.HostMetadata.HostnameSource != HostnameSourceFirstResource) { return errNoMetadata } diff --git a/exporter/datadogexporter/config/config_test.go b/exporter/datadogexporter/config/config_test.go index f68891f069a2..66e70d7a2228 100644 --- a/exporter/datadogexporter/config/config_test.go +++ b/exporter/datadogexporter/config/config_test.go @@ -180,16 +180,44 @@ func TestSpanNameRemappingsValidation(t *testing.T) { require.Error(t, err) } -func TestInvalidSumMode(t *testing.T) { - cfgMap := config.NewMapFromStringMap(map[string]interface{}{ - "metrics": map[string]interface{}{ - "sums": map[string]interface{}{ - "cumulative_monotonic_mode": "invalid_mode", - }, +func TestUnmarshal(t *testing.T) { + tests := []struct { + name string + configMap *config.Map + cfg Config + err string + }{ + { + name: "invalid cumulative monotonic mode", + configMap: config.NewMapFromStringMap(map[string]interface{}{ + "metrics": map[string]interface{}{ + "sums": map[string]interface{}{ + "cumulative_monotonic_mode": "invalid_mode", + }, + }, + }), + err: "1 error(s) decoding:\n\n* error decoding 'metrics.sums.cumulative_monotonic_mode': invalid cumulative monotonic sum mode \"invalid_mode\"", + }, + { + name: "invalid host metadata hostname source", + configMap: config.NewMapFromStringMap(map[string]interface{}{ + "host_metadata": map[string]interface{}{ + "hostname_source": "invalid_source", + }, + }), + err: "1 error(s) decoding:\n\n* error decoding 'host_metadata.hostname_source': invalid host metadata hostname source \"invalid_source\"", }, - }) + } - cfg := futureDefaultConfig() - err := cfg.Unmarshal(cfgMap) - assert.EqualError(t, err, "1 error(s) decoding:\n\n* error decoding 'metrics.sums.cumulative_monotonic_mode': invalid cumulative monotonic sum mode \"invalid_mode\"") + for _, testInstance := range tests { + t.Run(testInstance.name, func(t *testing.T) { + cfg := futureDefaultConfig() + err := cfg.Unmarshal(testInstance.configMap) + if err != nil || testInstance.err != "" { + assert.EqualError(t, err, testInstance.err) + } else { + assert.Equal(t, testInstance.cfg, cfg) + } + }) + } } diff --git a/exporter/datadogexporter/config/warn_envvars.go b/exporter/datadogexporter/config/warn_envvars.go index e7a786270a37..9e2176809a59 100644 --- a/exporter/datadogexporter/config/warn_envvars.go +++ b/exporter/datadogexporter/config/warn_envvars.go @@ -51,6 +51,10 @@ func futureDefaultConfig() *Config { SampleRate: 1, IgnoreResources: []string{}, }, + HostMetadata: HostMetadataConfig{ + Enabled: true, + HostnameSource: HostnameSourceFirstResource, + }, SendMetadata: true, UseResourceMetadata: true, } diff --git a/exporter/datadogexporter/config/warning_deprecated.go b/exporter/datadogexporter/config/warning_deprecated.go index 91d9a9c536ce..d4b732e29e05 100644 --- a/exporter/datadogexporter/config/warning_deprecated.go +++ b/exporter/datadogexporter/config/warning_deprecated.go @@ -53,6 +53,37 @@ var renamedSettings = []renameError{ } }, }, + { + oldName: "tags", + newName: "host_metadata::tags", + oldRemovedIn: "v0.52.0", + issueNumber: 9099, + updateFn: func(c *Config) { + c.HostMetadata.Tags = c.Tags + }, + }, + { + oldName: "send_metadata", + newName: "host_metadata::enabled", + oldRemovedIn: "v0.52.0", + issueNumber: 9099, + updateFn: func(c *Config) { + c.HostMetadata.Enabled = c.SendMetadata + }, + }, + { + oldName: "use_resource_metadata", + newName: "host_metadata::hostname_source", + oldRemovedIn: "v0.52.0", + issueNumber: 9099, + updateFn: func(c *Config) { + if c.UseResourceMetadata { + c.HostMetadata.HostnameSource = HostnameSourceFirstResource + } else { + c.HostMetadata.HostnameSource = HostnameSourceConfigOrSystem + } + }, + }, } // Error implements the error interface. diff --git a/exporter/datadogexporter/example/config.yaml b/exporter/datadogexporter/example/config.yaml index cf04b5ee25e2..e2812cff94ae 100644 --- a/exporter/datadogexporter/example/config.yaml +++ b/exporter/datadogexporter/example/config.yaml @@ -36,16 +36,32 @@ exporters: # version: myversion ## @param tags - list of strings - optional - default: [] - ## The list of default tags to add to every metric or trace. + ## The list of tags to send as host tags. + ## Deprecated: [v0.49.0] Use `host_metadata::tags` instead. + ## This option will be removed in v0.52.0. ## If unset it will be determined from the `DD_TAGS` environment variable, specified ## as a list of space-separated strings (Deprecated: [v0.47.0] use 'env' config source instead). # # tags: [] + ## @params send_metadata - boolean - optional - default: true + ## Deprecated: [v0.49.0] Use `host_metadata::enabled` instead. + ## This option will be removed in v0.52.0. + # + # send_metadata: true + + ## @params use_resource_metadata - boolean - optional - default: true + ## Deprecated: [v0.49.0] Use `host_metadata::hostname_source` instead. + ## This option will be removed in v0.52.0. + # + # use_resource_metadata: true + ## @param only_metadata - boolean - optional - default: false ## Whether to send only metadata. This is useful for agent-collector ## setups, so that metadata about a host is sent to the backend even ## when telemetry data is reported via a different host. + # + # only_metadata: false ## @param api - custom object - required. ## Specific API configuration. @@ -175,6 +191,40 @@ exporters: ## https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/1909 # # span_name_as_resource_name: true + + ## @param host_metadata - custom object - optional + ## Host metadata specific configuration. + ## Host metadata is the information used for populating the infrastructure list, the host map and providing host tags functionality. + ## + ## The exporter will send host metadata for a single host, whose name is chosen + ## according to `host_metadata::hostname_source`. + # + # host_metadata: + ## @param enabled - boolean - optional - default: true + ## Enable the host metadata functionality + # + # enabled: true + + ## @param hostname_source - enum - optional - default: first_resource + ## Source for the hostname of host metadata. + ## Valid values are 'first_resource' and 'config_or_system': + ## - 'first_resource' picks the host metadata hostname from the resource attributes on the first OTLP payload that gets to the exporter. + ## If the first payload lacks hostname-like attributes, it will fallback to 'config_or_system' behavior. + ## Do not use this hostname source if receiving data from multiple hosts. + ## + ## - 'config_or_system' picks the host metadata hostname from the 'hostname' setting, falling back to system and cloud provider APIs. + ## + ## The current default if 'first_resource'. + # + # hostname_source: first_resource + + ## @param tags - list of strings - optional - default: empty list + ## List of host tags to be sent as part of the host metadata. + ## These tags will be attached to telemetry signals that have the host metadata hostname. + ## + ## To attach tags to telemetry signals regardless of the host, use a processor instead. + # + # tags: [] service: diff --git a/exporter/datadogexporter/factory.go b/exporter/datadogexporter/factory.go index cff6b4afc18f..902c7d5e9f42 100644 --- a/exporter/datadogexporter/factory.go +++ b/exporter/datadogexporter/factory.go @@ -108,6 +108,11 @@ func (*factory) createDefaultConfig() config.Exporter { IgnoreResources: []string{}, }, + HostMetadata: ddconfig.HostMetadataConfig{ + Enabled: true, + HostnameSource: ddconfig.HostnameSourceFirstResource, + }, + SendMetadata: true, UseResourceMetadata: true, } diff --git a/exporter/datadogexporter/factory_test.go b/exporter/datadogexporter/factory_test.go index a59e2743a6e7..3c0ad5f18795 100644 --- a/exporter/datadogexporter/factory_test.go +++ b/exporter/datadogexporter/factory_test.go @@ -106,6 +106,11 @@ func TestCreateDefaultConfig(t *testing.T) { EnvVarTags: "TAGS", }, + HostMetadata: ddconfig.HostMetadataConfig{ + Enabled: true, + HostnameSource: ddconfig.HostnameSourceFirstResource, + }, + SendMetadata: true, OnlyMetadata: false, UseResourceMetadata: true, @@ -218,6 +223,12 @@ func TestLoadConfig(t *testing.T) { }, IgnoreResources: []string{}, }, + + HostMetadata: ddconfig.HostMetadataConfig{ + Enabled: true, + HostnameSource: ddconfig.HostnameSourceFirstResource, + }, + SendMetadata: true, OnlyMetadata: false, UseResourceMetadata: true, @@ -226,6 +237,16 @@ func TestLoadConfig(t *testing.T) { invalidConfig := cfg.Exporters[config.NewComponentIDWithName(typeStr, "invalid")].(*ddconfig.Config) err = invalidConfig.Sanitize(zap.NewNop()) require.Error(t, err) + + hostMetadataConfig := cfg.Exporters[config.NewComponentIDWithName(typeStr, "hostmetadata")].(*ddconfig.Config) + err = hostMetadataConfig.Sanitize(zap.NewNop()) + require.NoError(t, err) + + assert.Equal(t, ddconfig.HostMetadataConfig{ + Enabled: true, + HostnameSource: ddconfig.HostnameSourceConfigOrSystem, + Tags: []string{"example:one"}, + }, hostMetadataConfig.HostMetadata) } // TestLoadConfigEnvVariables tests that the loading configuration takes into account @@ -272,7 +293,6 @@ func TestLoadConfigEnvVariables(t *testing.T) { Hostname: "customhostname", Env: "prod", EnvVarTags: "envexample:tag envexample2:tag", - Tags: []string{"example:tag"}, }, apiConfig.TagsConfig) assert.Equal(t, ddconfig.APIConfig{ @@ -303,6 +323,12 @@ func TestLoadConfigEnvVariables(t *testing.T) { }, IgnoreResources: []string{}, }, apiConfig.Traces) + assert.Equal(t, + ddconfig.HostMetadataConfig{ + Enabled: true, + HostnameSource: ddconfig.HostnameSourceFirstResource, + Tags: []string{"example:tag"}, + }, apiConfig.HostMetadata) defaultConfig := cfg.Exporters[config.NewComponentIDWithName(typeStr, "default2")].(*ddconfig.Config) err = defaultConfig.Sanitize(zap.NewNop()) @@ -365,7 +391,7 @@ func TestCreateAPIMetricsExporter(t *testing.T) { // Use the mock server for API key validation c := (cfg.Exporters[config.NewComponentIDWithName(typeStr, "api")]).(*ddconfig.Config) c.Metrics.TCPAddr.Endpoint = server.URL - c.SendMetadata = false + c.HostMetadata.Enabled = false ctx := context.Background() exp, err := factory.CreateMetricsExporter( @@ -395,7 +421,7 @@ func TestCreateAPITracesExporter(t *testing.T) { // Use the mock server for API key validation c := (cfg.Exporters[config.NewComponentIDWithName(typeStr, "api")]).(*ddconfig.Config) c.Metrics.TCPAddr.Endpoint = server.URL - c.SendMetadata = false + c.HostMetadata.Enabled = false ctx := context.Background() exp, err := factory.CreateTracesExporter( @@ -425,13 +451,15 @@ func TestOnlyMetadata(t *testing.T) { RetrySettings: exporterhelper.NewDefaultRetrySettings(), QueueSettings: exporterhelper.NewDefaultQueueSettings(), - API: ddconfig.APIConfig{Key: "notnull"}, - Metrics: ddconfig.MetricsConfig{TCPAddr: confignet.TCPAddr{Endpoint: server.URL}}, - Traces: ddconfig.TracesConfig{TCPAddr: confignet.TCPAddr{Endpoint: server.URL}}, + API: ddconfig.APIConfig{Key: "notnull"}, + Metrics: ddconfig.MetricsConfig{TCPAddr: confignet.TCPAddr{Endpoint: server.URL}}, + Traces: ddconfig.TracesConfig{TCPAddr: confignet.TCPAddr{Endpoint: server.URL}}, + OnlyMetadata: true, - SendMetadata: true, - OnlyMetadata: true, - UseResourceMetadata: true, + HostMetadata: ddconfig.HostMetadataConfig{ + Enabled: true, + HostnameSource: ddconfig.HostnameSourceFirstResource, + }, } expTraces, err := factory.CreateTracesExporter( diff --git a/exporter/datadogexporter/hostmetadata.go b/exporter/datadogexporter/hostmetadata.go index 3f4cbbe93d32..cb33aae32ce3 100644 --- a/exporter/datadogexporter/hostmetadata.go +++ b/exporter/datadogexporter/hostmetadata.go @@ -23,16 +23,16 @@ import ( ) // getHostTags gets the host tags extracted from the configuration. -func getHostTags(t *config.TagsConfig) []string { - tags := t.Tags +func getHostTags(c *config.Config) []string { + tags := c.HostMetadata.Tags if len(tags) == 0 { //lint:ignore SA1019 Will be removed when environment variable detection is removed - tags = strings.Split(t.EnvVarTags, " ") //nolint + tags = strings.Split(c.EnvVarTags, " ") //nolint } - if t.Env != "none" { - tags = append(tags, fmt.Sprintf("env:%s", t.Env)) + if c.Env != "none" { + tags = append(tags, fmt.Sprintf("env:%s", c.Env)) } return tags } @@ -41,10 +41,10 @@ func getHostTags(t *config.TagsConfig) []string { func newMetadataConfigfromConfig(cfg *config.Config) metadata.PusherConfig { return metadata.PusherConfig{ ConfigHostname: cfg.Hostname, - ConfigTags: getHostTags(&cfg.TagsConfig), + ConfigTags: getHostTags(cfg), MetricsEndpoint: cfg.Metrics.Endpoint, APIKey: cfg.API.Key, - UseResourceMetadata: cfg.UseResourceMetadata, + UseResourceMetadata: cfg.HostMetadata.HostnameSource == config.HostnameSourceFirstResource, InsecureSkipVerify: cfg.TLSSetting.InsecureSkipVerify, TimeoutSettings: cfg.TimeoutSettings, RetrySettings: cfg.RetrySettings, diff --git a/exporter/datadogexporter/hostmetadata_test.go b/exporter/datadogexporter/hostmetadata_test.go index 7a4620fc7c22..0b34228a4559 100644 --- a/exporter/datadogexporter/hostmetadata_test.go +++ b/exporter/datadogexporter/hostmetadata_test.go @@ -23,13 +23,18 @@ import ( ) func TestHostTags(t *testing.T) { - tc := config.TagsConfig{ - Hostname: "customhost", - Env: "customenv", - // Service and version should be only used for traces - Service: "customservice", - Version: "customversion", - Tags: []string{"key1:val1", "key2:val2"}, + c := config.Config{ + TagsConfig: config.TagsConfig{ + Hostname: "customhost", + Env: "customenv", + // Service and version should be only used for traces + Service: "customservice", + Version: "customversion", + }, + + HostMetadata: config.HostMetadataConfig{ + Tags: []string{"key1:val1", "key2:val2"}, + }, } assert.ElementsMatch(t, @@ -38,17 +43,22 @@ func TestHostTags(t *testing.T) { "key1:val1", "key2:val2", }, - getHostTags(&tc), + getHostTags(&c), ) - tc = config.TagsConfig{ - Hostname: "customhost", - Env: "customenv", - // Service and version should be only used for traces - Service: "customservice", - Version: "customversion", - Tags: []string{"key1:val1", "key2:val2"}, - EnvVarTags: "key3:val3 key4:val4", + c = config.Config{ + TagsConfig: config.TagsConfig{ + Hostname: "customhost", + Env: "customenv", + // Service and version should be only used for traces + Service: "customservice", + Version: "customversion", + EnvVarTags: "key3:val3 key4:val4", + }, + + HostMetadata: config.HostMetadataConfig{ + Tags: []string{"key1:val1", "key2:val2"}, + }, } assert.ElementsMatch(t, @@ -57,16 +67,18 @@ func TestHostTags(t *testing.T) { "key1:val1", "key2:val2", }, - getHostTags(&tc), + getHostTags(&c), ) - tc = config.TagsConfig{ - Hostname: "customhost", - Env: "customenv", - // Service and version should be only used for traces - Service: "customservice", - Version: "customversion", - EnvVarTags: "key3:val3 key4:val4", + c = config.Config{ + TagsConfig: config.TagsConfig{ + Hostname: "customhost", + Env: "customenv", + // Service and version should be only used for traces + Service: "customservice", + Version: "customversion", + EnvVarTags: "key3:val3 key4:val4", + }, } assert.ElementsMatch(t, @@ -75,6 +87,6 @@ func TestHostTags(t *testing.T) { "key3:val3", "key4:val4", }, - getHostTags(&tc), + getHostTags(&c), ) } diff --git a/exporter/datadogexporter/metrics_exporter.go b/exporter/datadogexporter/metrics_exporter.go index 85b6bcb20694..5f04cf522950 100644 --- a/exporter/datadogexporter/metrics_exporter.go +++ b/exporter/datadogexporter/metrics_exporter.go @@ -161,7 +161,7 @@ func (exp *metricsExporter) PushMetricsData(ctx context.Context, md pdata.Metric // Start host metadata with resource attributes from // the first payload. - if exp.cfg.SendMetadata { + if exp.cfg.HostMetadata.Enabled { exp.onceMetadata.Do(func() { attrs := pdata.NewMap() if md.ResourceMetrics().Len() > 0 { diff --git a/exporter/datadogexporter/metrics_exporter_test.go b/exporter/datadogexporter/metrics_exporter_test.go index 5a313ed48daf..c74425c91e69 100644 --- a/exporter/datadogexporter/metrics_exporter_test.go +++ b/exporter/datadogexporter/metrics_exporter_test.go @@ -63,8 +63,8 @@ func TestNewExporter(t *testing.T) { require.NoError(t, err) assert.Equal(t, len(server.MetadataChan), 0) - cfg.SendMetadata = true - cfg.UseResourceMetadata = true + cfg.HostMetadata.Enabled = true + cfg.HostMetadata.HostnameSource = config.HostnameSourceFirstResource err = exp.ConsumeMetrics(context.Background(), testutils.TestMetrics.Clone()) require.NoError(t, err) body := <-server.MetadataChan diff --git a/exporter/datadogexporter/testdata/config.yaml b/exporter/datadogexporter/testdata/config.yaml index d783c7e76f94..9c17dd7bc1fa 100644 --- a/exporter/datadogexporter/testdata/config.yaml +++ b/exporter/datadogexporter/testdata/config.yaml @@ -13,6 +13,7 @@ exporters: # Deprecated; kept here to avoid regressions. version: myversion + # Deprecated; kept here to avoid regressions. tags: - example:tag @@ -27,8 +28,8 @@ exporters: hostname: customhostname env: prod - tags: - - example:tag + host_metadata: + tags: [example:tag] api: key: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -46,6 +47,16 @@ exporters: api: key: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + datadog/hostmetadata: + api: + key: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + # Deprecated; kept here to test rename system + tags: [example:one] + # Deprecated; kept here to test rename system + send_metadata: true + # Deprecated; kept here to test rename system + use_resource_metadata: false + datadog/default2: datadog/invalid: diff --git a/exporter/datadogexporter/traces_exporter.go b/exporter/datadogexporter/traces_exporter.go index d4ee257365c8..16d897c7787f 100644 --- a/exporter/datadogexporter/traces_exporter.go +++ b/exporter/datadogexporter/traces_exporter.go @@ -116,7 +116,7 @@ func (exp *traceExporter) pushTraceData( // Start host metadata with resource attributes from // the first payload. - if exp.cfg.SendMetadata { + if exp.cfg.HostMetadata.Enabled { exp.onceMetadata.Do(func() { attrs := pdata.NewMap() if td.ResourceSpans().Len() > 0 { diff --git a/exporter/datadogexporter/traces_exporter_test.go b/exporter/datadogexporter/traces_exporter_test.go index 16fd7b7fceb3..0a2acba161b0 100644 --- a/exporter/datadogexporter/traces_exporter_test.go +++ b/exporter/datadogexporter/traces_exporter_test.go @@ -188,8 +188,11 @@ func TestPushTraceData(t *testing.T) { SampleRate: 1, TCPAddr: confignet.TCPAddr{Endpoint: server.URL}, }, - SendMetadata: true, - UseResourceMetadata: true, + + HostMetadata: config.HostMetadataConfig{ + Enabled: true, + HostnameSource: config.HostnameSourceFirstResource, + }, } params := componenttest.NewNopExporterCreateSettings() From ed955008d97be1d46fa1086d1745a0230ac4ae0c Mon Sep 17 00:00:00 2001 From: Pablo Baeyens Date: Wed, 6 Apr 2022 13:25:43 +0200 Subject: [PATCH 2/4] Add CHANGELOG entry --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e32eb9f9e26..5cdc7739bf69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ generated code (#5270) - Add `make crosslink` target to ensure replace statements are included in `go.mod` for all transitive dependencies within repository (#8822) - `filestorageextension`: Change bbolt DB settings for better performance (#9004) +- `datadogexporter`: Add `host_metadata` configuration section to configure host metadata export (#9100) ### 🛑 Breaking changes 🛑 @@ -28,6 +29,9 @@ - `datadogexporter`: Deprecate `service` setting in favor of `service.name` semantic convention (#8784) - `datadogexporter`: Deprecate `version` setting in favor of `service.version` semantic convention (#8784) - `datadogexporter`: Deprecate `GetHostTags` method from `TagsConfig` struct (#8975) +- `datadogexporter`: Deprecate `tags` setting in favor of `host_metadata::tags` (#9100) +- `datadogexporter`: Deprecate `send_metadata` setting in favor of `host_metadata::enabled` (#9100) +- `datadogexporter`: Deprecate `use_resource_metadata` setting in favor of `host_metadata::hostname_source` (#9100) ### 🚀 New components 🚀 From e31ea1e9033d88e8d431771aff2d699d96e18d4c Mon Sep 17 00:00:00 2001 From: Pablo Baeyens Date: Wed, 6 Apr 2022 15:32:28 +0200 Subject: [PATCH 3/4] Apply suggestions from code review Co-authored-by: Albert Vaca Cintora --- exporter/datadogexporter/config/config.go | 2 +- exporter/datadogexporter/example/config.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/exporter/datadogexporter/config/config.go b/exporter/datadogexporter/config/config.go index 8e95fc3d5f7d..0b87457637de 100644 --- a/exporter/datadogexporter/config/config.go +++ b/exporter/datadogexporter/config/config.go @@ -31,7 +31,7 @@ import ( var ( errUnsetAPIKey = errors.New("api.key is not set") - errNoMetadata = errors.New("only_metadata can't be enabled when host_metadata::enabled = false or hostname_source != first_resource") + errNoMetadata = errors.New("only_metadata can't be enabled when host_metadata::enabled = false or host_metadata::hostname_source != first_resource") ) // TODO: Import these from translator when we eliminate cyclic dependency. diff --git a/exporter/datadogexporter/example/config.yaml b/exporter/datadogexporter/example/config.yaml index e2812cff94ae..3ffba742d2de 100644 --- a/exporter/datadogexporter/example/config.yaml +++ b/exporter/datadogexporter/example/config.yaml @@ -194,9 +194,9 @@ exporters: ## @param host_metadata - custom object - optional ## Host metadata specific configuration. - ## Host metadata is the information used for populating the infrastructure list, the host map and providing host tags functionality. + ## Host metadata is the information used for populating the infrastructure list, the host map and providing host tags functionality within the Datadog app. ## - ## The exporter will send host metadata for a single host, whose name is chosen + ## The exporter will only send host metadata for a single host, whose name is chosen ## according to `host_metadata::hostname_source`. # # host_metadata: From 04e7d72f6edbb4c16685e9270813738ae1743c11 Mon Sep 17 00:00:00 2001 From: Pablo Baeyens Date: Fri, 8 Apr 2022 13:54:06 +0200 Subject: [PATCH 4/4] Apply suggestions from code review Co-authored-by: Kylian Serrania --- exporter/datadogexporter/config/config.go | 6 +++--- exporter/datadogexporter/example/config.yaml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/exporter/datadogexporter/config/config.go b/exporter/datadogexporter/config/config.go index b62b1f7f8f5f..e2e2b54d4c91 100644 --- a/exporter/datadogexporter/config/config.go +++ b/exporter/datadogexporter/config/config.go @@ -257,7 +257,7 @@ type HostnameSource string const ( // HostnameSourceFirstResource picks the host metadata hostname from the resource // attributes on the first OTLP payload that gets to the exporter. If it is lacking any - // hostname-like attributes, it will fallback to system data (see below). + // hostname-like attributes, it will fallback to 'config_or_system' behavior (see below). // // Do not use this hostname source if receiving data from multiple hosts. HostnameSourceFirstResource HostnameSource = "first_resource" @@ -355,8 +355,8 @@ type Config struct { // metadata about a host is sent to the backend even // when telemetry data is reported via a different host. // - // This flag is incompatible with disabling host metadata - // or `use_resource_metadata`. + // This flag is incompatible with disabling host metadata, + // `use_resource_metadata`, or `host_metadata::hostname_source != first_resource` OnlyMetadata bool `mapstructure:"only_metadata"` // UseResourceMetadata defines whether to use resource attributes diff --git a/exporter/datadogexporter/example/config.yaml b/exporter/datadogexporter/example/config.yaml index a3f2157d78a7..5f743496171f 100644 --- a/exporter/datadogexporter/example/config.yaml +++ b/exporter/datadogexporter/example/config.yaml @@ -216,7 +216,7 @@ exporters: ## ## - 'config_or_system' picks the host metadata hostname from the 'hostname' setting, falling back to system and cloud provider APIs. ## - ## The current default if 'first_resource'. + ## The current default is 'first_resource'. # # hostname_source: first_resource