Skip to content

Commit 5d5fb21

Browse files
authored
Introduce component logger with appropriate attributes (#12259)
Implements the logger described in #12217 Alternative to #12057 Resolves #11814 `component/componentattribute`: - Initializes new module - Defines constants for component telemetry attribute keys - Defines a `zapcore.Core` which can remove attributes from the root logger `service`: - Rebases component instantiation on attribute sets - Internal constructors for attribute sets for each component type - Constructs loggers from `componentattribute` `otlpreceiver`: - Uses `componentattribute` to remove `otelcol.signal` attribute from logger `memorylimiter`: - Uses `componentattribute` to remove `otelcol.signal`, `otelcol.pipeline.id` and `otelcol.component.id` attributes from logger
1 parent 8d3fe01 commit 5d5fb21

39 files changed

+491
-208
lines changed

.chloggen/component-logger-api.yaml

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: 'enhancement'
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver)
7+
component: component/componentattribute
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: New module codifies component attributes and provides a zap.Logger for components.
11+
12+
# One or more tracking issues or pull requests related to the change
13+
issues: [12217]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext:
19+
20+
# Optional: The change log or logs in which this entry should be included.
21+
# e.g. '[user]' or '[user, api]'
22+
# Include 'user' if the change is relevant to end users.
23+
# Include 'api' if there is a change to a library API.
24+
# Default: '[user]'
25+
change_logs: [api]
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: bug_fix
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver)
7+
component: memorylimiter
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Logger no longer attributes to single signal, pipeline, or component.
11+
12+
# One or more tracking issues or pull requests related to the change
13+
issues: [12217]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext:
19+
20+
# Optional: The change log or logs in which this entry should be included.
21+
# e.g. '[user]' or '[user, api]'
22+
# Include 'user' if the change is relevant to end users.
23+
# Include 'api' if there is a change to a library API.
24+
# Default: '[user]'
25+
change_logs: []

.chloggen/component-logger-otlp.yaml

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: bug_fix
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver)
7+
component: otlpreceiver
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Logger no longer attributes to random signal when receiving multiple signals.
11+
12+
# One or more tracking issues or pull requests related to the change
13+
issues: [12217]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext:
19+
20+
# Optional: The change log or logs in which this entry should be included.
21+
# e.g. '[user]' or '[user, api]'
22+
# Include 'user' if the change is relevant to end users.
23+
# Include 'api' if there is a change to a library API.
24+
# Default: '[user]'
25+
change_logs: []

