Skip to content

Commit db5633c

Browse files
committed
Handle deployment.environment.name
If `deployment.environment.name` is set, we duplicate it into `deployment.environment` in order to make the `service.environment` -> `deployment.environment` work.
1 parent 29d0d13 commit db5633c

File tree

3 files changed

+78
-8
lines changed

3 files changed

+78
-8
lines changed

enrichments/trace/config/config.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@ type Config struct {
2828

2929
// ResourceConfig configures the enrichment of resource attributes.
3030
type ResourceConfig struct {
31-
AgentName AttributeConfig `mapstructure:"agent_name"`
32-
AgentVersion AttributeConfig `mapstructure:"agent_version"`
33-
OverrideHostName AttributeConfig `mapstructure:"override_host_name"`
31+
AgentName AttributeConfig `mapstructure:"agent_name"`
32+
AgentVersion AttributeConfig `mapstructure:"agent_version"`
33+
OverrideHostName AttributeConfig `mapstructure:"override_host_name"`
34+
DeploymentEnvironment AttributeConfig `mapstructure:"deployment_environment"`
3435
}
3536

3637
// ScopeConfig configures the enrichment of scope attributes.
@@ -103,9 +104,10 @@ type AttributeConfig struct {
103104
func Enabled() Config {
104105
return Config{
105106
Resource: ResourceConfig{
106-
AgentName: AttributeConfig{Enabled: true},
107-
AgentVersion: AttributeConfig{Enabled: true},
108-
OverrideHostName: AttributeConfig{Enabled: true},
107+
AgentName: AttributeConfig{Enabled: true},
108+
AgentVersion: AttributeConfig{Enabled: true},
109+
OverrideHostName: AttributeConfig{Enabled: true},
110+
DeploymentEnvironment: AttributeConfig{Enabled: true},
109111
},
110112
Scope: ScopeConfig{
111113
ServiceFrameworkName: AttributeConfig{Enabled: true},

enrichments/trace/internal/elastic/resource.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ import (
2323
"github.com/elastic/opentelemetry-lib/elasticattr"
2424
"github.com/elastic/opentelemetry-lib/enrichments/trace/config"
2525
"go.opentelemetry.io/collector/pdata/pcommon"
26-
semconv "go.opentelemetry.io/collector/semconv/v1.25.0"
26+
semconv25 "go.opentelemetry.io/collector/semconv/v1.25.0"
27+
semconv "go.opentelemetry.io/collector/semconv/v1.27.0"
2728
)
2829

2930
// EnrichResource derives and adds Elastic specific resource attributes.
@@ -73,6 +74,22 @@ func (s *resourceEnrichmentContext) Enrich(resource pcommon.Resource, cfg config
7374
if cfg.OverrideHostName.Enabled {
7475
s.overrideHostNameWithK8sNodeName(resource)
7576
}
77+
78+
if cfg.DeploymentEnvironment.Enabled {
79+
s.setDeploymentEnvironment(resource)
80+
}
81+
}
82+
83+
// SemConv v1.27.0 deprecated `deployment.environment` and added `deployment.environment.name` in favor of it.
84+
// In the `otel-data` ES plugin we alias `service.environment` to `deployment.environment`.
85+
// ES currently doesn't allow aliases with multiple targets, so if the new field name is used (SemConv v1.27+),
86+
// we duplicate the value and also send it with the old field name to make the alias work.
87+
func (s *resourceEnrichmentContext) setDeploymentEnvironment(resource pcommon.Resource) {
88+
if deploymentEnvironmentName, deploymentEnvironmentNameExists := resource.Attributes().Get(semconv.AttributeDeploymentEnvironmentName); deploymentEnvironmentNameExists {
89+
if _, deploymentEnvironmentExists := resource.Attributes().Get(semconv25.AttributeDeploymentEnvironment); !deploymentEnvironmentExists {
90+
resource.Attributes().PutStr(semconv25.AttributeDeploymentEnvironment, deploymentEnvironmentName.AsString())
91+
}
92+
}
7693
}
7794

7895
func (s *resourceEnrichmentContext) setAgentName(resource pcommon.Resource) {

enrichments/trace/internal/elastic/resource_test.go

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ import (
2525
"github.com/google/go-cmp/cmp"
2626
"github.com/stretchr/testify/assert"
2727
"go.opentelemetry.io/collector/pdata/pcommon"
28-
semconv "go.opentelemetry.io/collector/semconv/v1.25.0"
28+
semconv25 "go.opentelemetry.io/collector/semconv/v1.25.0"
29+
semconv "go.opentelemetry.io/collector/semconv/v1.27.0"
2930
)
3031

3132
func TestResourceEnrich(t *testing.T) {
@@ -194,6 +195,56 @@ func TestResourceEnrich(t *testing.T) {
194195
elasticattr.AgentVersion: "unknown",
195196
},
196197
},
198+
{
199+
// Pre SemConv 1.27
200+
name: "deployment_environment_set",
201+
input: func() pcommon.Resource {
202+
res := pcommon.NewResource()
203+
res.Attributes().PutStr(semconv25.AttributeDeploymentEnvironment, "prod")
204+
return res
205+
}(),
206+
config: config.Enabled().Resource,
207+
enrichedAttrs: map[string]any{
208+
semconv25.AttributeDeploymentEnvironment: "prod",
209+
elasticattr.AgentName: "otlp",
210+
elasticattr.AgentVersion: "unknown",
211+
},
212+
},
213+
{
214+
// SemConv 1.27+ with new `deployment.environment.name` field
215+
name: "deployment_environment_name_set",
216+
input: func() pcommon.Resource {
217+
res := pcommon.NewResource()
218+
res.Attributes().PutStr(semconv.AttributeDeploymentEnvironmentName, "prod")
219+
return res
220+
}(),
221+
config: config.Enabled().Resource,
222+
enrichedAttrs: map[string]any{
223+
// To satisfy aliases defined in ES, we duplicate the value for both fields.
224+
semconv25.AttributeDeploymentEnvironment: "prod",
225+
semconv.AttributeDeploymentEnvironmentName: "prod",
226+
elasticattr.AgentName: "otlp",
227+
elasticattr.AgentVersion: "unknown",
228+
},
229+
},
230+
{
231+
// Mixed pre and post SemConv 1.27 versions (should be an edge case, but some EDOTs might do this).
232+
name: "deployment_environment_mixed",
233+
input: func() pcommon.Resource {
234+
res := pcommon.NewResource()
235+
res.Attributes().PutStr(semconv.AttributeDeploymentEnvironmentName, "prod")
236+
res.Attributes().PutStr(semconv25.AttributeDeploymentEnvironment, "test")
237+
return res
238+
}(),
239+
config: config.Enabled().Resource,
240+
enrichedAttrs: map[string]any{
241+
// If both are set, we don't touch those values and take them as they are.
242+
semconv25.AttributeDeploymentEnvironment: "test",
243+
semconv.AttributeDeploymentEnvironmentName: "prod",
244+
elasticattr.AgentName: "otlp",
245+
elasticattr.AgentVersion: "unknown",
246+
},
247+
},
197248
} {
198249
t.Run(tc.name, func(t *testing.T) {
199250
// Merge existing resource attrs with the attrs added

0 commit comments

Comments
 (0)