Over the last few months, I have been attempting to develop some triggers for some custom needs and have ran into some frustrations (leading to having to do a bunch of convoluted trickery in an attempt to compensate). I have reached the point where I can't find a workaround to get some stuff that I need.
There is no way to do an "if" (such as the C trinary operator) in a calculated value.
There are no mathematical functions that can operate on arguments:
min({Template xyz SNMP IF-MIB:ifHCInOctets[{#IFINDEX}].avg(20m), {Template xyz SNMP IF-MIB:ifHCOutOctets[{#IFINDEX}].avg(20m))
diff (and several other functions) do not accept time_shift.
There appears to be no way specify which order items will be processed (such as if one calculated value depends on another calculated value)
The following is accepted and appears to be processed (it does not result in an error when the item is processed), but always returns 0 (or possibly no data):
count(item1[{#IFINDEX}], 60m, calculatedItem2[{#IFINDEX}]*.985,"ge")
In particular it would be nice to be able to do min, max, ceil, floor, and abs between an item (where item might have its own function, such as .last(#2) ) and a constant, or two items, and to nest these, in both triggers and in calculated values.
Also, it would be nice if a trigger could find out the last time it was fired (or when some other trigger was fired) which would make hysteresis significantly easier to implement.
For example, I have a calculated value that needs to return either the calculation, or 0 IF another calculated value changed. I either need this calculated value to always be calculated AFTER the other one is calculated OR I need to be able to do a diff between the last 2 AND the previous to last and previous previous to last values of the other item:
This was my last attempt at a workaround until I found out diff won't take a time_shift:
count(InSomeItem[{#IFINDEX}],#1,98.5,"ge") * (1-diff(InSomeOtherItem[{#IFINDEX}])) * (1-diff(InSomeOtherItem[{#IFINDEX}]), 1)
The first clause being the value I'm trying to calculate, unless InSomeOtherItem changed. The third clause being because I don't know if this calculation will occur before or after InSomeOtherItem is processed. And the whole "1-diff..." construct being an attempt to simulate the trinary operator (and/or compensate for the lack of min(item1, item2) ) (calculate the value, and then multiply it by 1 or 0)
And indeed some of the calculated values i'm using are because of not being able to do some of the above in a trigger (such as nesting) (min(abs(item1), abs(item2))
If I am wrong about not being able to do some of the above, please enlighten me (I got rather excited when I thought I was able to provide an item as an argument to a function (instead of a constant) only to have it silently fail.
Zabbix is the most powerful open-source monitoring system I've thus used, but I feel the above limitations are holding it back significantly; I can almost accomplish what I need to, but not quite.
--
For reference: C style trinary operator (allows for conditionals inside mathematical formulas):
someCondition ? trueExpression : falseExpression
the value of the entire operator is either trueExpression or falseExpression depending on the boolean value of the someCondition)
There is no way to do an "if" (such as the C trinary operator) in a calculated value.
There are no mathematical functions that can operate on arguments:
min({Template xyz SNMP IF-MIB:ifHCInOctets[{#IFINDEX}].avg(20m), {Template xyz SNMP IF-MIB:ifHCOutOctets[{#IFINDEX}].avg(20m))
diff (and several other functions) do not accept time_shift.
There appears to be no way specify which order items will be processed (such as if one calculated value depends on another calculated value)
The following is accepted and appears to be processed (it does not result in an error when the item is processed), but always returns 0 (or possibly no data):
count(item1[{#IFINDEX}], 60m, calculatedItem2[{#IFINDEX}]*.985,"ge")
In particular it would be nice to be able to do min, max, ceil, floor, and abs between an item (where item might have its own function, such as .last(#2) ) and a constant, or two items, and to nest these, in both triggers and in calculated values.
Also, it would be nice if a trigger could find out the last time it was fired (or when some other trigger was fired) which would make hysteresis significantly easier to implement.
For example, I have a calculated value that needs to return either the calculation, or 0 IF another calculated value changed. I either need this calculated value to always be calculated AFTER the other one is calculated OR I need to be able to do a diff between the last 2 AND the previous to last and previous previous to last values of the other item:
This was my last attempt at a workaround until I found out diff won't take a time_shift:
count(InSomeItem[{#IFINDEX}],#1,98.5,"ge") * (1-diff(InSomeOtherItem[{#IFINDEX}])) * (1-diff(InSomeOtherItem[{#IFINDEX}]), 1)
The first clause being the value I'm trying to calculate, unless InSomeOtherItem changed. The third clause being because I don't know if this calculation will occur before or after InSomeOtherItem is processed. And the whole "1-diff..." construct being an attempt to simulate the trinary operator (and/or compensate for the lack of min(item1, item2) ) (calculate the value, and then multiply it by 1 or 0)
And indeed some of the calculated values i'm using are because of not being able to do some of the above in a trigger (such as nesting) (min(abs(item1), abs(item2))
If I am wrong about not being able to do some of the above, please enlighten me (I got rather excited when I thought I was able to provide an item as an argument to a function (instead of a constant) only to have it silently fail.
Zabbix is the most powerful open-source monitoring system I've thus used, but I feel the above limitations are holding it back significantly; I can almost accomplish what I need to, but not quite.
--
For reference: C style trinary operator (allows for conditionals inside mathematical formulas):
someCondition ? trueExpression : falseExpression
the value of the entire operator is either trueExpression or falseExpression depending on the boolean value of the someCondition)

Comment