Skip to content

Commit 2c264fe

Browse files
Fix otel extension status reporting (#8696) (#10198)
* Fix otel extension status reporting * Explicitly handle errors from otel status id parsing (cherry picked from commit de39cae) Co-authored-by: Mikołaj Świątek <mail@mikolajswiatek.com>
1 parent 27f4202 commit 2c264fe

File tree

2 files changed

+64
-16
lines changed

2 files changed

+64
-16
lines changed

internal/pkg/otel/translate/status.go

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,13 @@ func DropComponentStateFromOtelStatus(otelStatus *status.AggregateStatus) (*stat
6464
newStatus := deepCopyStatus(otelStatus)
6565
for pipelineStatusId := range newStatus.ComponentStatusMap {
6666
pipelineId := &pipeline.ID{}
67-
componentKind, pipelineIdStr := parseEntityStatusId(pipelineStatusId)
67+
componentKind, pipelineIdStr, parseErr := parseEntityStatusId(pipelineStatusId)
68+
if parseErr != nil {
69+
return nil, parseErr
70+
}
71+
if componentKind == "extensions" {
72+
continue
73+
}
6874
if componentKind != "pipeline" {
6975
return nil, fmt.Errorf("pipeline status id %s is not a pipeline", pipelineStatusId)
7076
}
@@ -91,7 +97,13 @@ func getOtelRuntimePipelineStatuses(otelStatus *status.AggregateStatus) (map[str
9197

9298
for pipelineStatusId, pipelineStatus := range otelStatus.ComponentStatusMap {
9399
pipelineId := &pipeline.ID{}
94-
componentKind, pipelineIdStr := parseEntityStatusId(pipelineStatusId)
100+
componentKind, pipelineIdStr, parseErr := parseEntityStatusId(pipelineStatusId)
101+
if parseErr != nil {
102+
return nil, parseErr
103+
}
104+
if componentKind == "extensions" {
105+
continue
106+
}
95107
if componentKind != "pipeline" {
96108
return nil, fmt.Errorf("pipeline status id %s is not a pipeline", pipelineStatusId)
97109
}
@@ -176,8 +188,11 @@ func getUnitOtelStatuses(pipelineStatus *status.AggregateStatus) (
176188

177189
for otelCompStatusId, otelCompStatus := range pipelineStatus.ComponentStatusMap {
178190
var otelComponentID otelcomponent.ID
179-
componentKind, otelComponentIDStr := parseEntityStatusId(otelCompStatusId)
180-
err := otelComponentID.UnmarshalText([]byte(otelComponentIDStr))
191+
componentKind, otelComponentIDStr, parseErr := parseEntityStatusId(otelCompStatusId)
192+
if parseErr != nil {
193+
return nil, nil, parseErr
194+
}
195+
err = otelComponentID.UnmarshalText([]byte(otelComponentIDStr))
181196
if err != nil {
182197
return nil, nil, err
183198
}
@@ -267,13 +282,17 @@ func otelStatusToUnitState(status componentstatus.Status) client.UnitState {
267282

268283
// parseEntityStatusId parses an entity status ID into its kind and entity ID. An entity can be a pipeline or otel component.
269284
// The ID is expected to be in the format "kind:entityId", where kind is either "pipeline" or the otel component type (e.g., "receiver", "exporter").
285+
// The returned entityId may be empty - this is true for the top-level "extensions" key.
270286
// This format is used by the healthcheckv2 extension.
271-
func parseEntityStatusId(id string) (kind string, entityId string) {
287+
func parseEntityStatusId(id string) (kind string, entityId string, err error) {
288+
if id == "extensions" {
289+
return "extensions", "", nil
290+
}
272291
parts := strings.SplitN(id, ":", 2)
273292
if len(parts) != 2 {
274-
return "", ""
293+
return "", "", fmt.Errorf("couldn't parse otel status id: %s", id)
275294
}
276-
return parts[0], parts[1]
295+
return parts[0], parts[1], nil
277296
}
278297

279298
// deepCopyStatus makes a deep copy of the status.

internal/pkg/otel/translate/status_test.go

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func TestGetAllComponentState(t *testing.T) {
7878
},
7979
},
8080
},
81-
expectedErr: fmt.Errorf("pipeline status id %s is not a pipeline", fmt.Sprintf("logs/%sfilestream-default", OtelNamePrefix)),
81+
expectedErr: fmt.Errorf("couldn't parse otel status id: %s", fmt.Sprintf("logs/%sfilestream-default", OtelNamePrefix)),
8282
},
8383
{
8484
name: "one otel component, one process component",
@@ -213,7 +213,20 @@ func TestDropComponentStateFromOtelStatus(t *testing.T) {
213213
s, err := DropComponentStateFromOtelStatus(otelStatus)
214214
require.Error(t, err)
215215
require.Nil(t, s)
216-
assert.Equal(t, "pipeline status id logs is not a pipeline", err.Error())
216+
assert.Equal(t, "couldn't parse otel status id: logs", err.Error())
217+
})
218+
219+
t.Run("ignore extensions", func(t *testing.T) {
220+
otelStatus := &status.AggregateStatus{
221+
ComponentStatusMap: map[string]*status.AggregateStatus{
222+
"extensions": {
223+
Event: componentstatus.NewEvent(componentstatus.StatusOK),
224+
},
225+
},
226+
}
227+
s, err := DropComponentStateFromOtelStatus(otelStatus)
228+
require.NoError(t, err)
229+
assert.Equal(t, otelStatus, s)
217230
})
218231
}
219232

@@ -262,7 +275,19 @@ func TestGetOtelRuntimePipelineStatuses(t *testing.T) {
262275
},
263276
},
264277
expected: nil,
265-
err: "pipeline status id invalid-format is not a pipeline",
278+
err: "couldn't parse otel status id: invalid-format",
279+
},
280+
{
281+
name: "extensions are ignored",
282+
status: &status.AggregateStatus{
283+
Event: componentstatus.NewEvent(componentstatus.StatusOK),
284+
ComponentStatusMap: map[string]*status.AggregateStatus{
285+
"extensions": {
286+
Event: componentstatus.NewEvent(componentstatus.StatusOK),
287+
},
288+
},
289+
},
290+
expected: map[string]*status.AggregateStatus{},
266291
},
267292
}
268293

@@ -487,16 +512,20 @@ func TestParseEntityStatusId(t *testing.T) {
487512
id string
488513
expectedKind string
489514
expectedEntityID string
515+
expectedErr error
490516
}{
491-
{"pipeline:logs", "pipeline", "logs"},
492-
{"pipeline:logs/filestream-monitoring", "pipeline", "logs/filestream-monitoring"},
493-
{"receiver:filebeat/filestream-monitoring", "receiver", "filebeat/filestream-monitoring"},
494-
{"exporter:elasticsearch/default", "exporter", "elasticsearch/default"},
495-
{"invalid", "", ""},
517+
{"pipeline:logs", "pipeline", "logs", nil},
518+
{"pipeline:logs/filestream-monitoring", "pipeline", "logs/filestream-monitoring", nil},
519+
{"receiver:filebeat/filestream-monitoring", "receiver", "filebeat/filestream-monitoring", nil},
520+
{"exporter:elasticsearch/default", "exporter", "elasticsearch/default", nil},
521+
{"invalid", "", "", fmt.Errorf("couldn't parse otel status id: %s", "invalid")},
522+
{"", "", "", fmt.Errorf("couldn't parse otel status id: %s", "")},
523+
{"extensions", "extensions", "", nil},
496524
}
497525

498526
for _, test := range tests {
499-
componentKind, pipelineId := parseEntityStatusId(test.id)
527+
componentKind, pipelineId, err := parseEntityStatusId(test.id)
528+
assert.Equal(t, test.expectedErr, err)
500529
assert.Equal(t, test.expectedKind, componentKind, "component kind")
501530
assert.Equal(t, test.expectedEntityID, pipelineId, "pipeline id")
502531
}

0 commit comments

Comments
 (0)