.chloggen/component-logger.yaml

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: enhancement
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver)
7+
component: service
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Align component logger attributes with those defined in RFC
11+
12+
# One or more tracking issues or pull requests related to the change
13+
issues: [12217]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext: |
19+
See [Pipeline Component Telemetry RFC](https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/rfcs/component-universal-telemetry.md#attributes)
20+
21+
# Optional: The change log or logs in which this entry should be included.
22+
# e.g. '[user]' or '[user, api]'
23+
# Include 'user' if the change is relevant to end users.
24+
# Include 'api' if there is a change to a library API.
25+
# Default: '[user]'
26+
change_logs: []

cmd/builder/internal/builder/main_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ require (
4040
var replaceModules = []string{
4141
"",
4242
"/component",
43-
"/component/componenttest",
43+
"/component/componentattribute",
4444
"/component/componentstatus",
45+
"/component/componenttest",
4546
"/client",
4647
"/config/configauth",
4748
"/config/configcompression",

cmd/otelcorecol/builder-config.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ replaces:
4141
- go.opentelemetry.io/collector/client => ../../client
4242
- go.opentelemetry.io/collector/component => ../../component
4343
- go.opentelemetry.io/collector/component/componenttest => ../../component/componenttest
44+
- go.opentelemetry.io/collector/component/componentattribute => ../../component/componentattribute
4445
- go.opentelemetry.io/collector/component/componentstatus => ../../component/componentstatus
4546
- go.opentelemetry.io/collector/config/configauth => ../../config/configauth
4647
- go.opentelemetry.io/collector/config/configcompression => ../../config/configcompression

cmd/otelcorecol/go.mod

+3
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ require (
8282
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
8383
go.opentelemetry.io/collector v0.119.0 // indirect
8484
go.opentelemetry.io/collector/client v1.25.0 // indirect
85+
go.opentelemetry.io/collector/component/componentattribute v0.119.0 // indirect
8586
go.opentelemetry.io/collector/component/componentstatus v0.119.0 // indirect
8687
go.opentelemetry.io/collector/component/componenttest v0.119.0 // indirect
8788
go.opentelemetry.io/collector/config/configauth v0.119.0 // indirect
@@ -169,6 +170,8 @@ replace go.opentelemetry.io/collector/component => ../../component
169170

170171
replace go.opentelemetry.io/collector/component/componenttest => ../../component/componenttest
171172

173+
replace go.opentelemetry.io/collector/component/componentattribute => ../../component/componentattribute
174+
172175
replace go.opentelemetry.io/collector/component/componentstatus => ../../component/componentstatus
173176

174177
replace go.opentelemetry.io/collector/config/configauth => ../../config/configauth

component/componentattribute/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include ../../Makefile.Common
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package componentattribute // import "go.opentelemetry.io/collector/component/componentattribute"
5+
6+
const (
7+
ComponentKindKey = "otelcol.component.kind"
8+
ComponentIDKey = "otelcol.component.id"
9+
PipelineIDKey = "otelcol.pipeline.id"
10+
SignalKey = "otelcol.signal"
11+
SignalOutputKey = "otelcol.signal.output"
12+
)

component/componentattribute/go.mod

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
module go.opentelemetry.io/collector/component/componentattribute
2+
3+
go 1.22.0
4+
5+
require (
6+
github.com/stretchr/testify v1.10.0
7+
go.opentelemetry.io/collector/pipeline v0.119.0
8+
go.opentelemetry.io/otel v1.34.0
9+
go.uber.org/zap v1.27.0
10+
)
11+
12+
require (
13+
github.com/davecgh/go-spew v1.1.1 // indirect
14+
github.com/kr/pretty v0.3.1 // indirect
15+
github.com/pmezard/go-difflib v1.0.0 // indirect
16+
github.com/rogpeppe/go-internal v1.10.0 // indirect
17+
go.uber.org/multierr v1.11.0 // indirect
18+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
19+
gopkg.in/yaml.v3 v3.0.1 // indirect
20+
)
21+
22+
replace go.opentelemetry.io/collector/pipeline => ../../pipeline

component/componentattribute/go.sum

+33
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package componentattribute // import "go.opentelemetry.io/collector/component/componentattribute"
5+
6+
import (
7+
"go.opentelemetry.io/otel/attribute"
8+
"go.uber.org/zap"
9+
"go.uber.org/zap/zapcore"
10+
)
11+
12+
var _ zapcore.Core = (*coreWithout)(nil)
13+
14+
type coreWithout struct {
15+
zapcore.Core
16+
from zapcore.Core
17+
fields []zap.Field
18+
}
19+
20+
func NewLogger(logger *zap.Logger, attrs *attribute.Set) *zap.Logger {
21+
fields := []zap.Field{}
22+
for _, kv := range attrs.ToSlice() {
23+
fields = append(fields, zap.String(string(kv.Key), kv.Value.AsString()))
24+
}
25+
return logger.WithOptions(
26+
zap.WrapCore(func(core zapcore.Core) zapcore.Core {
27+
return &coreWithout{Core: core.With(fields), from: core, fields: fields}
28+
}),
29+
)
30+
}
31+
32+
func (l *coreWithout) Without(keys ...string) zapcore.Core {
33+
excludeKeys := make(map[string]struct{})
34+
for _, key := range keys {
35+
excludeKeys[key] = struct{}{}
36+
}
37+
38+
fieldsWithout := []zap.Field{}
39+
for _, field := range l.fields {
40+
if _, excluded := excludeKeys[field.Key]; !excluded {
41+
fieldsWithout = append(fieldsWithout, field)
42+
}
43+
}
44+
45+
return &coreWithout{Core: l.from.With(fieldsWithout), from: l.from, fields: fieldsWithout}
46+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package componentattribute_test
5+
6+
import (
7+
"testing"
8+
9+
"github.com/stretchr/testify/require"
10+
"go.opentelemetry.io/otel/attribute"
11+
"go.uber.org/zap"
12+
"go.uber.org/zap/zapcore"
13+
"go.uber.org/zap/zaptest/observer"
14+
15+
"go.opentelemetry.io/collector/component/componentattribute"
16+
"go.opentelemetry.io/collector/pipeline"
17+
)
18+
19+
type loggerCore interface {
20+
Without(fields ...string) zapcore.Core
21+
}
22+
23+
func TestCore(t *testing.T) {
24+
core, observed := observer.New(zap.DebugLevel)
25+
logger := zap.New(core).With(zap.String("preexisting", "value"))
26+
27+
attrs := attribute.NewSet(
28+
attribute.String(componentattribute.SignalKey, pipeline.SignalLogs.String()),
29+
attribute.String(componentattribute.ComponentIDKey, "filelog"),
30+
)
31+
32+
parent := componentattribute.NewLogger(logger, &attrs)
33+
parent.Info("test parent before child")
34+
childCore := parent.Core().(loggerCore).Without(string(componentattribute.SignalKey))
35+
child := zap.New(childCore)
36+
child.Info("test child")
37+
parent.Info("test parent after child")
38+
39+
observedLogs := observed.All()
40+
require.Len(t, observedLogs, 3)
41+
42+
parentContext := map[string]string{
43+
"preexisting": "value",
44+
componentattribute.SignalKey: pipeline.SignalLogs.String(),
45+
componentattribute.ComponentIDKey: "filelog",
46+
}
47+
childContext := map[string]string{
48+
"preexisting": "value",
49+
componentattribute.ComponentIDKey: "filelog",
50+
}
51+
52+
require.Equal(t, "test parent before child", observedLogs[0].Message)
53+
require.Len(t, observedLogs[0].Context, len(parentContext))
54+
for _, field := range observedLogs[0].Context {
55+
require.Equal(t, parentContext[field.Key], field.String)
56+
}
57+
58+
require.Equal(t, "test child", observedLogs[1].Message)
59+
require.Len(t, observedLogs[1].Context, len(childContext))
60+
for _, field := range observedLogs[1].Context {
61+
require.Equal(t, childContext[field.Key], field.String)
62+
}
63+
64+
require.Equal(t, "test parent after child", observedLogs[2].Message)
65+
require.Len(t, observedLogs[2].Context, len(parentContext))
66+
for _, field := range observedLogs[2].Context {
67+
require.Equal(t, parentContext[field.Key], field.String)
68+
}
69+
}

component/telemetry.go

+15
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"go.opentelemetry.io/otel/metric"
88
"go.opentelemetry.io/otel/trace"
99
"go.uber.org/zap"
10+
"go.uber.org/zap/zapcore"
1011

1112
"go.opentelemetry.io/collector/pdata/pcommon"
1213
)
@@ -26,3 +27,17 @@ type TelemetrySettings struct {
2627
// Resource contains the resource attributes for the collector's telemetry.
2728
Resource pcommon.Resource
2829
}
30+
31+
func (ts *TelemetrySettings) LoggerWithout(fields ...string) *zap.Logger {
32+
type coreWithout interface {
33+
Without(fields ...string) zapcore.Core
34+
}
35+
if _, ok := ts.Logger.Core().(coreWithout); !ok {
36+
return ts.Logger
37+
}
38+
return ts.Logger.WithOptions(
39+
zap.WrapCore(func(from zapcore.Core) zapcore.Core {
40+
return from.(coreWithout).Without(fields...)
41+
}),
42+
)
43+
}

internal/e2e/go.mod

+3
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ require (
8080
github.com/yusufpapurcu/wmi v1.2.4 // indirect
8181
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
8282
go.opentelemetry.io/collector/client v1.25.0 // indirect
83+
go.opentelemetry.io/collector/component/componentattribute v0.119.0 // indirect
8384
go.opentelemetry.io/collector/config/configauth v0.119.0 // indirect
8485
go.opentelemetry.io/collector/config/configcompression v1.25.0 // indirect
8586
go.opentelemetry.io/collector/connector/xconnector v0.119.0 // indirect
@@ -244,3 +245,5 @@ replace go.opentelemetry.io/collector/extension/extensiontest => ../../extension
244245
replace go.opentelemetry.io/collector/extension/auth/authtest => ../../extension/auth/authtest
245246

246247
replace go.opentelemetry.io/collector/extension/xextension => ../../extension/xextension
248+
249+
replace go.opentelemetry.io/collector/component/componentattribute => ../../component/componentattribute

otelcol/go.mod

+3
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ require (
7171
github.com/tklauser/numcpus v0.6.1 // indirect
7272
github.com/yusufpapurcu/wmi v1.2.4 // indirect
7373
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
74+
go.opentelemetry.io/collector/component/componentattribute v0.119.0 // indirect
7475
go.opentelemetry.io/collector/component/componenttest v0.119.0 // indirect
7576
go.opentelemetry.io/collector/connector/xconnector v0.119.0 // indirect
7677
go.opentelemetry.io/collector/consumer v1.25.0 // indirect
@@ -207,3 +208,5 @@ replace go.opentelemetry.io/collector/extension/extensiontest => ../extension/ex
207208
replace go.opentelemetry.io/collector/extension/auth/authtest => ../extension/auth/authtest
208209

209210
replace go.opentelemetry.io/collector/extension/xextension => ../extension/xextension
211+
212+
replace go.opentelemetry.io/collector/component/componentattribute => ../component/componentattribute

otelcol/otelcoltest/go.mod

+3
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ require (
6666
github.com/tklauser/numcpus v0.6.1 // indirect
6767
github.com/yusufpapurcu/wmi v1.2.4 // indirect
6868
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
69+
go.opentelemetry.io/collector/component/componentattribute v0.119.0 // indirect
6970
go.opentelemetry.io/collector/component/componentstatus v0.119.0 // indirect
7071
go.opentelemetry.io/collector/component/componenttest v0.119.0 // indirect
7172
go.opentelemetry.io/collector/config/configtelemetry v0.119.0 // indirect
@@ -222,3 +223,5 @@ replace go.opentelemetry.io/collector/confmap/xconfmap => ../../confmap/xconfmap
222223
replace go.opentelemetry.io/collector/processor/processortest => ../../processor/processortest
223224

224225
replace go.opentelemetry.io/collector/pdata/testdata => ../../pdata/testdata
226+
227+
replace go.opentelemetry.io/collector/component/componentattribute => ../../component/componentattribute

0 commit comments

Comments
 (0)