diff --git a/README.md b/README.md index 6e8774e3..c9828909 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Gatus is a developer-oriented health dashboard that gives you the ability to monitor your services using HTTP, ICMP, TCP, and even DNS queries as well as evaluate the result of said queries by using a list of conditions on values like the status code, the response time, the certificate expiration, the body and many others. The icing on top is that each of these health -checks can be paired with alerting via Slack, PagerDuty, Pushover, Discord, Twilio and more. +checks can be paired with alerting via Slack, Teams, PagerDuty, Discord, Twilio and many more. I personally deploy it in my Kubernetes cluster and let it monitor the status of my core applications: https://status.twin.sh/ diff --git a/core/condition.go b/core/condition.go index 35e857f7..bca75760 100644 --- a/core/condition.go +++ b/core/condition.go @@ -302,10 +302,18 @@ func sanitizeAndResolveNumerical(list []string, result *Result) (parameters []st parameters, resolvedParameters := sanitizeAndResolve(list, result) for _, element := range resolvedParameters { if duration, err := time.ParseDuration(element); duration != 0 && err == nil { + // If the string is a duration, convert it to milliseconds resolvedNumericalParameters = append(resolvedNumericalParameters, duration.Milliseconds()) } else if number, err := strconv.ParseInt(element, 10, 64); err != nil { - // Default to 0 if the string couldn't be converted to an integer - resolvedNumericalParameters = append(resolvedNumericalParameters, 0) + // It's not an int, so we'll check if it's a float + if f, err := strconv.ParseFloat(element, 64); err == nil { + // It's a float, but we'll convert it to an int. We're losing precision here, but it's better than + // just returning 0. + resolvedNumericalParameters = append(resolvedNumericalParameters, int64(f)) + } else { + // Default to 0 if the string couldn't be converted to an integer or a float + resolvedNumericalParameters = append(resolvedNumericalParameters, 0) + } } else { resolvedNumericalParameters = append(resolvedNumericalParameters, number) } diff --git a/core/condition_test.go b/core/condition_test.go index 678eed9e..25976d6a 100644 --- a/core/condition_test.go +++ b/core/condition_test.go @@ -294,6 +294,13 @@ func TestCondition_evaluate(t *testing.T) { ExpectedSuccess: false, ExpectedOutput: "[BODY].data.id (1) > 5", }, + { + Name: "body-jsonpath-float-using-greater-than-issue433", // As of v5.3.1, Gatus will convert a float to an int. We're losing precision, but it's better than just returning 0 + Condition: Condition("[BODY].balance > 100"), + Result: &Result{body: []byte(`{"balance": "123.40000000000005"}`)}, + ExpectedSuccess: true, + ExpectedOutput: "[BODY].balance > 100", + }, { Name: "body-jsonpath-complex-int-using-less-than", Condition: Condition("[BODY].data.id < 5"), diff --git a/jsonpath/jsonpath_test.go b/jsonpath/jsonpath_test.go index 41d657c2..83244c5c 100644 --- a/jsonpath/jsonpath_test.go +++ b/jsonpath/jsonpath_test.go @@ -158,6 +158,22 @@ func TestEval(t *testing.T) { ExpectedOutputLength: 0, ExpectedError: true, }, + { + Name: "float-as-string", + Path: "balance", + Data: `{"balance": "123.40000000000005"}`, + ExpectedOutput: "123.40000000000005", + ExpectedOutputLength: 18, + ExpectedError: false, + }, + { + Name: "float-as-number", + Path: "balance", + Data: `{"balance": 123.40000000000005}`, + ExpectedOutput: "123.40000000000005", + ExpectedOutputLength: 18, + ExpectedError: false, + }, } for _, scenario := range scenarios { t.Run(scenario.Name, func(t *testing.T) {