Skip to content

Commit 61a4c13

Browse files
Add service.name resource attribute to the collector's own telemetry
Resolves open-telemetry#6136 - The default service.name is set to "io.opentelemetry.collector". I think this is a good choice since it is unambiguous and is still short enough to be readable. This also coincides with OpAMP recommendations: https://github.com/open-telemetry/opamp-spec/blob/main/specification.md#agentdescriptionidentifying_attributes - I made the service.name a setting in BuildInfo which can be overridden when building the Collector. Other distros may choose a different service.name. - The service.name can be also overridden by the end user via telemetry config setting.
1 parent 65ea4f0 commit 61a4c13

File tree

9 files changed

+104
-21
lines changed

9 files changed

+104
-21
lines changed

cmd/builder/internal/builder/config.go

+3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
)
2828

2929
const defaultOtelColVersion = "0.60.0"
30+
const defaultOtelColServiceName = "io.opentelemetry.collector"
3031

3132
// ErrInvalidGoMod indicates an invalid gomod
3233
var ErrInvalidGoMod = errors.New("invalid gomod specification for module")
@@ -55,6 +56,7 @@ type Distribution struct {
5556
OtelColVersion string `mapstructure:"otelcol_version"`
5657
OutputPath string `mapstructure:"output_path"`
5758
Version string `mapstructure:"version"`
59+
ServiceName string `mapstructure:"service_name"`
5860
BuildTags string `mapstructure:"build_tags"`
5961
}
6062

@@ -84,6 +86,7 @@ func NewDefaultConfig() Config {
8486
OutputPath: outputDir,
8587
OtelColVersion: defaultOtelColVersion,
8688
Module: "go.opentelemetry.io/collector/cmd/builder",
89+
ServiceName: defaultOtelColServiceName,
8790
},
8891
}
8992
}

cmd/builder/internal/builder/templates/main.go.tmpl

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ func main() {
2020
Command: "{{ .Distribution.Name }}",
2121
Description: "{{ .Distribution.Description }}",
2222
Version: "{{ .Distribution.Version }}",
23+
ServiceName: "{{ .Distribution.ServiceName }}",
2324
}
2425

