 # trend calculation utterly broken for unsigned values

XMLWordPrintable

#### Details

• Incident report
• Resolution: Fixed
• Critical
• 1.8.4

#### Description

I have an item which monitors the running process count of a certain program. The values vary a bit and the average at around 6..7 but there are sometimes values of 1 and 2 and sometimes 10 or more. But there is a problem when the trends are calculated - they are almost always too low. This is because only integer arithmetic is used witch is rounding down on divisions. On each trend calculation the error is multiplied and the average value has a tendency to get near the minimum value. Let me show you an example (int and float):

(1) current history value is 6 and we starting a new trend interval (num = 0):
(int) average value = history value / (num + 1) = 6 / 1 = 6
(float) average value = history value / (num + 1) = 6.0 / 1 = 6.0

(2) current history value is 6 (num = 1)
(int) average value = (num * average value + history value) / (num + 1) = (1 * 6 + 6) / (1 + 1) = 6
(float) average value = (num * average value + history value) / (num + 1) = (1 * 6.0 + 6.0) / (1 + 1) = 6.0

(3) current history value is 7 (num = 2)
(int) average value = (num * average value + history value) / (num + 1) = (2 * 6 + 7) / (2 + 1) = 6
(float) average value = (num * average value + history value) / (num + 1) = (2 * 6.0 + 7.0) / (2 + 1) = 6.33

(4) current history value is 7 (num = 3)
(int) average value = (num * average value + history value) / (num + 1) = (3 * 6 + 7) / (3 + 1) = 6
(float) average value = (num * average value + history value) / (num + 1) = (3 * 6.33 + 7.0) / (3 + 1) = 6.49

(5) current history value is 5 (num = 4)
(int) average value = (num * average value + history value) / (num + 1) = (4 * 6 + 5) / (4 + 1) = 5
(float) average value = (num * average value + history value) / (num + 1) = (4 * 6.49 + 5.0) / (4 + 1) = 6.19

(6) current history value is 10 (num = 5)
(int) average value = (num * average value + history value) / (num + 1) = (5 * 5 + 10) / (5 + 1) = 5
(float) average value = (num * average value + history value) / (num + 1) = (5 * 6.19 + 10.0) / (5 + 1) = 6.83

You see that this integer arithmetic has a tendency to prefer small values over larger ones because errors are propagated and multiplied

In our specific case (process count) the real average is 6..7 but zabbix calculates something 2..3 which is near the minimum values which occur only in a low frequency. In the end the trends are just unusable.

I propose to keep the average values in double and only convert them by rounding only if necessary (e.g when writing them to db or showing them in frontend).

#### People Unassigned Ronald Wahl