Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reject infinite performance data values #10077

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

RincewindsHat
Copy link
Member

Some fault monitoring plugins may return "inf" or "-inf" as values due to a failure to initialize or other errors.

This patch introduces a check on whether the parse value is infinite (or negative infinite) and rejects the data point if that is the case.

The reasoning here is: There is no possible way a value of "inf" is ever a true measuring or even useful. Furthermore, when passed to the performance data writers, it may be rejected by the backend and lead to further complications.

fixes #10073

@cla-bot cla-bot bot added the cla/signed label Jun 9, 2024
@@ -259,6 +259,10 @@ PerfdataValue::Ptr PerfdataValue::Parse(const String& perfdata)

double value = Convert::ToDouble(tokens[0].SubStr(0, pos));

if (value == INFINITY || value == - INFINITY) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are special functions for such checks like std::isinf(). A related function like std::isfinite() or std::isnormal() might be even better suited here as it excludes more edge cases (I haven't checked if subnormal numbers would be a problem, that seems to be the only difference between these two functions).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please excuse my C. Those functions do seem more appropriate and sane to use.
I will change that accordingly. Thank you for the tip

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@RincewindsHat RincewindsHat force-pushed the reject_invalid_perfdata branch from 310efe0 to b8c6899 Compare June 10, 2024 10:49
@RincewindsHat
Copy link
Member Author

@julianbrost should be fine now

@RincewindsHat
Copy link
Member Author

@julianbrost @oxzi ping

@oxzi oxzi self-assigned this Jan 8, 2025
Some fault monitoring plugins may return "inf" or "-inf" as
values due to a failure to initialize or other errors.

This patch introduces a check on whether the parse value is infinite
(or negative infinite) and rejects the data point if that is the case.

The reasoning here is: There is no possible way a value of "inf" is ever
a true measuring or even useful. Furthermore, when passed to the
performance data writers, it may be rejected by the backend and lead
to further complications.
@oxzi oxzi force-pushed the reject_invalid_perfdata branch from b8c6899 to e738119 Compare January 9, 2025 10:46
Copy link
Member

@oxzi oxzi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First things first: Thanks a lot for this Pull Request and please excuse the delay on our side.

I have taken a closer look and tested it in a variety of setups. After rebasing it on the current master, I have added a test case for inf values which would succeed on the master branch, but raises an exception with your changes. (That's good.)

Then I built myself a test setup with an InfluxDB 2 registered as an Influxdb2Writer at the Icinga 2 and a CheckCommand sometimes dropping inf performance data.

CheckCommand definition

object CheckCommand "random fortune" {
    import "plugin-check-command"
    command = [ "/bin/bash", "-c", "/usr/games/fortune; echo \"|foo=`echo -e \"inf\n23\n42\" | shuf | head -n1`\"; exit $$0" ]
    arguments += {
        "(no key)" = {
            skip_key = true
            value = {{
                var rand = Math.random() * 1000
                if (host.last_check == -1 || host.state == 0) {
                    if (rand > 995) {
                        return 2
                    } else {
                        return 0
                    }
                } else {
                    if (rand > 900) {
                        return 0
                    } else {
                        return 2
                    }
                }
            }}
        }
    }
}

With an Icinga 2 built from the master branch, this would always result in invalid data sent to the InfluxDB 2 as the valid data points are sent bundled together with invalid ones. Effectively no data will be stored in the InfluxDB 2 as the whole POST request will be discarded.

However, when building Icinga 2 based on this branch, the invalid data points are being removed and only the valid ones are sent. Meanwhile, Icinga 2 logs something like the following:

[2025-01-09 10:55:20 +0000] warning/Influxdb2Writer: Ignoring invalid perfdata for checkable 'dummy
-929!random fortune' and command 'random fortune' with value: foo=inf
Context:
    (0) Processing check result for 'dummy-929!random fortune'

@oxzi oxzi removed their assignment Jan 9, 2025
@oxzi oxzi requested a review from julianbrost January 9, 2025 11:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Performance data values parsing problem: inf, -inf
3 participants