2526
if err := run(service.CollectorSettings{BuildInfo: info, Factories: factories}); err != nil {

cmd/builder/internal/command.go

+4
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ const (
3636
distributionNameFlag = "name"
3737
distributionDescriptionFlag = "description"
3838
distributionVersionFlag = "version"
39+
distributionServiceNameFlag = "service-name"
3940
distributionOtelColVersionFlag = "otelcol-version"
4041
distributionOutputPathFlag = "output-path"
4142
distributionGoFlag = "go"
@@ -180,6 +181,9 @@ func applyCfgFromFile(flags *flag.FlagSet, cfgFromFile builder.Config) {
180181
if !flags.Changed(distributionVersionFlag) && cfgFromFile.Distribution.Version != "" {
181182
cfg.Distribution.Version = cfgFromFile.Distribution.Version
182183
}
184+
if !flags.Changed(distributionServiceNameFlag) && cfgFromFile.Distribution.ServiceName != "" {
185+
cfg.Distribution.ServiceName = cfgFromFile.Distribution.ServiceName
186+
}
183187
if !flags.Changed(distributionOtelColVersionFlag) && cfgFromFile.Distribution.OtelColVersion != "" {
184188
cfg.Distribution.OtelColVersion = cfgFromFile.Distribution.OtelColVersion
185189
}

cmd/builder/internal/config/default.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ dist:
44
description: Local OpenTelemetry Collector binary, testing only.
55
version: 0.60.0-dev
66
otelcol_version: 0.60.0
7+
service_name: io.opentelemetry.collector
78

89
receivers:
910
- import: go.opentelemetry.io/collector/receiver/otlpreceiver

cmd/otelcorecol/builder-config.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ dist:
44
description: Local OpenTelemetry Collector binary, testing only.
55
version: 0.60.0-dev
66
otelcol_version: 0.60.0
7+
service_name: io.opentelemetry.collector
78

89
receivers:
910
- import: go.opentelemetry.io/collector/receiver/otlpreceiver

cmd/otelcorecol/main.go

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

component/build_info.go

+6
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ type BuildInfo struct {
2525

2626
// Version string.
2727
Version string
28+
29+
// ServiceName is the value of "service.name" attribute in the telemetry
30+
// that the Collector produces about itself. This can be overridden
31+
// by the end user via telemetry.Config.Resource setting.
32+
ServiceName string
2833
}
2934

3035
// NewDefaultBuildInfo returns a default BuildInfo.
@@ -33,5 +38,6 @@ func NewDefaultBuildInfo() BuildInfo {
3338
Command: "otelcol",
3439
Description: "OpenTelemetry Collector",
3540
Version: "latest",
41+
ServiceName: "io.opentelemetry.collector",
3642
}
3743
}

service/telemetry.go

+33-21
Original file line numberDiff line numberDiff line change
@@ -112,27 +112,8 @@ func (tel *telemetryInitializer) initOnce(buildInfo component.BuildInfo, logger
112112

113113
logger.Info("Setting up own telemetry...")
114114

115-
// Construct telemetry attributes from resource attributes.
116-
telAttrs := map[string]string{}
117-
for k, v := range cfg.Resource {
118-
// nil value indicates that the attribute should not be included in the telemetry.
119-
if v != nil {
120-
telAttrs[k] = *v
121-
}
122-
}
123-
124-
if _, ok := cfg.Resource[semconv.AttributeServiceInstanceID]; !ok {
125-
// AttributeServiceInstanceID is not specified in the config. Auto-generate one.
126-
instanceUUID, _ := uuid.NewRandom()
127-
instanceID := instanceUUID.String()
128-
telAttrs[semconv.AttributeServiceInstanceID] = instanceID
129-
}
130-
131-
if _, ok := cfg.Resource[semconv.AttributeServiceVersion]; !ok {
132-
// AttributeServiceVersion is not specified in the config. Use the actual
133-
// build version.
134-
telAttrs[semconv.AttributeServiceVersion] = buildInfo.Version
135-
}
115+
// Construct telemetry attributes from build info and config's resource attributes.
116+
telAttrs := buildTelAttrs(buildInfo, cfg)
136117

137118
if tp, err := textMapPropagatorFromConfig(cfg.Traces.Propagators); err == nil {
138119
otel.SetTextMapPropagator(tp)
@@ -174,6 +155,37 @@ func (tel *telemetryInitializer) initOnce(buildInfo component.BuildInfo, logger
174155
return nil
175156
}
176157

158+
func buildTelAttrs(buildInfo component.BuildInfo, cfg telemetry.Config) map[string]string {
159+
telAttrs := map[string]string{}
160+
161+
for k, v := range cfg.Resource {
162+
// nil value indicates that the attribute should not be included in the telemetry.
163+
if v != nil {
164+
telAttrs[k] = *v
165+
}
166+
}
167+
168+
if _, ok := cfg.Resource[semconv.AttributeServiceName]; !ok {
169+
// AttributeServiceName is not specified in the config. Use the Service name.
170+
telAttrs[semconv.AttributeServiceName] = buildInfo.ServiceName
171+
}
172+
173+
if _, ok := cfg.Resource[semconv.AttributeServiceInstanceID]; !ok {
174+
// AttributeServiceInstanceID is not specified in the config. Auto-generate one.
175+
instanceUUID, _ := uuid.NewRandom()
176+
instanceID := instanceUUID.String()
177+
telAttrs[semconv.AttributeServiceInstanceID] = instanceID
178+
}
179+
180+
if _, ok := cfg.Resource[semconv.AttributeServiceVersion]; !ok {
181+
// AttributeServiceVersion is not specified in the config. Use the actual
182+
// build version.
183+
telAttrs[semconv.AttributeServiceVersion] = buildInfo.Version
184+
}
185+
186+
return telAttrs
187+
}
188+
177189
func (tel *telemetryInitializer) initOpenCensus(cfg telemetry.Config, telAttrs map[string]string) (http.Handler, error) {
178190
tel.ocRegistry = ocmetric.NewRegistry()
179191
metricproducer.GlobalManager().AddProducer(tel.ocRegistry)

service/telemetry_test.go

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package service
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
"go.opentelemetry.io/collector/component"
8+
semconv "go.opentelemetry.io/collector/semconv/v1.5.0"
9+
"go.opentelemetry.io/collector/service/telemetry"
10+
)
11+
12+
func TestBuildTelAttrs(t *testing.T) {
13+
buildInfo := component.NewDefaultBuildInfo()
14+
15+
// Check default config
16+
cfg := telemetry.Config{}
17+
telAttrs := buildTelAttrs(buildInfo, cfg)
18+
19+
assert.Len(t, telAttrs, 3)
20+
assert.Equal(t, buildInfo.ServiceName, telAttrs[semconv.AttributeServiceName])
21+
assert.Equal(t, buildInfo.Version, telAttrs[semconv.AttributeServiceVersion])
22+
23+
_, exists := telAttrs[semconv.AttributeServiceInstanceID]
24+
assert.True(t, exists)
25+
26+
// Check override by nil
27+
cfg = telemetry.Config{
28+
Resource: map[string]*string{
29+
semconv.AttributeServiceName: nil,
30+
semconv.AttributeServiceVersion: nil,
31+
semconv.AttributeServiceInstanceID: nil,
32+
},
33+
}
34+
telAttrs = buildTelAttrs(buildInfo, cfg)
35+
36+
// Attribute should not exist
37+
assert.Len(t, telAttrs, 0)
38+
39+
// Check override values
40+
strPtr := func(v string) *string { return &v }
41+
cfg = telemetry.Config{
42+
Resource: map[string]*string{
43+
semconv.AttributeServiceName: strPtr("a"),
44+
semconv.AttributeServiceVersion: strPtr("b"),
45+
semconv.AttributeServiceInstanceID: strPtr("c"),
46+
},
47+
}
48+
telAttrs = buildTelAttrs(buildInfo, cfg)
49+
50+
assert.Len(t, telAttrs, 3)
51+
assert.Equal(t, "a", telAttrs[semconv.AttributeServiceName])
52+
assert.Equal(t, "b", telAttrs[semconv.AttributeServiceVersion])
53+
assert.Equal(t, "c", telAttrs[semconv.AttributeServiceInstanceID])
54+
}

0 commit comments

Comments
 (0)