Skip to content

Commit

Permalink
Add support for failureThreshold passed as float64 from policy (#6230)
Browse files Browse the repository at this point in the history
  • Loading branch information
pchila authored Dec 6, 2024
1 parent 4de0ff7 commit 039baab
Show file tree
Hide file tree
Showing 2 changed files with 184 additions and 2 deletions.
18 changes: 16 additions & 2 deletions internal/pkg/agent/application/monitoring/v1_monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package monitoring
import (
"crypto/sha256"
"fmt"
"math"
"net/url"
"os"
"path/filepath"
Expand Down Expand Up @@ -164,12 +165,25 @@ func (b *BeatsMonitor) MonitoringConfig(
case uint:
failureThreshold = &policyValue
case int:
if policyValue < 0 {
return nil, fmt.Errorf("converting policy failure threshold int to uint, value must be non-negative: %v", policyValue)
}
unsignedValue := uint(policyValue)
failureThreshold = &unsignedValue
case float64:
if policyValue < 0 || policyValue > math.MaxUint {
return nil, fmt.Errorf("converting policy failure threshold float64 to uint, value out of range: %v", policyValue)
}
truncatedUnsignedValue := uint(policyValue)
failureThreshold = &truncatedUnsignedValue
case string:
parsedPolicyValue, err := strconv.Atoi(policyValue)
parsedPolicyValue, err := strconv.ParseUint(policyValue, 10, 64)
if err != nil {
return nil, fmt.Errorf("failed to convert policy failure threshold string to int: %w", err)
return nil, fmt.Errorf("converting policy failure threshold string to uint: %w", err)
}
if parsedPolicyValue > math.MaxUint {
// this is to catch possible overflow in 32-bit envs, should not happen that often
return nil, fmt.Errorf("converting policy failure threshold from string to uint, value out of range: %v", policyValue)
}
uintPolicyValue := uint(parsedPolicyValue)
failureThreshold = &uintPolicyValue
Expand Down
168 changes: 168 additions & 0 deletions internal/pkg/agent/application/monitoring/v1_monitor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,34 @@ func TestMonitoringConfigMetricsFailureThreshold(t *testing.T) {
},
expectedThreshold: sampleTenErrorsStreamThreshold,
},
{
name: "policy failure threshold float64",
monitoringCfg: &monitoringConfig{
C: &monitoringcfg.MonitoringConfig{
Enabled: true,
MonitorMetrics: true,
HTTP: &monitoringcfg.MonitoringHTTPConfig{
Enabled: false,
},
FailureThreshold: &sampleSevenErrorsStreamThreshold,
},
},
policy: map[string]any{
"agent": map[string]any{
"monitoring": map[string]any{
"metrics": true,
"http": map[string]any{
"enabled": false,
},
failureThresholdKey: float64(10),
},
},
"outputs": map[string]any{
"default": map[string]any{},
},
},
expectedThreshold: sampleTenErrorsStreamThreshold,
},
}

for _, tc := range tcs {
Expand Down Expand Up @@ -462,6 +490,146 @@ func TestMonitoringConfigMetricsFailureThreshold(t *testing.T) {
}
}

func TestErrorMonitoringConfigMetricsFailureThreshold(t *testing.T) {

agentInfo, err := info.NewAgentInfo(context.Background(), false)
require.NoError(t, err, "Error creating agent info")

tcs := []struct {
name string
monitoringCfg *monitoringConfig
policy map[string]any
assertError assert.ErrorAssertionFunc
}{
{
name: "invalid policy failure threshold float64",
monitoringCfg: &monitoringConfig{
C: &monitoringcfg.MonitoringConfig{
Enabled: true,
MonitorMetrics: true,
HTTP: &monitoringcfg.MonitoringHTTPConfig{
Enabled: false,
},
FailureThreshold: nil,
},
},
policy: map[string]any{
"agent": map[string]any{
"monitoring": map[string]any{
"metrics": true,
"http": map[string]any{
"enabled": false,
},
failureThresholdKey: float64(-1),
},
},
"outputs": map[string]any{
"default": map[string]any{},
},
},
assertError: assert.Error,
},
{
name: "invalid policy failure threshold string",
monitoringCfg: &monitoringConfig{
C: &monitoringcfg.MonitoringConfig{
Enabled: true,
MonitorMetrics: true,
HTTP: &monitoringcfg.MonitoringHTTPConfig{
Enabled: false,
},
FailureThreshold: nil,
},
},
policy: map[string]any{
"agent": map[string]any{
"monitoring": map[string]any{
"metrics": true,
"http": map[string]any{
"enabled": false,
},
failureThresholdKey: "foobar",
},
},
"outputs": map[string]any{
"default": map[string]any{},
},
},
assertError: assert.Error,
},
{
name: "invalid policy failure threshold negative number as string",
monitoringCfg: &monitoringConfig{
C: &monitoringcfg.MonitoringConfig{
Enabled: true,
MonitorMetrics: true,
HTTP: &monitoringcfg.MonitoringHTTPConfig{
Enabled: false,
},
FailureThreshold: nil,
},
},
policy: map[string]any{
"agent": map[string]any{
"monitoring": map[string]any{
"metrics": true,
"http": map[string]any{
"enabled": false,
},
failureThresholdKey: "-12",
},
},
"outputs": map[string]any{
"default": map[string]any{},
},
},
assertError: assert.Error,
},
{
name: "invalid policy failure threshold negative int",
monitoringCfg: &monitoringConfig{
C: &monitoringcfg.MonitoringConfig{
Enabled: true,
MonitorMetrics: true,
HTTP: &monitoringcfg.MonitoringHTTPConfig{
Enabled: false,
},
FailureThreshold: nil,
},
},
policy: map[string]any{
"agent": map[string]any{
"monitoring": map[string]any{
"metrics": true,
"http": map[string]any{
"enabled": false,
},
failureThresholdKey: -12,
},
},
"outputs": map[string]any{
"default": map[string]any{},
},
},
assertError: assert.Error,
},
}

for _, tc := range tcs {

t.Run(tc.name, func(t *testing.T) {
b := &BeatsMonitor{
enabled: true,
config: tc.monitoringCfg,
operatingSystem: runtime.GOOS,
agentInfo: agentInfo,
}
_, err := b.MonitoringConfig(tc.policy, nil, map[string]string{"foobeat": "filebeat"}, map[string]uint64{}) // put a componentID/binary mapping to have something in the beats monitoring input
tc.assertError(t, err)
})
}
}

func TestMonitoringConfigComponentFields(t *testing.T) {
agentInfo, err := info.NewAgentInfo(context.Background(), false)
require.NoError(t, err, "Error creating agent info")
Expand Down

0 comments on commit 039baab

Please sign in to comment.