Skip to content

Commit 628d9a3

Browse files
committed
Propagate telemetry.resource to the internal logs. open-telemetry#12582
Signed-off-by: Israel Blancas <[email protected]>
1 parent 8cf42f3 commit 628d9a3

File tree

3 files changed

+161
-15
lines changed

3 files changed

+161
-15
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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: "internal telemetry"
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: "Add resource attributes from telemetry.resource to the logger"
11+
12+
# One or more tracking issues or pull requests related to the change
13+
issues: [12582]
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+
Resource attributes from telemetry.resource were not added to the internal
20+
logs but to metrics and traces. This fix ensures they are added to the logs.
21+
22+
# Optional: The change log or logs in which this entry should be included.
23+
# e.g. '[user]' or '[user, api]'
24+
# Include 'user' if the change is relevant to end users.
25+
# Include 'api' if there is a change to a library API.
26+
# Default: '[user]'
27+
change_logs: []

service/telemetry/logger.go

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,23 +37,34 @@ func newLogger(set Settings, cfg Config) (*zap.Logger, log.LoggerProvider, error
3737
return nil, nil, err
3838
}
3939

40+
fields := []zap.Field{}
41+
for k, v := range cfg.Resource {
42+
if v != nil {
43+
f := zap.Field{Key: k, Type: zapcore.StringType, String: *v}
44+
fields = append(fields, f)
45+
}
46+
}
47+
4048
var lp log.LoggerProvider
4149

4250
if len(cfg.Logs.Processors) > 0 && set.SDK != nil {
4351
lp = set.SDK.LoggerProvider()
4452

45-
logger = logger.WithOptions(zap.WrapCore(func(c zapcore.Core) zapcore.Core {
46-
core, err := zapcore.NewIncreaseLevelCore(zapcore.NewTee(
47-
c,
48-
otelzap.NewCore("go.opentelemetry.io/collector/service/telemetry",
49-
otelzap.WithLoggerProvider(lp),
50-
),
51-
), zap.NewAtomicLevelAt(cfg.Logs.Level))
52-
if err != nil {
53-
panic(err)
54-
}
55-
return core
56-
}))
53+
logger = logger.WithOptions(
54+
zap.WrapCore(func(c zapcore.Core) zapcore.Core {
55+
core, err := zapcore.NewIncreaseLevelCore(zapcore.NewTee(
56+
c,
57+
otelzap.NewCore("go.opentelemetry.io/collector/service/telemetry",
58+
otelzap.WithLoggerProvider(lp),
59+
),
60+
), zap.NewAtomicLevelAt(cfg.Logs.Level))
61+
if err != nil {
62+
panic(err)
63+
}
64+
return core
65+
}),
66+
zap.Fields(fields...),
67+
)
5768
}
5869

