Skip to content

Commit

Permalink
Add service.name resource attribute to the collector's own telemetry
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tigrannajaryan committed Sep 27, 2022
1 parent 65ea4f0 commit 696e914
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 21 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

- Add AppendEmpty and EnsureCapacity method to primitive pdata slices (#6060)
- Expose `AsRaw` and `FromRaw` `pcommon.Value` methods (#6090)
- service.name Resource attribute is added to Collector's own telemetry and defaults to "io.opentelemetry.collector" (#6152)

## v0.60.0 Beta

Expand Down
1 change: 1 addition & 0 deletions cmd/otelcorecol/builder-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ dist:
description: Local OpenTelemetry Collector binary, testing only.
version: 0.60.0-dev
otelcol_version: 0.60.0
service_name: io.opentelemetry.collector

receivers:
- import: go.opentelemetry.io/collector/receiver/otlpreceiver
Expand Down
59 changes: 38 additions & 21 deletions service/telemetry.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ const (
// supported trace propagators
traceContextPropagator = "tracecontext"
b3Propagator = "b3"

// Default value of "service.name" attribute in the telemetry
// that the Collector produces about itself. This can be overridden
// by the end user via telemetry.Config.Resource setting.
defaultServiceName = "io.opentelemetry.collector"
)

var (
Expand Down Expand Up @@ -112,27 +117,8 @@ func (tel *telemetryInitializer) initOnce(buildInfo component.BuildInfo, logger

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

// Construct telemetry attributes from resource attributes.
telAttrs := map[string]string{}
for k, v := range cfg.Resource {
// nil value indicates that the attribute should not be included in the telemetry.
if v != nil {
telAttrs[k] = *v
}
}

if _, ok := cfg.Resource[semconv.AttributeServiceInstanceID]; !ok {
// AttributeServiceInstanceID is not specified in the config. Auto-generate one.
instanceUUID, _ := uuid.NewRandom()
instanceID := instanceUUID.String()
telAttrs[semconv.AttributeServiceInstanceID] = instanceID
}

if _, ok := cfg.Resource[semconv.AttributeServiceVersion]; !ok {
// AttributeServiceVersion is not specified in the config. Use the actual
// build version.
telAttrs[semconv.AttributeServiceVersion] = buildInfo.Version
}
// Construct telemetry attributes from build info and config's resource attributes.
telAttrs := buildTelAttrs(buildInfo, cfg)

if tp, err := textMapPropagatorFromConfig(cfg.Traces.Propagators); err == nil {
otel.SetTextMapPropagator(tp)
Expand Down Expand Up @@ -174,6 +160,37 @@ func (tel *telemetryInitializer) initOnce(buildInfo component.BuildInfo, logger
return nil
}

func buildTelAttrs(buildInfo component.BuildInfo, cfg telemetry.Config) map[string]string {
telAttrs := map[string]string{}

for k, v := range cfg.Resource {
// nil value indicates that the attribute should not be included in the telemetry.
if v != nil {
telAttrs[k] = *v
}
}

if _, ok := cfg.Resource[semconv.AttributeServiceName]; !ok {
// AttributeServiceName is not specified in the config. Use the Service name.
telAttrs[semconv.AttributeServiceName] = defaultServiceName
}

if _, ok := cfg.Resource[semconv.AttributeServiceInstanceID]; !ok {
// AttributeServiceInstanceID is not specified in the config. Auto-generate one.
instanceUUID, _ := uuid.NewRandom()
instanceID := instanceUUID.String()
telAttrs[semconv.AttributeServiceInstanceID] = instanceID
}

if _, ok := cfg.Resource[semconv.AttributeServiceVersion]; !ok {
// AttributeServiceVersion is not specified in the config. Use the actual
// build version.
telAttrs[semconv.AttributeServiceVersion] = buildInfo.Version
}

return telAttrs
}

func (tel *telemetryInitializer) initOpenCensus(cfg telemetry.Config, telAttrs map[string]string) (http.Handler, error) {
tel.ocRegistry = ocmetric.NewRegistry()
metricproducer.GlobalManager().AddProducer(tel.ocRegistry)
Expand Down
69 changes: 69 additions & 0 deletions service/telemetry_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package service

import (
"testing"

"github.com/stretchr/testify/assert"

"go.opentelemetry.io/collector/component"
semconv "go.opentelemetry.io/collector/semconv/v1.5.0"
"go.opentelemetry.io/collector/service/telemetry"
)

func TestBuildTelAttrs(t *testing.T) {
buildInfo := component.NewDefaultBuildInfo()

// Check default config
cfg := telemetry.Config{}
telAttrs := buildTelAttrs(buildInfo, cfg)

assert.Len(t, telAttrs, 3)
assert.Equal(t, defaultServiceName, telAttrs[semconv.AttributeServiceName])
assert.Equal(t, buildInfo.Version, telAttrs[semconv.AttributeServiceVersion])

_, exists := telAttrs[semconv.AttributeServiceInstanceID]
assert.True(t, exists)

// Check override by nil
cfg = telemetry.Config{
Resource: map[string]*string{
semconv.AttributeServiceName: nil,
semconv.AttributeServiceVersion: nil,
semconv.AttributeServiceInstanceID: nil,
},
}
telAttrs = buildTelAttrs(buildInfo, cfg)

// Attributes should not exist since we nil-ified all.
assert.Len(t, telAttrs, 0)

// Check override values
strPtr := func(v string) *string { return &v }
cfg = telemetry.Config{
Resource: map[string]*string{
semconv.AttributeServiceName: strPtr("a"),
semconv.AttributeServiceVersion: strPtr("b"),
semconv.AttributeServiceInstanceID: strPtr("c"),
},
}
telAttrs = buildTelAttrs(buildInfo, cfg)

assert.Len(t, telAttrs, 3)
assert.Equal(t, "a", telAttrs[semconv.AttributeServiceName])
assert.Equal(t, "b", telAttrs[semconv.AttributeServiceVersion])
assert.Equal(t, "c", telAttrs[semconv.AttributeServiceInstanceID])
}

0 comments on commit 696e914

Please sign in to comment.