Skip to content

Commit edc4900

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 matches the OpAMP recommendations: https://github.com/open-telemetry/opamp-spec/blob/main/specification.md#agentdescriptionidentifying_attributes - The service.name can be overridden by the end user via telemetry config setting.
1 parent 8254e36 commit edc4900

File tree

3 files changed

+109
-22
lines changed

3 files changed

+109
-22
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
- Delete deprecated `pcommon.Map.Update*` funcs. (#6088)
1515
- Change `pcommon.NewValueBytes` signature to match `pcommon.NewValueBytesEmpty`. (#6088)
1616
- Delete deprecated `pcommon.Empty[Trace|Span]ID`. (#6098)
17-
- Delete deprecated `pcommon.[Trace|Span]ID.Bytes()`. (#6098)
17+
- Delete deprecated `pcommon.SpanID.Bytes()`. (#6098)
1818
- Delete deprecated `pcommon.New[Trace|Span]ID()`. (#6098)
1919
- Delete deprecated `pcommon.Value.SetBytesVal`. (#6088)
2020
- Delete deprecated `pmetric.Metric.SetDataType`. (#6095)
@@ -46,6 +46,7 @@
4646

4747
- Add AppendEmpty and EnsureCapacity method to primitive pdata slices (#6060)
4848
- Expose `AsRaw` and `FromRaw` `pcommon.Value` methods (#6090)
49+
- service.name Resource attribute is added to Collector's own telemetry and defaults to "io.opentelemetry.collector" (#6152)
4950
- Updated how `telemetryInitializer` is created so it's instanced per Collector instance rather than global to the process (#6138)
5051

5152
## v0.60.0 Beta

service/telemetry.go

+38-21
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ const (
5757
// supported trace propagators
5858
traceContextPropagator = "tracecontext"
5959
b3Propagator = "b3"
60+
61+
// Default value of "service.name" resource attribute in the telemetry
62+
// that the Collector produces about itself. This can be overridden
63+
// by the end user via telemetry.Config.Resource setting.
64+
defaultServiceName = "io.opentelemetry.collector"
6065
)
6166

6267
var (
@@ -117,27 +122,8 @@ func (tel *telemetryInitializer) initOnce(buildInfo component.BuildInfo, logger
117122

118123
logger.Info("Setting up own telemetry...")
119124

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

142128
if tp, err := textMapPropagatorFromConfig(cfg.Traces.Propagators); err == nil {
143129
otel.SetTextMapPropagator(tp)
@@ -179,6 +165,37 @@ func (tel *telemetryInitializer) initOnce(buildInfo component.BuildInfo, logger
179165
return nil
180166
}
181167

168+
func buildTelAttrs(buildInfo component.BuildInfo, cfg telemetry.Config) map[string]string {
169+
telAttrs := map[string]string{}
170+
171+
for k, v := range cfg.Resource {
172+
// nil value indicates that the attribute should not be included in the telemetry.
173+
if v != nil {
174+
telAttrs[k] = *v
175+
}
176+
}
177+
178+
if _, ok := cfg.Resource[semconv.AttributeServiceName]; !ok {
179+
// AttributeServiceName is not specified in the config. Use the default service name.
180+
telAttrs[semconv.AttributeServiceName] = defaultServiceName
181+
}
182+
183+
if _, ok := cfg.Resource[semconv.AttributeServiceInstanceID]; !ok {
184+
// AttributeServiceInstanceID is not specified in the config. Auto-generate one.
185+
instanceUUID, _ := uuid.NewRandom()
186+
instanceID := instanceUUID.String()
187+
telAttrs[semconv.AttributeServiceInstanceID] = instanceID
188+
}
189+
190+
if _, ok := cfg.Resource[semconv.AttributeServiceVersion]; !ok {
191+
// AttributeServiceVersion is not specified in the config. Use the actual
192+
// build version.
193+
telAttrs[semconv.AttributeServiceVersion] = buildInfo.Version
194+
}
195+
196+
return telAttrs
197+
}
198+
182199
func (tel *telemetryInitializer) initOpenCensus(cfg telemetry.Config, telAttrs map[string]string) (http.Handler, error) {
183200
tel.ocRegistry = ocmetric.NewRegistry()
184201
metricproducer.GlobalManager().AddProducer(tel.ocRegistry)

service/telemetry_test.go

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright The OpenTelemetry Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package service
16+
17+
import (
18+
"testing"
19+
20+
"github.com/stretchr/testify/assert"
21+
22+
"go.opentelemetry.io/collector/component"
23+
semconv "go.opentelemetry.io/collector/semconv/v1.5.0"
24+
"go.opentelemetry.io/collector/service/telemetry"
25+
)
26+
27+
func TestBuildTelAttrs(t *testing.T) {
28+
buildInfo := component.NewDefaultBuildInfo()
29+
30+
// Check default config
31+
cfg := telemetry.Config{}
32+
telAttrs := buildTelAttrs(buildInfo, cfg)
33+
34+
assert.Len(t, telAttrs, 3)
35+
assert.Equal(t, defaultServiceName, telAttrs[semconv.AttributeServiceName])
36+
assert.Equal(t, buildInfo.Version, telAttrs[semconv.AttributeServiceVersion])
37+
38+
_, exists := telAttrs[semconv.AttributeServiceInstanceID]
39+
assert.True(t, exists)
40+
41+
// Check override by nil
42+
cfg = telemetry.Config{
43+
Resource: map[string]*string{
44+
semconv.AttributeServiceName: nil,
45+
semconv.AttributeServiceVersion: nil,
46+
semconv.AttributeServiceInstanceID: nil,
47+
},
48+
}
49+
telAttrs = buildTelAttrs(buildInfo, cfg)
50+
51+
// Attributes should not exist since we nil-ified all.
52+
assert.Len(t, telAttrs, 0)
53+
54+
// Check override values
55+
strPtr := func(v string) *string { return &v }
56+
cfg = telemetry.Config{
57+
Resource: map[string]*string{
58+
semconv.AttributeServiceName: strPtr("a"),
59+
semconv.AttributeServiceVersion: strPtr("b"),
60+
semconv.AttributeServiceInstanceID: strPtr("c"),
61+
},
62+
}
63+
telAttrs = buildTelAttrs(buildInfo, cfg)
64+
65+
assert.Len(t, telAttrs, 3)
66+
assert.Equal(t, "a", telAttrs[semconv.AttributeServiceName])
67+
assert.Equal(t, "b", telAttrs[semconv.AttributeServiceVersion])
68+
assert.Equal(t, "c", telAttrs[semconv.AttributeServiceInstanceID])
69+
}

0 commit comments

Comments
 (0)