5970
if cfg.Logs.Sampling != nil && cfg.Logs.Sampling.Enabled {

service/telemetry/logger_test.go

Lines changed: 111 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,19 @@ package telemetry // import "go.opentelemetry.io/collector/service/telemetry"
66
import (
77
"context"
88
"errors"
9+
"io"
10+
"net/http"
11+
"net/http/httptest"
912
"reflect"
1013
"testing"
1114

15+
"github.com/stretchr/testify/assert"
1216
"github.com/stretchr/testify/require"
1317
config "go.opentelemetry.io/contrib/otelconf/v0.3.0"
1418
"go.uber.org/zap/zapcore"
19+
20+
"go.opentelemetry.io/collector/pdata/plog/plogotlp"
21+
semconv "go.opentelemetry.io/collector/semconv/v1.18.0"
1522
)
1623

1724
func TestNewLogger(t *testing.T) {
@@ -79,13 +86,114 @@ func TestNewLogger(t *testing.T) {
7986
require.NoError(t, err)
8087
gotType := reflect.TypeOf(l.Core()).String()
8188
require.Equal(t, tt.wantCoreType, gotType)
82-
type shutdownable interface {
83-
Shutdown(context.Context) error
84-
}
8589
if prov, ok := lp.(shutdownable); ok {
8690
require.NoError(t, prov.Shutdown(context.Background()))
8791
}
8892
}
8993
})
9094
}
9195
}
96+
97+
func TestOTELZapIntegration(t *testing.T) {
98+
version := "1.2.3"
99+
service := "test-service"
100+
testAttribute := "test-attribute"
101+
102+
receivedLogs := 0
103+
totalLogs := 10
104+
105+
// Create a backend to receive the logs and assert the content
106+
srv := createBackend("/v1/logs", func(writer http.ResponseWriter, request *http.Request) {
107+
body, err := io.ReadAll(request.Body)
108+
require.NoError(t, err)
109+
defer request.Body.Close()
110+
111+
// Unmarshal the protobuf body into logs
112+
req := plogotlp.NewExportRequest()
113+
err = req.UnmarshalProto(body)
114+
require.NoError(t, err)
115+
116+
logs := req.Logs()
117+
rl := logs.ResourceLogs().At(0)
118+
sl := rl.ScopeLogs().At(0)
119+
logRecord := sl.LogRecords().At(0)
120+
attrs := logRecord.Attributes().AsRaw()
121+
122+
assert.Contains(t, attrs, semconv.AttributeServiceName)
123+
assert.Contains(t, attrs, semconv.AttributeServiceVersion)
124+
assert.Contains(t, attrs, testAttribute)
125+
receivedLogs++
126+
127+
writer.WriteHeader(http.StatusOK)
128+
})
129+
defer srv.Close()
130+
131+
processors := []config.LogRecordProcessor{
132+
{
133+
Simple: &config.SimpleLogRecordProcessor{
134+
Exporter: config.LogRecordExporter{
135+
OTLP: &config.OTLP{
136+
Endpoint: ptr(srv.URL),
137+
Protocol: ptr("http/protobuf"),
138+
Insecure: ptr(true),
139+
},
140+
},
141+
},
142+
},
143+
}
144+
145+
sdk, _ := config.NewSDK(
146+
config.WithOpenTelemetryConfiguration(
147+
config.OpenTelemetryConfiguration{
148+
LoggerProvider: &config.LoggerProvider{
149+
Processors: processors,
150+
},
151+
},
152+
),
153+
)
154+
155+
cfg := Config{
156+
Logs: LogsConfig{
157+
Level: zapcore.DebugLevel,
158+
Development: true,
159+
Encoding: "json",
160+
Processors: processors,
161+
},
162+
Resource: map[string]*string{
163+
semconv.AttributeServiceName: ptr(service),
164+
semconv.AttributeServiceVersion: ptr(version),
165+
testAttribute: ptr("test-value"),
166+
},
167+
}
168+
l, lp, err := newLogger(Settings{SDK: &sdk}, cfg)
169+
require.NoError(t, err)
170+
require.NotNil(t, l)
171+
require.NotNil(t, lp)
172+
173+
defer func() {
174+
if prov, ok := lp.(shutdownable); ok {
175+
require.NoError(t, prov.Shutdown(context.Background()))
176+
}
177+
}()
178+
179+
// Generate some logs to send to the backend
180+
for i := 0; i < totalLogs; i++ {
181+
l.Info("Test log message")
182+
}
183+
184+
// Ensure the correct number of logs were received
185+
assert.Equal(t, totalLogs, receivedLogs)
186+
}
187+
188+
type shutdownable interface {
189+
Shutdown(context.Context) error
190+
}
191+
192+
func createBackend(endpoint string, handler func(writer http.ResponseWriter, request *http.Request)) *httptest.Server {
193+
mux := http.NewServeMux()
194+
mux.HandleFunc(endpoint, handler)
195+
196+
srv := httptest.NewServer(mux)
197+
198+
return srv
199+
}

0 commit comments

Comments
 (0)