Skip to content

Commit 84bea87

Browse files
authored
[receiver/otlpjsonfile][bugfix] only add attributes if record/span/metric count is greater than 0 (#38354)
<!--Ex. Fixing a bug - Describe the bug and how this fixes the issue. Ex. Adding a feature - Explain what this achieves.--> #### Description Fix nil pointer dereference due to empty token <!-- Issue number (e.g. #1234) or full URL to issue, if applicable. --> #### Link to tracking issue Fixes #38289 <!--Describe what testing was performed and which tests were added.--> #### Testing Added test which fails without the fix in place.
1 parent 3bbabb0 commit 84bea87

File tree

3 files changed

+113
-33
lines changed

3 files changed

+113
-33
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. filelogreceiver)
7+
component: otlpjsonfilereceiver
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Fix nil pointer dereference due to empty token
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [38289]
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+
# If your change doesn't affect end users or the exported elements of any package,
21+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
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: []

receiver/otlpjsonfilereceiver/file.go

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -88,22 +88,22 @@ func createLogsReceiver(_ context.Context, settings receiver.Settings, configura
8888
ctx = obsrecv.StartLogsOp(ctx)
8989
var l plog.Logs
9090
l, err = logsUnmarshaler.UnmarshalLogs(token)
91-
// Appends token.Attributes
92-
for i := 0; i < l.ResourceLogs().Len(); i++ {
93-
resourceLog := l.ResourceLogs().At(i)
94-
for j := 0; j < resourceLog.ScopeLogs().Len(); j++ {
95-
scopeLog := resourceLog.ScopeLogs().At(j)
96-
for k := 0; k < scopeLog.LogRecords().Len(); k++ {
97-
LogRecords := scopeLog.LogRecords().At(k)
98-
appendToMap(attributes, LogRecords.Attributes())
99-
}
100-
}
101-
}
10291
if err != nil {
10392
obsrecv.EndLogsOp(ctx, metadata.Type.String(), 0, err)
10493
} else {
10594
logRecordCount := l.LogRecordCount()
10695
if logRecordCount != 0 {
96+
// Appends token.Attributes
97+
for i := 0; i < l.ResourceLogs().Len(); i++ {
98+
resourceLog := l.ResourceLogs().At(i)
99+
for j := 0; j < resourceLog.ScopeLogs().Len(); j++ {
100+
scopeLog := resourceLog.ScopeLogs().At(j)
101+
for k := 0; k < scopeLog.LogRecords().Len(); k++ {
102+
LogRecords := scopeLog.LogRecords().At(k)
103+
appendToMap(attributes, LogRecords.Attributes())
104+
}
105+
}
106+
}
107107
err = logs.ConsumeLogs(ctx, l)
108108
}
109109
obsrecv.EndLogsOp(ctx, metadata.Type.String(), logRecordCount, err)
@@ -138,21 +138,21 @@ func createMetricsReceiver(_ context.Context, settings receiver.Settings, config
138138
ctx = obsrecv.StartMetricsOp(ctx)
139139
var m pmetric.Metrics
140140
m, err = metricsUnmarshaler.UnmarshalMetrics(token)
141-
// Appends token.Attributes
142-
for i := 0; i < m.ResourceMetrics().Len(); i++ {
143-
resourceMetric := m.ResourceMetrics().At(i)
144-
for j := 0; j < resourceMetric.ScopeMetrics().Len(); j++ {
145-
ScopeMetric := resourceMetric.ScopeMetrics().At(j)
146-
for k := 0; k < ScopeMetric.Metrics().Len(); k++ {
147-
metric := ScopeMetric.Metrics().At(k)
148-
appendToMap(attributes, metric.Metadata())
149-
}
150-
}
151-
}
152141
if err != nil {
153142
obsrecv.EndMetricsOp(ctx, metadata.Type.String(), 0, err)
154143
} else {
155144
if m.ResourceMetrics().Len() != 0 {
145+
// Appends token.Attributes
146+
for i := 0; i < m.ResourceMetrics().Len(); i++ {
147+
resourceMetric := m.ResourceMetrics().At(i)
148+
for j := 0; j < resourceMetric.ScopeMetrics().Len(); j++ {
149+
ScopeMetric := resourceMetric.ScopeMetrics().At(j)
150+
for k := 0; k < ScopeMetric.Metrics().Len(); k++ {
151+
metric := ScopeMetric.Metrics().At(k)
152+
appendToMap(attributes, metric.Metadata())
153+
}
154+
}
155+
}
156156
err = metrics.ConsumeMetrics(ctx, m)
157157
}
158158
obsrecv.EndMetricsOp(ctx, metadata.Type.String(), m.MetricCount(), err)
@@ -187,21 +187,21 @@ func createTracesReceiver(_ context.Context, settings receiver.Settings, configu
187187
ctx = obsrecv.StartTracesOp(ctx)
188188
var t ptrace.Traces
189189
t, err = tracesUnmarshaler.UnmarshalTraces(token)
190-
// Appends token.Attributes
191-
for i := 0; i < t.ResourceSpans().Len(); i++ {
192-
resourceSpan := t.ResourceSpans().At(i)
193-
for j := 0; j < resourceSpan.ScopeSpans().Len(); j++ {
194-
scopeSpan := resourceSpan.ScopeSpans().At(j)
195-
for k := 0; k < scopeSpan.Spans().Len(); k++ {
196-
spans := scopeSpan.Spans().At(k)
197-
appendToMap(attributes, spans.Attributes())
198-
}
199-
}
200-
}
201190
if err != nil {
202191
obsrecv.EndTracesOp(ctx, metadata.Type.String(), 0, err)
203192
} else {
204193
if t.ResourceSpans().Len() != 0 {
194+
// Appends token.Attributes
195+
for i := 0; i < t.ResourceSpans().Len(); i++ {
196+
resourceSpan := t.ResourceSpans().At(i)
197+
for j := 0; j < resourceSpan.ScopeSpans().Len(); j++ {
198+
scopeSpan := resourceSpan.ScopeSpans().At(j)
199+
for k := 0; k < scopeSpan.Spans().Len(); k++ {
200+
spans := scopeSpan.Spans().At(k)
201+
appendToMap(attributes, spans.Attributes())
202+
}
203+
}
204+
}
205205
err = traces.ConsumeTraces(ctx, t)
206206
}
207207
obsrecv.EndTracesOp(ctx, metadata.Type.String(), t.SpanCount(), err)

receiver/otlpjsonfilereceiver/file_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,3 +304,56 @@ func TestFileMixedSignals(t *testing.T) {
304304
err = pr.Shutdown(context.Background())
305305
assert.NoError(t, err)
306306
}
307+
308+
func TestEmptyLine(t *testing.T) {
309+
tempFolder := t.TempDir()
310+
factory := NewFactory()
311+
cfg := createDefaultConfig().(*Config)
312+
cfg.Config.Include = []string{filepath.Join(tempFolder, "*")}
313+
cfg.Config.StartAt = "beginning"
314+
cs := receivertest.NewNopSettings(metadata.Type)
315+
t.Run("metrics receiver", func(t *testing.T) {
316+
ms := new(consumertest.MetricsSink)
317+
mr, err := factory.CreateMetrics(context.Background(), cs, cfg, ms)
318+
assert.NoError(t, err)
319+
err = mr.Start(context.Background(), nil)
320+
assert.NoError(t, err)
321+
defer func() {
322+
assert.NoError(t, mr.Shutdown(context.Background()))
323+
}()
324+
err = os.WriteFile(filepath.Join(tempFolder, "metrics.json"), []byte{'\n', '\n'}, 0o600)
325+
assert.NoError(t, err)
326+
time.Sleep(1 * time.Second)
327+
require.Empty(t, ms.AllMetrics())
328+
})
329+
330+
t.Run("trace receiver", func(t *testing.T) {
331+
ts := new(consumertest.TracesSink)
332+
tr, err := factory.CreateTraces(context.Background(), cs, cfg, ts)
333+
assert.NoError(t, err)
334+
err = tr.Start(context.Background(), nil)
335+
assert.NoError(t, err)
336+
defer func() {
337+
assert.NoError(t, tr.Shutdown(context.Background()))
338+
}()
339+
err = os.WriteFile(filepath.Join(tempFolder, "traces.json"), []byte{'\n', '\n'}, 0o600)
340+
assert.NoError(t, err)
341+
time.Sleep(1 * time.Second)
342+
require.Empty(t, ts.AllTraces())
343+
})
344+
345+
t.Run("log receiver", func(t *testing.T) {
346+
ls := new(consumertest.LogsSink)
347+
lr, err := factory.CreateLogs(context.Background(), cs, cfg, ls)
348+
assert.NoError(t, err)
349+
err = lr.Start(context.Background(), nil)
350+
assert.NoError(t, err)
351+
defer func() {
352+
assert.NoError(t, lr.Shutdown(context.Background()))
353+
}()
354+
err = os.WriteFile(filepath.Join(tempFolder, "logs.json"), []byte{'\n', '\n'}, 0o600)
355+
assert.NoError(t, err)
356+
time.Sleep(1 * time.Second)
357+
require.Empty(t, ls.AllLogs())
358+
})
359+
}

0 commit comments

Comments
 (0)