Skip to content

Commit b95cc76

Browse files
authored
[beatreceiver] fix status reporting (#47936) (#48098)
* [beatreceiver] fix status reporting
1 parent 122e532 commit b95cc76

3 files changed

Lines changed: 40 additions & 8 deletions

File tree

x-pack/libbeat/cmd/instance/receiver.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ import (
1616
"github.com/elastic/beats/v7/libbeat/cfgfile"
1717
"github.com/elastic/beats/v7/libbeat/cmd/instance"
1818
"github.com/elastic/beats/v7/libbeat/common/backoff"
19+
"github.com/elastic/beats/v7/libbeat/management/status"
1920
"github.com/elastic/beats/v7/x-pack/libbeat/common/otelbeat/otelmanager"
20-
"github.com/elastic/beats/v7/x-pack/libbeat/common/otelbeat/status"
21+
otelstatus "github.com/elastic/beats/v7/x-pack/libbeat/common/otelbeat/status"
2122
_ "github.com/elastic/beats/v7/x-pack/libbeat/include"
2223
"github.com/elastic/elastic-agent-libs/logp"
2324
"github.com/elastic/elastic-agent-libs/monitoring"
@@ -96,9 +97,10 @@ func NewBeatReceiver(ctx context.Context, b *instance.Beat, creator beat.Creator
9697

9798
// BeatReceiver.Start() starts the beat receiver.
9899
func (br *BeatReceiver) Start(host component.Host) error {
100+
var groupReporter otelstatus.RunnerReporter
99101
if w, ok := br.beater.(cfgfile.WithOtelFactoryWrapper); ok {
100-
groupReporter := status.NewGroupStatusReporter(host)
101-
w.WithOtelFactoryWrapper(status.StatusReporterFactory(groupReporter))
102+
groupReporter = otelstatus.NewGroupStatusReporter(host)
103+
w.WithOtelFactoryWrapper(otelstatus.StatusReporterFactory(groupReporter))
102104
}
103105

104106
// We go through all extensions to find any that implement the DiagnosticExtension interface.
@@ -126,6 +128,8 @@ func (br *BeatReceiver) Start(host component.Host) error {
126128
}
127129

128130
if err := br.beater.Run(&br.beat.Beat); err != nil {
131+
// set beatreceiver status
132+
groupReporter.UpdateStatus(status.Failed, err.Error())
129133
return fmt.Errorf("beat receiver run error: %w", err)
130134
}
131135

x-pack/libbeat/common/otelbeat/status/reporter.go

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ func toPdata(r *runnerState) pcommon.Map {
3636
// This is used for grouping and managing statuses of multiple runners
3737
type RunnerReporter interface {
3838
GetReporterForRunner(id string) status.StatusReporter
39+
40+
// UpdateStatus updates the group status of a runnerReporter
41+
UpdateStatus(status status.Status, msg string)
3942
}
4043

4144
type reporter struct {
@@ -81,22 +84,40 @@ func (r *reporter) updateStatusForRunner(id string, state status.Status, msg str
8184
}
8285
}
8386

84-
// report status to parent reporter
85-
r.UpdateStatus()
87+
// report aggregated status for all sub-components
88+
evt := r.calculateOtelStatus()
89+
r.emitDummyStatus(evt)
90+
componentstatus.ReportStatus(r.host, evt)
8691
}
8792

88-
func (r *reporter) UpdateStatus() {
89-
evt := r.calculateOtelStatus()
93+
// UpdateStatus reports the overall status of the group.
94+
// This is useful to report any failures encountered before a runner is initialized.
95+
// Note: This will override all sub-reporter statuses if any
96+
func (r *reporter) UpdateStatus(status status.Status, msg string) {
97+
otelStatus := beatStatusToOtelStatus(status)
98+
if otelStatus == componentstatus.StatusNone {
99+
return
100+
}
101+
var eventBuilderOpts []componentstatus.EventBuilderOption
102+
if componentstatus.StatusIsError(otelStatus) {
103+
eventBuilderOpts = append(eventBuilderOpts, componentstatus.WithError(errors.New(msg)))
104+
}
105+
evt := componentstatus.NewEvent(otelStatus, eventBuilderOpts...)
106+
r.emitDummyStatus(evt)
107+
componentstatus.ReportStatus(r.host, evt)
108+
}
109+
110+
func (r *reporter) emitDummyStatus(evt *componentstatus.Event) {
90111
oppositeStatus := getOppositeStatus(evt.Status())
91112
if oppositeStatus != componentstatus.StatusNone {
92113
// emit a dummy event first to ensure the otel core framework acknowledges the change
93114
// workaround for https://github.com/open-telemetry/opentelemetry-collector/issues/14282
94115
dummyEvt := componentstatus.NewEvent(oppositeStatus)
95116
componentstatus.ReportStatus(r.host, dummyEvt)
96117
}
97-
componentstatus.ReportStatus(r.host, evt)
98118
}
99119

120+
// calculateOtelStatus aggregates the statuses of all runners
100121
func (r *reporter) calculateOtelStatus() *componentstatus.Event {
101122
var evt *componentstatus.Event
102123
s, msg := r.calculateAggregateState()

x-pack/libbeat/common/otelbeat/status/reporter_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ func TestGroupStatus(t *testing.T) {
4040
require.Equalf(t, m.Evt.Status(), componentstatus.StatusPermanentError, "expected StatusPermanentError, got %v", m.Evt.Status())
4141
require.NotNil(t, m.Evt.Err(), "expected non-nil error, got nil")
4242
require.Equalf(t, m.Evt.Err().Error(), "Failed Runner2", "expected 'Failed Runner1', got %v", m.Evt.Err())
43+
44+
// group reporter is updated directly
45+
reporter.UpdateStatus(status.Failed, "beatreceiver failed to start")
46+
47+
require.Equalf(t, m.Evt.Status(), componentstatus.StatusPermanentError, "expected StatusPermanentError, got %v", m.Evt.Status())
48+
require.NotNil(t, m.Evt.Err(), "expected non-nil error, got nil")
49+
require.Equalf(t, m.Evt.Err().Error(), "beatreceiver failed to start", "expected 'beatreceiver failed to start', got %v", m.Evt.Err())
4350
}
4451

4552
func TestToPdata(t *testing.T) {

0 commit comments

Comments
 (0)