Skip to content

Commit 3dbff30

Browse files
committed
Log warning about switching to process runtime for monitoring
1 parent f05ad55 commit 3dbff30

File tree

5 files changed

+57
-18
lines changed

5 files changed

+57
-18
lines changed

internal/pkg/agent/application/application.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ func New(
149149
cfg.Settings.DownloadConfig.OS(),
150150
cfg.Settings.MonitoringConfig,
151151
agentInfo,
152+
log,
152153
)
153154

154155
runtime, err := runtime.NewManager(

internal/pkg/agent/application/monitoring/component/v1_monitor.go

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ type BeatsMonitor struct {
104104
config *monitoringConfig
105105
operatingSystem string
106106
agentInfo info.Agent
107+
logger *logp.Logger
107108
}
108109

109110
// componentInfo is the information necessary to generate monitoring configuration for a component. We don't just use
@@ -122,14 +123,21 @@ type monitoringConfig struct {
122123
}
123124

124125
// New creates a new BeatsMonitor instance.
125-
func New(enabled bool, operatingSystem string, cfg *monitoringCfg.MonitoringConfig, agentInfo info.Agent) *BeatsMonitor {
126+
func New(
127+
enabled bool,
128+
operatingSystem string,
129+
cfg *monitoringCfg.MonitoringConfig,
130+
agentInfo info.Agent,
131+
logger *logp.Logger,
132+
) *BeatsMonitor {
126133
return &BeatsMonitor{
127134
enabled: enabled,
128135
config: &monitoringConfig{
129136
C: cfg,
130137
},
131138
operatingSystem: operatingSystem,
132139
agentInfo: agentInfo,
140+
logger: logger,
133141
}
134142
}
135143

@@ -242,11 +250,13 @@ func (b *BeatsMonitor) MonitoringConfig(
242250
return nil, nil
243251
}
244252

245-
outputOtelSupported := isOutputOtelSupported(outputCfg)
253+
outputOtelSupportedErr := verifyOutputOtelSupported(outputCfg)
246254
monitoringRuntime := component.RuntimeManager(b.config.C.RuntimeManager)
247-
if !outputOtelSupported {
255+
if outputOtelSupportedErr != nil {
256+
b.logger.Warnf("otel runtime is not supported for monitoring output, switching to process runtime, reason: %v", outputOtelSupportedErr)
248257
monitoringRuntime = monitoringCfg.ProcessRuntimeManager
249258
}
259+
outputOtelSupported := outputOtelSupportedErr == nil
250260
componentInfos := b.getComponentInfos(components, monitoringRuntime, outputOtelSupported, componentIDPidMap)
251261

252262
// initializes inputs collection so injectors don't have to deal with it
@@ -482,13 +492,18 @@ func (b *BeatsMonitor) getComponentInfos(
482492
}
483493
// If any other component uses the Otel runtime, also add a component to monitor its telemetry.
484494
// This component only works in the Otel runtime, so we can't add it if the output doesn't support it.
485-
if b.config.C.MonitorMetrics && usingOtelRuntime(componentInfos) && outputOtelSupported {
486-
componentInfos = append(componentInfos,
487-
componentInfo{
488-
ID: prometheusMonitoringComponentId,
489-
BinaryName: metricBeatName,
490-
RuntimeManager: component.OtelRuntimeManager,
491-
})
495+
if b.config.C.MonitorMetrics && usingOtelRuntime(componentInfos) {
496+
if outputOtelSupported {
497+
componentInfos = append(componentInfos,
498+
componentInfo{
499+
ID: prometheusMonitoringComponentId,
500+
BinaryName: metricBeatName,
501+
RuntimeManager: component.OtelRuntimeManager,
502+
})
503+
} else {
504+
b.logger.Warn("The Otel prometheus metrics monitoring input can't run in a beats process, skipping")
505+
}
506+
492507
}
493508
// sort the components to ensure a consistent order of inputs in the configuration
494509
slices.SortFunc(componentInfos, func(a, b componentInfo) int {
@@ -1525,14 +1540,13 @@ func isSupportedBeatsBinary(binaryName string) bool {
15251540
return false
15261541
}
15271542

1528-
func isOutputOtelSupported(outputCfg map[string]any) bool {
1543+
func verifyOutputOtelSupported(outputCfg map[string]any) error {
15291544
parsed, err := component.ParseOutput(monitoringOutput, outputCfg, logp.InfoLevel, nil)
15301545
if err != nil {
1531-
return false
1546+
return err
15321547
}
15331548

1534-
err = translate.VerifyOutputIsOtelSupported(parsed.OutputType, outputCfg)
1535-
return err == nil
1549+
return translate.VerifyOutputIsOtelSupported(parsed.OutputType, outputCfg)
15361550
}
15371551

15381552
func monitoringDrop(path string) (drop string) {

internal/pkg/agent/application/monitoring/component/v1_monitor_test.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import (
1717

1818
"github.com/go-viper/mapstructure/v2"
1919

20+
"github.com/elastic/elastic-agent-libs/logp"
21+
2022
"github.com/stretchr/testify/assert"
2123
"github.com/stretchr/testify/require"
2224
"gopkg.in/yaml.v2"
@@ -126,6 +128,7 @@ func TestMonitoringFull(t *testing.T) {
126128
},
127129
},
128130
agentInfo: agentInfo,
131+
logger: logp.NewNopLogger(),
129132
}
130133

131134
expectedConfigBytes, err := os.ReadFile(tc.ExpectedConfigPath)
@@ -176,6 +179,7 @@ func TestMonitoringWithEndpoint(t *testing.T) {
176179
},
177180
},
178181
agentInfo: agentInfo,
182+
logger: logp.NewNopLogger(),
179183
}
180184

181185
policy := map[string]any{
@@ -350,6 +354,7 @@ func TestMonitoringConfigMetricsInterval(t *testing.T) {
350354
config: tc.monitoringCfg,
351355
operatingSystem: runtime.GOOS,
352356
agentInfo: agentInfo,
357+
logger: logp.NewNopLogger(),
353358
}
354359
got, err := b.MonitoringConfig(tc.policy, components, map[string]uint64{}) // put a componentID/binary mapping to have something in the beats monitoring input
355360
assert.NoError(t, err)
@@ -583,6 +588,7 @@ func TestMonitoringConfigMetricsFailureThreshold(t *testing.T) {
583588
config: tc.monitoringCfg,
584589
operatingSystem: runtime.GOOS,
585590
agentInfo: agentInfo,
591+
logger: logp.NewNopLogger(),
586592
}
587593
got, err := b.MonitoringConfig(tc.policy, components, map[string]uint64{}) // put a componentID/binary mapping to have something in the beats monitoring input
588594
assert.NoError(t, err)
@@ -758,6 +764,7 @@ func TestErrorMonitoringConfigMetricsFailureThreshold(t *testing.T) {
758764
config: tc.monitoringCfg,
759765
operatingSystem: runtime.GOOS,
760766
agentInfo: agentInfo,
767+
logger: logp.NewNopLogger(),
761768
}
762769

763770
_, err := b.MonitoringConfig(tc.policy, components, map[string]uint64{}) // put a componentID/binary mapping to have something in the beats monitoring input
@@ -797,6 +804,7 @@ func TestMonitoringConfigComponentFields(t *testing.T) {
797804
enabled: true,
798805
config: cfg,
799806
agentInfo: agentInfo,
807+
logger: logp.NewNopLogger(),
800808
}
801809

802810
components := []component.Component{
@@ -907,6 +915,7 @@ func TestMonitoringConfigForBeatsReceivers(t *testing.T) {
907915
enabled: true,
908916
config: cfg,
909917
agentInfo: agentInfo,
918+
logger: logp.NewNopLogger(),
910919
}
911920

912921
components := []component.Component{
@@ -1005,6 +1014,7 @@ func TestMonitoringWithOtelRuntime(t *testing.T) {
10051014
enabled: true,
10061015
config: cfg,
10071016
agentInfo: agentInfo,
1017+
logger: logp.NewNopLogger(),
10081018
}
10091019

10101020
components := []component.Component{
@@ -1090,6 +1100,7 @@ func TestEnrichArgs(t *testing.T) {
10901100
b := &BeatsMonitor{
10911101
enabled: test.enabled,
10921102
config: &test.config,
1103+
logger: logp.NewNopLogger(),
10931104
}
10941105
args := b.EnrichArgs(unitID, test.binaryName, nil)
10951106
// replace socket path with placeholder, it's annoying to do cross-platform tests on these
@@ -1123,7 +1134,7 @@ func TestMonitorReload(t *testing.T) {
11231134
monitorcfg.MonitorLogs = false
11241135
monitorcfg.MonitorMetrics = false
11251136

1126-
beatsMonitor := New(true, "", monitorcfg, nil)
1137+
beatsMonitor := New(true, "", monitorcfg, nil, logp.NewNopLogger())
11271138
assert.Equal(t, beatsMonitor.config.C.MonitorLogs, false)
11281139
assert.Equal(t, beatsMonitor.config.C.MonitorLogs, false)
11291140

@@ -1197,6 +1208,7 @@ func TestMonitoringConfigOtelOutputSupport(t *testing.T) {
11971208
},
11981209
},
11991210
agentInfo: agentInfo,
1211+
logger: logp.NewNopLogger(),
12001212
}
12011213

12021214
policy := map[string]any{

internal/pkg/agent/install/componentvalidation/validation.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,13 @@ func GetMonitoringFn(ctx context.Context, logger *logger.Logger, cfg map[string]
125125
return nil, fmt.Errorf("could not load agent info: %w", err)
126126
}
127127

128-
monitor := componentmonitoring.New(agentCfg.Settings.V1MonitoringEnabled, agentCfg.Settings.DownloadConfig.OS(), agentCfg.Settings.MonitoringConfig, agentInfo)
128+
monitor := componentmonitoring.New(
129+
agentCfg.Settings.V1MonitoringEnabled,
130+
agentCfg.Settings.DownloadConfig.OS(),
131+
agentCfg.Settings.MonitoringConfig,
132+
agentInfo,
133+
logger,
134+
)
129135
return monitor.MonitoringConfig, nil
130136
}
131137

testing/integration/ess/beat_receivers_test.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -819,8 +819,9 @@ agent.monitoring.enabled: false
819819

820820
// Log lines TestBeatsReceiverProcessRuntimeFallback checks for
821821
const (
822-
otelRuntimeUnsupportedLogLineStart = "otel runtime is not supported"
823-
prometheusInputSkippedLogLine = "The Otel prometheus metrics monitoring input can't run in a beats process, skipping"
822+
otelRuntimeUnsupportedLogLineStart = "otel runtime is not supported"
823+
otelRuntimeMonitoringOutputUnsupportedLogLineStart = "otel runtime is not supported for monitoring output"
824+
prometheusInputSkippedLogLine = "The Otel prometheus metrics monitoring input can't run in a beats process, skipping"
824825
)
825826

826827
// TestBeatsReceiverProcessRuntimeFallback verifies that we fall back to the process runtime if the otel runtime
@@ -885,6 +886,7 @@ outputs:
885886
// verify we've logged a warning about using the process runtime
886887
var unsupportedLogRecords []map[string]any
887888
var prometheusUnsupportedLogRecord map[string]any
889+
var monitoringOutputUnsupportedLogRecord map[string]any
888890
for _, line := range strings.Split(string(logsBytes), "\n") {
889891
line = strings.TrimSpace(line)
890892
if line == "" {
@@ -902,6 +904,9 @@ outputs:
902904
if strings.HasPrefix(message, prometheusInputSkippedLogLine) {
903905
prometheusUnsupportedLogRecord = logRecord
904906
}
907+
if strings.HasPrefix(message, otelRuntimeMonitoringOutputUnsupportedLogLineStart) {
908+
monitoringOutputUnsupportedLogRecord = logRecord
909+
}
905910
}
906911
}
907912

@@ -914,6 +919,7 @@ outputs:
914919

915920
assert.Len(t, unsupportedLogRecords, 5, "one log line for each component we try to run")
916921
assert.NotEmpty(t, prometheusUnsupportedLogRecord, "should get a log line about Otel prometheus metrics input being skipped")
922+
assert.NotEmpty(t, monitoringOutputUnsupportedLogRecord, "should get a log line about monitoring output not being supported")
917923
}
918924

919925
// TestComponentWorkDir verifies that the component working directory is not deleted when moving the component from

0 commit comments

Comments
 (0)