[ZBXNEXT-1791] Trigger functions evaluation for unsupported items Created: 2013 Jun 12 Updated: 2022 Oct 08 Resolved: 2016 Sep 02 |
|
Status: | Closed |
Project: | ZABBIX FEATURE REQUESTS |
Component/s: | Server (S) |
Affects Version/s: | 1.8.16, 2.0.6 |
Fix Version/s: | 3.2.0beta1 |
Type: | Change Request | Priority: | Major |
Reporter: | alix | Assignee: | Unassigned |
Resolution: | Fixed | Votes: | 43 |
Labels: | evaluation, notsupported | ||
Remaining Estimate: | Not Specified | ||
Time Spent: | Not Specified | ||
Original Estimate: | Not Specified |
Issue Links: |
|
Description |
I'd like to discuss the way trigger functions are evaluated for unsupported items, and what can be changed for the greater good. Existing trigger functions can be separated in two logical groups. Currently when an item changes status to unsupported, any trigger expression function referencing this item change trigger value to UNKNOWN. Let's look at first group of functions. nodata() is the only sane way to detect whether an important item is receiving new values. When an item's data source is broken, and item turns unsupported, nodata() stops evaluating, making it impossible to detect that this exact item is not updating anymore. I'm aware of the way to track global number of server's unsupported items, but it requires tedious manual work to find out which item(s) went sideways, and it isn't healthy. Due to limitations of currently implemented trigger expression parser, each date() dayofmonth() dayofweek() time() and now() function call requires a mandatory argument, a reference to an existing item. This item is not used in function calculation at all. Therefore, it is illogical to stop recalculation of these functions when dummy item argument turns unsupported, as there's no connection between a function and its item-parameter at all. I feel that current implementation requires rethinking, and composing a spec about the way this must be handled. |
Comments |
Comment by Oleksii Zagorskyi [ 2013 Jun 13 ] |
Seems I recall related issue report but cannot find it at the moment. Also remember about |
Comment by alix [ 2013 Jun 13 ] |
my main complaint is about nodata() behaviour, time-based functions got carried in by an accident (Richlv). |
Comment by Oleksii Zagorskyi [ 2013 Jun 14 ] |
For nodata() we had discussions in |
Comment by alix [ 2013 Jun 14 ] |
|
Comment by Oleksii Zagorskyi [ 2013 Jul 02 ] |
The issue I meant in first my comment is |
Comment by v99glu [ 2014 Sep 07 ] |
IMHO, when an item doesn't receive values for X sec (and it does not matter because of item became not supported or zabbix agent became not available or zabbix agent stopped sending values, etc.) condition "there is no data for item" is TRUE, therefore function nodata(X) MUST be evaluated to "1" and corresponding trigger MUST fire independently of item state. Isn't it logical? |
Comment by richlv [ 2014 Dec 01 ] |
one usecase where this would be very useful : |
Comment by Michael [ 2014 Dec 01 ] |
Since duplicate issue was closed, I would like to copy my comment here, it shows two real live scenarios related to this feature request. We are struggling a lot without having any possibility to trigger on item becoming unsupported. I will give you a couple examples so that you can understand how important it may be. |
Comment by Dmitry Samsonov [ 2015 Jan 20 ] |
Any chance to finally implement it in near future? Thank you. |
Comment by Benjamin Goodrich [ 2015 Mar 07 ] |
Anyone at all looking at this? |
Comment by Slash [ 2015 Mar 19 ] |
I recently had this issue with nodata(). When some item report a null value, and the item is of the type float, the item becomes unsupported with the message Received value [] is not suitable for value type [Numeric (float)] This is problematic because in my case, I call a custom script that always run fine, and my only option to tell zabbix that there is no data is to return nothing, but then [] is not a float so it becomes unsupported instead... As a workaround, I specifically return an other value when I have no response with my script (0 in this case) and I changed the trigger to fire when the return value is 0. But this is not a perfect solution since it mess with the average value of the item, which can be important (in my case, it's timing value in seconds). |
Comment by Slash [ 2015 Mar 19 ] |
Same issue when a script times out:
Timeout while executing a shell script.
The item become then becomes unsupported and nodata() doesn't work either. |
Comment by Tatapoum [ 2015 Mar 23 ] |
Yes, this is something we hope to see in a future release. If an external script times out or returns no value, there is no way to trigger an alert, which is very dangerous. |
Comment by Paulo Estrela [ 2015 Sep 01 ] |
It is definitively an important thing. It happens with odbc monitoring. If you are monitoring a database and isql can't connect, you get a "unsuported item" and your database may be down and you will never know unless you look at your mail or zabbix_server log. nodata processing would help. |
Comment by Javier [ 2016 Jan 14 ] |
Hi Zabbix team. It's been a while since I'm not using Zabbix, so sorry in advance if this issue has been already sorted out. Looking at What's new in Zabbix 3.0.0 apparently the new items_unsupported implementation fix this issue. If yes, can you please state it clearly in this issue? Many thanks. |
Comment by Aleksandrs Saveljevs [ 2016 Jan 14 ] |
caraconan, in "What's new in Zabbix 3.0.0" there is the following statement with the keyword you quoted:
This statement talks about new internal checks. This issue, however, is about evaluating trigger functions that reference unsupported items. So no, this issue has not been fixed. |
Comment by Andrew Baker [ 2016 Feb 17 ] |
Suggested solution for .nodata. Currently returns 1 for no data in X time period, or 0 if all is well. Could we create a third result? "2 - Item not supported". This change I beleive would allow triggers to be built to satisfy many of the above concerns. Mine as well. |
Comment by richlv [ 2016 Apr 12 ] |
thinking more about this specific issue, it's fairly sad for userparameters. if a userparam script fails, it has no way to allow nodata() triggers fire - if it sends crap data, that's bad, timing out makes the item unsupported... is there a technical difficulty in making nodata() work on "unsupported" items ? |
Comment by alix [ 2016 Apr 13 ] |
in case anyone is interested in an inspiration on the subject: I'm running the patch supplied in |
Comment by Oleksii Zagorskyi [ 2016 Aug 13 ] |
In a |
Comment by Andris Mednis [ 2016 Aug 24 ] |
Development branches:
|
Comment by Andris Zeila [ 2016 Aug 24 ] |
(1) It would be better to define ZBX_UNKNOWN_STR_LEN as ZBX_CONST_STRLEN(ZBX_UNKNOWN_STR) rather than hardcoded value 11. andris RESOLVED in r61904 . wiper CLOSED |
Comment by Andris Mednis [ 2016 Aug 24 ] |
The 1st merge is available in pre-3.2.0alpha3 (trunk) r61915 . It enables evaluation of nodata() and time-based functions for NOTSUPPORTED items in trigger expressions and calculated items. |
Comment by Andris Mednis [ 2016 Aug 24 ] |
The 1st merge documented in sasha Excellent! CLOSED |
Comment by Andris Zeila [ 2016 Aug 25 ] |
(2) In expression.c:zbx_evaluate_item_functions() andris Thanks! RESOLVED in r61931 . wiper CLOSED |
Comment by Andris Zeila [ 2016 Aug 25 ] |
(3) In evaluate.c:evaluate_number() andris Good idea! RESOLVED in r61933 . wiper Also I think it would be better to remove THIS_SHOULD_NEVER_HAPPEN, as user can create valid setup which would result in this error. andris RESOLVED in r61941 wiper CLOSED |
Comment by Andris Zeila [ 2016 Aug 25 ] |
(4) In DCupdate_hosts_availability(void) the sql* variables are renamed to sql_buff*. We have 150+ places where sql* variables are used and 0 with sql_buf* naming. I think it's better to stay with the usual naming. andris The reason of renaming local variables 'sql', 'sql_alloc' and 'sql_offset' is to avoid shadowing of global variables with the same names. WON'T FIX. |
Comment by Andris Zeila [ 2016 Aug 25 ] |
(5) In serveral evaluate_term* functions the returned index is lost if the term does not match the following expression. It can lead to unitialized variable usage and crashes. This crude patch appears to help, but it might still be missing something. Index: src/libs/zbxalgo/evaluate.c =================================================================== --- src/libs/zbxalgo/evaluate.c (revision 61904) +++ src/libs/zbxalgo/evaluate.c (working copy) @@ -292,6 +292,9 @@ if (ZBX_INFINITY == (result = evaluate_term7(&res_idx))) return ZBX_INFINITY; + if (ZBX_UNKNOWN == result) + *unknown_idx = res_idx; + /* if evaluate_term7() returns ZBX_UNKNOWN then continue as with regular number */ while ('*' == *ptr || '/' == *ptr) @@ -365,6 +368,9 @@ if (ZBX_INFINITY == (result = evaluate_term6(&res_idx))) return ZBX_INFINITY; + if (ZBX_UNKNOWN == result) + *unknown_idx = res_idx; + /* if evaluate_term6() returns ZBX_UNKNOWN then continue as with regular number */ while ('+' == *ptr || '-' == *ptr) @@ -416,6 +422,9 @@ if (ZBX_INFINITY == (result = evaluate_term5(&res_idx))) return ZBX_INFINITY; + if (ZBX_UNKNOWN == result) + *unknown_idx = res_idx; + /* if evaluate_term5() returns ZBX_UNKNOWN then continue as with regular number */ while (1) @@ -489,6 +498,9 @@ if (ZBX_INFINITY == (result = evaluate_term4(&res_idx))) return ZBX_INFINITY; + if (ZBX_UNKNOWN == result) + *unknown_idx = res_idx; + /* if evaluate_term4() returns ZBX_UNKNOWN then continue as with regular number */ while (1) @@ -550,6 +562,9 @@ if (ZBX_INFINITY == (result = evaluate_term3(&res_idx))) return ZBX_INFINITY; + if (ZBX_UNKNOWN == result) + *unknown_idx = res_idx; + /* if evaluate_term3() returns ZBX_UNKNOWN then continue as with regular number */ while ('a' == ptr[0] && 'n' == ptr[1] && 'd' == ptr[2] && SUCCEED == is_operator_delimiter(ptr[3])) @@ -625,6 +640,9 @@ if (ZBX_INFINITY == (result = evaluate_term2(&res_idx))) return ZBX_INFINITY; + if (ZBX_UNKNOWN == result) + *unknown_idx = res_idx; + /* if evaluate_term2() returns ZBX_UNKNOWN then continue as with regular number */ while ('o' == ptr[0] && 'r' == ptr[1] && SUCCEED == is_operator_delimiter(ptr[2])) andris Thanks for finding this and patch! RESOLVED in r61936 . wiper CLOSED |
Comment by Andris Zeila [ 2016 Aug 25 ] |
(6) Continuing from the (3) - we should validate the index returned by evaluate_term1 against the unknown_msgs vector boundaries. Otherwise it's possible to crash server when using last() function if item value is something like ZBX_UNKNOWN1234. andris RESOLVED in r61949. wiper CLOSED |
Comment by Andris Mednis [ 2016 Aug 25 ] |
The 2nd merge is available in pre-3.2.0beta1 (trunk) r61960 . It enables evaluation of logical expressions with unsupported items in trigger expressions and calculated items. |
Comment by Andris Zeila [ 2016 Aug 26 ] |
(7) When both items in an expression are unknown the generated error refers to the second item. It would be more natural to refer the first item. andris This is an approved design decision - if there are multiple unknown operands and expression evaluates to Unknown then the error message refers to the last unknown item. |
Comment by Andris Zeila [ 2016 Aug 26 ] |
Base evaluation logic tested: {Trapper:strap[1].last()} or {Trapper:strap[2].last()} | Left | Right | Expected | Result | |------|-------|----------|-----------------------------------------------------------------------------------------------------------| | 0 | 0 | 0 | 0 | | 0 | 1 | 1 | 1 | | 1 | 0 | 1 | 1 | | 1 | 1 | 1 | 1 | | ? | 0 | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[1].last()": item is not supported.". | | 0 | ? | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[2].last()": item is not supported.". | | ? | 1 | 1 | 1 | | 1 | ? | 1 | 1 | | ? | ? | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[2].last()": item is not supported.". | AND {Trapper:strap[1].last()} and {Trapper:strap[2].last()} | Left | Right | Expected | Result | |------|-------|----------|-----------------------------------------------------------------------------------------------------------| | 0 | 0 | 0 | 0 | | 0 | 1 | 0 | 0 | | 1 | 0 | 0 | 0 | | 1 | 1 | 1 | 1 | | ? | 0 | 0 | 0 | | 0 | ? | 0 | 0 | | ? | 1 | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[1].last()": item is not supported.". | | 1 | ? | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[2].last()": item is not supported.". | | ? | ? | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[2].last()": item is not supported.". | =, <> {Trapper:strap[1].last()} = {Trapper:strap[2].last()} | Left | Right | Expected | Result | |------|-------|----------|-----------------------------------------------------------------------------------------------------------| | 0 | 0 | 1 | 1 | | 0 | 1 | 0 | 0 | | 1 | 0 | 0 | 0 | | 1 | 1 | 1 | 1 | | ? | 0 | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[1].last()": item is not supported.". | | 0 | ? | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[2].last()": item is not supported.". | | ? | 1 | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[1].last()": item is not supported.". | | 1 | ? | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[2].last()": item is not supported.". | | ? | ? | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[2].last()": item is not supported.". | <. <=, >, >= {Trapper:strap[1].last()} < {Trapper:strap[2].last()} | Left | Right | Expected | Result | |------|-------|----------|-----------------------------------------------------------------------------------------------------------| | 0 | 0 | 0 | 0 | | 0 | 1 | 1 | 1 | | 1 | 0 | 0 | 0 | | 1 | 1 | 0 | 0 | | ? | 0 | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[1].last()": item is not supported.". | | 0 | ? | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[2].last()": item is not supported.". | | ? | 1 | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[1].last()": item is not supported.". | | 1 | ? | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[2].last()": item is not supported.". | | ? | ? | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[2].last()": item is not supported.". | +, - {Trapper:strap[1].last()} + {Trapper:strap[2].last()} | Left | Right | Expected | Result | |------|-------|----------|-----------------------------------------------------------------------------------------------------------| | 0 | 0 | 0 | 0 | | 0 | 1 | 1 | 1 | | 1 | 0 | 1 | 1 | | 1 | 1 | 2 | 2 | | ? | 0 | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[1].last()": item is not supported.". | | 0 | ? | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[2].last()": item is not supported.". | | ? | 1 | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[1].last()": item is not supported.". | | 1 | ? | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[2].last()": item is not supported.". | | ? | ? | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[2].last()": item is not supported.". | *, / {Trapper:strap[1].last()} * {Trapper:strap[2].last()} | Left | Right | Expected | Result | |------|-------|----------|-----------------------------------------------------------------------------------------------------------| | 0 | 0 | 0 | 0 | | 0 | 1 | 0 | 0 | | 1 | 0 | 0 | 0 | | 1 | 1 | 1 | 1 | | ? | 0 | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[1].last()": item is not supported.". | | 0 | ? | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[2].last()": item is not supported.". | | ? | 1 | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[1].last()": item is not supported.". | | 1 | ? | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[2].last()": item is not supported.". | | ? | ? | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[2].last()": item is not supported.". | NOT not {Trapper:strap[1].last()} | Left | Expected | Result | |------|----------|-----------------------------------------------------------------------------------------------------------| | 0 | 1 | 1 | | 1 | 0 | 0 | | ? | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[1].last()": item is not supported.". | unary - -{Trapper:strap[1].last()} | Left | Expected | Result | |------|----------|-----------------------------------------------------------------------------------------------------------| | 0 | -0 | -0 | | 1 | -1 | -1 | | ? | ? | Cannot evaluate expression: "Cannot evaluate function "Trapper:strap[1].last()": item is not supported.". | |
Comment by Andris Zeila [ 2016 Aug 26 ] |
(8) Reverted evaluate() function error parameters to be mandatory. It's being assigned to a static variable and there is a high possibility of bugs if NULL is used. RESOLVED in development branch svn://svn.zabbix.com/branches/dev/ZBXNEXT-1791-4 r62003 andris Merged into trunk r62051. CLOSED |
Comment by Andris Mednis [ 2016 Aug 26 ] |
(9) Currently calculated item "1 or notexistingfunction(vfs.file.cksum[/test_file.txt])" evaluates to 1. andris For triggers the frontend does not allow to use non-existing functions. Only calculated items are affected and validation in the frontend should be developed. WON'T FIX. |
Comment by Sandis Neilands (Inactive) [ 2016 Aug 30 ] |
(10) Clang static analysis tool reports new defects in trunk. Number of defects before this change: 45. Number of defects after: 63. Please take a look! ./bootstrap.sh ./configure --prefix=`pwd`/usr CC=clang CFLAGS="-Wall -Wextra -g" --enable-server --enable-proxy --enable-agent --enable-java --enable-ipv6 --with-mysql --with-jabber --with-libxml2 --with-net-snmp --with-unixodbc --with-ssh2 --with-openipmi --with-ldap --with-libcurl --with-iconv --with-openssl make dbschema scan-build make install 2>&1 | tee make.log scan-view /tmp/scan-build-2016-08-30-103815-15464-1 andris Thanks for finding! This uncovered some bugs. andris RESOLVED in dev branch svn://svn.zabbix.com/branches/dev/ZBXNEXT-1791-5, r62119. wiper CLOSED andris Merged into trunk r62138 . |