22
require_once "maps.inc.php";
23
require_once "acknow.inc.php";
26
* Function: INIT_TRIGGER_EXPRESSION_STRUCTURES
29
* initialize structures for trigger expression
32
* Eugene Grigorjev (eugene.grigorjev@zabbix.com)
37
function INIT_TRIGGER_EXPRESSION_STRUCTURES()
39
if ( defined('TRIGGER_EXPRESSION_STRUCTURES_OK') ) return;
40
define('TRIGGER_EXPRESSION_STRUCTURES_OK', 1);
42
global $ZBX_TR_EXPR_ALLOWED_MACROS, $ZBX_TR_EXPR_REPLACE_TO, $ZBX_TR_EXPR_ALLOWED_FUNCTIONS;
44
$ZBX_TR_EXPR_ALLOWED_MACROS['{TRIGGER.VALUE}'] = '{TRIGGER.VALUE}';
46
$ZBX_TR_EXPR_REPLACE_TO = 'zbx_expr_ok';
48
$ZBX_TR_EXPR_ALLOWED_FUNCTIONS['abschange'] = array('args' => null,
49
'item_types' => array(
50
ITEM_VALUE_TYPE_FLOAT,
51
ITEM_VALUE_TYPE_UINT64,
56
$ZBX_TR_EXPR_ALLOWED_FUNCTIONS['avg'] = array('args' => array( 0 => array('type' => 'sec_num','mandat' => true) ),
57
'item_types' => array(
58
ITEM_VALUE_TYPE_FLOAT,
59
ITEM_VALUE_TYPE_UINT64
62
$ZBX_TR_EXPR_ALLOWED_FUNCTIONS['delta'] = array('args' => array( 0 => array('type' => 'sec_num','mandat' => true) ),
63
'item_types' => array(
64
ITEM_VALUE_TYPE_FLOAT,
65
ITEM_VALUE_TYPE_UINT64
68
$ZBX_TR_EXPR_ALLOWED_FUNCTIONS['change'] = array('args' => null,
69
'item_types' => array(
70
ITEM_VALUE_TYPE_FLOAT,
71
ITEM_VALUE_TYPE_UINT64,
76
$ZBX_TR_EXPR_ALLOWED_FUNCTIONS['count'] = array('args' => array( 0 => array('type' => 'sec','mandat' => true), 1 => array('type' => 'str') ),
77
'item_types' => array(
78
ITEM_VALUE_TYPE_FLOAT,
79
ITEM_VALUE_TYPE_UINT64,
85
$ZBX_TR_EXPR_ALLOWED_FUNCTIONS['date'] = array('args' => null, 'item_types' => null );
87
$ZBX_TR_EXPR_ALLOWED_FUNCTIONS['dayofweek']= array('args' => null, 'item_types' => null );
89
$ZBX_TR_EXPR_ALLOWED_FUNCTIONS['diff'] = array('args' => null,
90
'item_types' => array(
91
ITEM_VALUE_TYPE_FLOAT,
92
ITEM_VALUE_TYPE_UINT64,
97
$ZBX_TR_EXPR_ALLOWED_FUNCTIONS['fuzzytime'] = array('args' => null,
98
'item_types' => array(
99
ITEM_VALUE_TYPE_FLOAT,
100
ITEM_VALUE_TYPE_UINT64
103
$ZBX_TR_EXPR_ALLOWED_FUNCTIONS['last'] = array('args' => null,
104
'item_types' => array(
105
ITEM_VALUE_TYPE_FLOAT,
106
ITEM_VALUE_TYPE_UINT64,
111
$ZBX_TR_EXPR_ALLOWED_FUNCTIONS['max'] = array('args' => array( 0 => array('type' => 'sec_num','mandat' => true) ),
112
'item_types' => array(
113
ITEM_VALUE_TYPE_FLOAT,
114
ITEM_VALUE_TYPE_UINT64
117
$ZBX_TR_EXPR_ALLOWED_FUNCTIONS['min'] = array('args' => array( 0 => array('type' => 'sec_num','mandat' => true) ),
118
'item_types' => array(
119
ITEM_VALUE_TYPE_FLOAT,
120
ITEM_VALUE_TYPE_UINT64
123
$ZBX_TR_EXPR_ALLOWED_FUNCTIONS['nodata']= array('args' => array( 0 => array('type' => 'sec','mandat' => true) ), 'item_types' => null );
124
$ZBX_TR_EXPR_ALLOWED_FUNCTIONS['now'] = array('args' => null, 'item_types' => null );
125
$ZBX_TR_EXPR_ALLOWED_FUNCTIONS['prev'] = array('args' => null,
126
'item_types' => array(
127
ITEM_VALUE_TYPE_FLOAT,
128
ITEM_VALUE_TYPE_UINT64,
133
$ZBX_TR_EXPR_ALLOWED_FUNCTIONS['str'] = array('args' => array( 0 => array('type' => 'str','mandat' => true) ),
134
'item_types' => array(
141
$ZBX_TR_EXPR_ALLOWED_FUNCTIONS['sum'] = array('args' => array( 0 => array('type' => 'sec_num','mandat' => true) ),
142
'item_types' => array(
143
ITEM_VALUE_TYPE_FLOAT,
144
ITEM_VALUE_TYPE_UINT64
147
$ZBX_TR_EXPR_ALLOWED_FUNCTIONS['logseverity']= array('args' => null,
148
'item_types' => array(
152
$ZBX_TR_EXPR_ALLOWED_FUNCTIONS['logsource']= array('args' => array( 0=> array('type' => 'str','mandat' => true) ),
153
'item_types' => array(
158
$ZBX_TR_EXPR_ALLOWED_FUNCTIONS['regexp']= array('args' => array( 0 => array('type' => 'str','mandat' => true) ),
159
'item_types' => array(
166
INIT_TRIGGER_EXPRESSION_STRUCTURES();
170
* Function: get_severity_style
173
* convert severity constant in to the CSS style name
176
* Eugene Grigorjev (eugene.grigorjev@zabbix.com)
181
function get_severity_style($severity)
183
if($severity == TRIGGER_SEVERITY_INFORMATION) return 'information';
184
elseif($severity == TRIGGER_SEVERITY_WARNING) return 'warning';
185
elseif($severity == TRIGGER_SEVERITY_AVERAGE) return 'average';
186
elseif($severity == TRIGGER_SEVERITY_HIGH) return 'high';
187
elseif($severity == TRIGGER_SEVERITY_DISASTER) return 'disaster';
193
* Function: get_severity_description
196
* convert severity constant in to the string representation
199
* Eugene Grigorjev (eugene.grigorjev@zabbix.com)
22
204
function get_severity_description($severity)
24
if($severity == 0) return S_NOT_CLASSIFIED;
25
else if($severity == 1) return S_INFORMATION;
26
else if($severity == 2) return S_WARNING;
27
else if($severity == 3) return S_AVERAGE;
28
else if($severity == 4) return S_HIGH;
29
else if($severity == 5) return S_DISASTER;
206
if($severity == TRIGGER_SEVERITY_NOT_CLASSIFIED) return S_NOT_CLASSIFIED;
207
else if($severity == TRIGGER_SEVERITY_INFORMATION) return S_INFORMATION;
208
else if($severity == TRIGGER_SEVERITY_WARNING) return S_WARNING;
209
else if($severity == TRIGGER_SEVERITY_AVERAGE) return S_AVERAGE;
210
else if($severity == TRIGGER_SEVERITY_HIGH) return S_HIGH;
211
else if($severity == TRIGGER_SEVERITY_DISASTER) return S_DISASTER;
217
* Function: get_trigger_value_style
220
* convert trigger value in to the CSS style name
223
* Eugene Grigorjev (eugene.grigorjev@zabbix.com)
228
function get_trigger_value_style($value)
230
$str_val[TRIGGER_VALUE_FALSE] = 'off';
231
$str_val[TRIGGER_VALUE_TRUE] = 'on';
232
$str_val[TRIGGER_VALUE_UNKNOWN] = 'unknown';
234
if(isset($str_val[$value]))
235
return $str_val[$value];
241
* Function: trigger_value2str
244
* convert trigger value in to the string representation
247
* Eugene Grigorjev (eugene.grigorjev@zabbix.com)
252
function trigger_value2str($value)
254
$str_val[TRIGGER_VALUE_FALSE] = S_FALSE_BIG;
255
$str_val[TRIGGER_VALUE_TRUE] = S_TRUE_BIG;
256
$str_val[TRIGGER_VALUE_UNKNOWN] = S_UNKNOWN_BIG;
258
if(isset($str_val[$value]))
259
return $str_val[$value];
265
* Function: get_realhosts_by_triggerid
268
* retrive real host for trigger
271
* Eugene Grigorjev (eugene.grigorjev@zabbix.com)
34
276
function get_realhosts_by_triggerid($triggerid)
36
278
$trigger = get_trigger_by_triggerid($triggerid);
37
if($trigger["templateid"] <> 0)
38
return get_realhosts_by_triggerid($trigger["templateid"]);
279
if($trigger['templateid'] > 0)
280
return get_realhosts_by_triggerid($trigger['templateid']);
40
282
return get_hosts_by_triggerid($triggerid);
89
343
return DBselect($sql);
92
function get_triggers_by_templateid($triggerid)
94
return DBselect("select * from triggers where templateid=$triggerid");
97
function get_hosts_by_expression($expression)
102
for($i=0,$max=strlen($expression); $i<$max; $i++)
104
if($expression[$i] == '{' && $state=="")
111
if($expression[$i] == '}' && $state=="")
114
$hosts[$host] = $host;
118
if($expression[$i] == '(' && $state == "FUNCTION")
124
if($expression[$i] == ')' && $state == "PARAMETER")
130
if($expression[$i] == ':' && $state == "HOST")
136
if($expression[$i] == '.' && ($state == "KEY" || $state == "FUNCTION"))
144
$host .= $expression[$i];
147
if($state == "KEY" || $state == "FUNCTION" || $state == "PARAMETER")
151
$sql = "select distinct * from hosts where hostid=0";
152
foreach($hosts as $host)
154
$sql .= " or host=".zbx_dbstr($host);
156
return DBselect($sql);
346
function &get_triggers_by_templateid($triggerid)
348
return DBselect('select * from triggers where templateid='.$triggerid);
352
* Function: get_hosts_by_expression
355
* retrive selection of hosts by trigger expression
358
* Eugene Grigorjev (eugene.grigorjev@zabbix.com)
363
function &get_hosts_by_expression($expression)
365
global $ZBX_CURNODEID, $ZBX_TR_EXPR_ALLOWED_MACROS, $ZBX_TR_EXPR_REPLACE_TO;
371
/* Replace all {server:key.function(param)} and {MACRO} with '$ZBX_TR_EXPR_REPLACE_TO' */
372
while(ereg(ZBX_EREG_EXPRESSION_TOKEN_FORMAT, $expr, $arr))
374
if ( $arr[ZBX_EXPRESSION_MACRO_ID] && !isset($ZBX_TR_EXPR_ALLOWED_MACROS[$arr[ZBX_EXPRESSION_MACRO_ID]]) )
379
else if( !$arr[ZBX_EXPRESSION_MACRO_ID] )
381
$hosts[] = zbx_dbstr($arr[ZBX_EXPRESSION_SIMPLE_EXPRESSION_ID + ZBX_SIMPLE_EXPRESSION_HOST_ID]);
383
$expr = $arr[ZBX_EXPRESSION_LEFT_ID].$ZBX_TR_EXPR_REPLACE_TO.$arr[ZBX_EXPRESSION_RIGHT_ID];
386
if(count($hosts) == 0) $hosts = array('0');
388
return DBselect('select distinct * from hosts where '.DBid2nodeid('hostid').'='.$ZBX_CURNODEID.
389
' and host in ('.implode(',',$hosts).')');
393
* Function: zbx_unquote_param
396
* unquote string and unescape cahrs
399
* Eugene Grigorjev (eugene.grigorjev@zabbix.com)
402
* Double quotes used only.
403
* Unquote string only if value directly in quotes.
404
* Unescape only '\\' and '\"' combination
407
function zbx_unquote_param($value)
409
$value = trim($value);
410
if ( !empty($value) && '"' == $value[0] )
411
{ /* open quotes and unescape chars */
412
$value = substr($value, 1, strlen($value)-2);
415
for ( $i=0, $max=strlen($value); $i < $max; $i++)
417
if ( $i+1 < $max && $value[$i] == '\\' && ($value[$i+1] == '\\' || $value[$i+1] == '"') )
418
$new_val .= $value[++$i];
420
$new_val .= $value[$i];
428
* Function: zbx_get_params
431
* parse list of quoted parameters
434
* Eugene Grigorjev (eugene.grigorjev@zabbix.com)
437
* Double quotes used only.
440
function zbx_get_params($string)
445
for( $param_s = $i = 0, $len = strlen($string); $i < $len; $i++)
447
switch ( $string[$i] )
455
$params[] = zbx_unquote_param(substr($string, $param_s, $i - $param_s));
460
if ( $quoted && $i+1 < $len && ($string[$i+1] == '\\' || $string[$i+1] == '"'))
468
error('Incorrect usage of quotes. ['.$string.']');
474
$params[] = zbx_unquote_param(substr($string, $param_s, $i - $param_s));
481
* Function: validate_expression
484
* check trigger expression syntax and validate values
487
* Eugene Grigorjev (eugene.grigorjev@zabbix.com)
159
492
function validate_expression($expression)
161
// echo "Validating expression: $expression<br>";
162
$exp_hosts = get_hosts_by_expression($expression);
165
// Replace all {server:key.function(param)} with 0
168
// echo "Expression:$expression<br>";
170
if (eregi('^((.)*)[ ]*(\{((.)*)\})[ ]*((.)*)$', $expression, $arr))
172
// for($i=0;$i<20;$i++)
175
// echo " $i: ",$arr[$i],"<br>";
177
if(validate_simple_expression($arr[3])!=0)
181
$expression=$arr[1]."0".$arr[6];
188
// echo "Result:$expression<br><hr>";
193
// Replace all <float> <sign> <float> <K|M|G> with 0
194
// echo "Expression:$expression<br>";
196
// The '-' must be the last character in the list, otherwise it won't work!
197
if (eregi('^((.)*)([0-9\.]+[A-Z]{0,1})[ ]*([\&\|\>\<\=\+\*\/\#-]{1})[ ]*([0-9\.]+[A-Z]{0,1})((.)*)$', $expression, $arr))
200
// for($i=0;$i<50;$i++)
203
// echo " $i: ",$arr[$i],"<br>";
205
if(validate_float($arr[3])!=0)
207
error("[".$arr[3]."] is not a float");
210
if(validate_float($arr[5])!=0)
212
error("[".$arr[5]."] is not a float");
215
$expression=$arr[1]."(0)".$arr[6];
223
// Replace all (float) with 0
224
// echo "Expression2:[$expression]<br>";
226
if (eregi('^((.)*)(\(([ 0-9\.]+)\))((.)*)$', $expression, $arr))
229
// for($i=0;$i<30;$i++)
232
// echo " $i: ",$arr[$i],"<br>";
234
if(validate_float($arr[4])!=0)
236
error("[".$arr[4]."] is not a float");
239
$expression=$arr[1]."0".$arr[5];
251
$exp_host = DBfetch($exp_hosts);
254
error("Incorrect trigger expression. Incorrect host is used.");
263
if($exp_host["status"]==HOST_STATUS_TEMPLATE)
268
} while($exp_host = DBfetch($exp_hosts));
270
if(isset($fail) && ($rows>1))
272
error("Incorrect trigger expression. You can't use template hosts".
273
" in mixed expressions.");
283
error("Incorrect trigger expression '$expression'");
494
global $ZBX_CURNODEID, $ZBX_TR_EXPR_ALLOWED_MACROS, $ZBX_TR_EXPR_REPLACE_TO, $ZBX_TR_EXPR_ALLOWED_FUNCTIONS;
496
if( empty($expression) )
498
error('Expression can\'t be empty');
504
/* Replace all {server:key.function(param)} and {MACRO} with '$ZBX_TR_EXPR_REPLACE_TO' */
505
while(ereg(ZBX_EREG_EXPRESSION_TOKEN_FORMAT, $expr, $arr))
507
if ( $arr[ZBX_EXPRESSION_MACRO_ID] && !isset($ZBX_TR_EXPR_ALLOWED_MACROS[$arr[ZBX_EXPRESSION_MACRO_ID]]) )
509
error('Unknown macro ['.$arr[ZBX_EXPRESSION_MACRO_ID].']');
512
else if( !$arr[ZBX_EXPRESSION_MACRO_ID] )
514
$host = &$arr[ZBX_EXPRESSION_SIMPLE_EXPRESSION_ID + ZBX_SIMPLE_EXPRESSION_HOST_ID];
515
$key = &$arr[ZBX_EXPRESSION_SIMPLE_EXPRESSION_ID + ZBX_SIMPLE_EXPRESSION_KEY_ID];
516
$function = &$arr[ZBX_EXPRESSION_SIMPLE_EXPRESSION_ID + ZBX_SIMPLE_EXPRESSION_FUNCTION_NAME_ID];
517
$parameter = &$arr[ZBX_EXPRESSION_SIMPLE_EXPRESSION_ID + ZBX_SIMPLE_EXPRESSION_FUNCTION_PARAM_ID];
520
$row=DBfetch(DBselect('select count(*) as cnt,min(status) as status,min(hostid) as hostid from hosts h where h.host='.zbx_dbstr($host).
521
' and '.DBid2nodeid('h.hostid').'='.$ZBX_CURNODEID
525
error('No such host ('.$host.')');
528
elseif($row['cnt']!=1)
530
error('Too many hosts ('.$host.')');
534
$h_status[$row['status']][$row['hostid']] = $row['cnt'];
537
if ( !($item = DBfetch(DBselect('select i.itemid,i.value_type from hosts h,items i where h.host='.zbx_dbstr($host).
538
' and i.key_='.zbx_dbstr($key).' and h.hostid=i.hostid '.
539
' and '.DBid2nodeid('h.hostid').'='.$ZBX_CURNODEID
542
error('No such monitored parameter ('.$key.') for host ('.$host.')');
547
if( !isset($ZBX_TR_EXPR_ALLOWED_FUNCTIONS[$function]) )
549
error('Unknown function ['.$function.']');
553
$fnc_valid = &$ZBX_TR_EXPR_ALLOWED_FUNCTIONS[$function];
555
if ( is_array($fnc_valid['item_types']) &&
556
!in_array($item['value_type'], $fnc_valid['item_types']))
558
$allowed_types = array();
559
foreach($fnc_valid['item_types'] as $type)
560
$allowed_types[] = item_value_type2str($type);
561
info('Function ('.$function.') available only for items with value types ['.implode(',',$allowed_types).']');
562
error('Incorrect value type ['.item_value_type2str($item['value_type']).'] for function ('.$function.') of key ('.$host.':'.$key.')');
566
if( !is_null($fnc_valid['args']) )
568
$parameter = zbx_get_params($parameter);
570
if( !is_array($fnc_valid['args']) )
571
$fnc_valid['args'] = array($fnc_valid['args']);
573
foreach($fnc_valid['args'] as $pid => $params)
575
if(!isset($parameter[$pid]))
577
if( !isset($params['mandat']) )
583
error('Missed mandatory parameter for function ('.$function.')');
588
if( 'sec' == $params['type']
589
&& (validate_float($parameter[$pid])!=0) )
591
error('['.$parameter[$pid].'] is not a float for function ('.$function.')');
595
if( 'sec_num' == $params['type']
596
&& (validate_ticks($parameter[$pid])!=0) )
598
error('['.$parameter[$pid].'] is not a float or counter for function ('.$function.')');
604
$expr = $arr[ZBX_EXPRESSION_LEFT_ID].$ZBX_TR_EXPR_REPLACE_TO.$arr[ZBX_EXPRESSION_RIGHT_ID];
607
if ( isset($h_status[HOST_STATUS_TEMPLATE]) && ( count($h_status) > 1 || count($h_status[HOST_STATUS_TEMPLATE]) > 1 ))
609
error("Incorrect trigger expression. You can't use template hosts".
610
" in mixed expressions.");
614
/* Replace all calculations and numbers with '$ZBX_TR_EXPR_REPLACE_TO' */
615
$expt_number = '('.$ZBX_TR_EXPR_REPLACE_TO.'|'.ZBX_EREG_NUMBER.')';
616
$expt_term = '((\('.$expt_number.'\))|('.$expt_number.'))';
617
$expr_format = '(('.$expt_term.ZBX_EREG_SIGN.$expt_term.')|(\('.$expt_term.'\)))';
618
$expr_full_format = '((\('.$expr_format.'\))|('.$expr_format.'))';
620
while($res = ereg($expr_full_format.'([[:print:]]*)$', $expr, $arr))
622
$expr = substr($expr, 0, strpos($expr, $arr[1])).$ZBX_TR_EXPR_REPLACE_TO.$arr[54];
625
if ( $ZBX_TR_EXPR_REPLACE_TO != $expr )
627
error('Incorrect trigger expression. ['.str_replace($ZBX_TR_EXPR_REPLACE_TO, ' ... ', $expr).']');
289
636
$expression, $description, $priority, $status,
290
637
$comments, $url, $deps=array(), $templateid=0)
292
// if(!check_right("Trigger","A",0))
294
// error("Insufficient permissions");
297
if(!is_null($expression)) if(validate_expression($expression)) return FALSE;
639
if( !validate_expression($expression) )
642
$triggerid=get_dbid("triggers","triggerid");
299
644
$result=DBexecute("insert into triggers".
300
" (description,priority,status,comments,url,value,error,templateid)".
301
" values (".zbx_dbstr($description).",$priority,$status,".zbx_dbstr($comments).",".
645
" (triggerid,description,priority,status,comments,url,value,error,templateid)".
646
" values ($triggerid,".zbx_dbstr($description).",$priority,$status,".zbx_dbstr($comments).",".
302
647
"".zbx_dbstr($url).",2,'Trigger just added. No status update so far.',$templateid)");
308
$triggerid = DBinsert_id($result,"triggers","triggerid");
309
add_alarm($triggerid,TRIGGER_VALUE_UNKNOWN);
653
add_event($triggerid,TRIGGER_VALUE_UNKNOWN);
311
$expression = implode_exp($expression,$triggerid);
313
DBexecute("update triggers set expression=".zbx_dbstr($expression)." where triggerid=$triggerid");
315
reset_items_nextcheck($triggerid);
317
foreach($deps as $val)
319
$result = add_trigger_dependency($triggerid, $val);
655
if( null == ($expression = implode_exp($expression,$triggerid)) )
662
DBexecute("update triggers set expression=".zbx_dbstr($expression)." where triggerid=$triggerid");
664
reset_items_nextcheck($triggerid);
666
foreach($deps as $val)
668
$result = add_trigger_dependency($triggerid, $val);
322
672
$trig_hosts = get_hosts_by_triggerid($triggerid);
685
{// create trigger for childs
336
686
$child_hosts = get_hosts_by_templateid($trig_host["hostid"]);
337
687
while($child_host = DBfetch($child_hosts))
339
$result = copy_trigger_to_host($triggerid, $child_host["hostid"]);
342
{ // delete main trigger (and recursively childs)
343
delete_trigger($triggerid);
689
if( !($result = copy_trigger_to_host($triggerid, $child_host["hostid"])))
696
{ // delete main trigger (and recursively childs)
697
delete_trigger($triggerid);
350
702
return $triggerid;
353
function copy_trigger_to_host($triggerid, $hostid)
705
/******************************************************************************
707
* Comments: !!! Don't forget sync code with C !!! *
709
******************************************************************************/
710
function get_trigger_dependences_by_triggerid($triggerid)
714
$db_deps = DBselect("select * from trigger_depends where triggerid_down=".$triggerid);
715
while($db_dep = DBfetch($db_deps))
716
$result[] = $db_dep['triggerid_up'];
721
/******************************************************************************
723
* Comments: !!! Don't forget sync code with C !!! *
725
******************************************************************************/
726
function replace_template_dependences($deps, $hostid)
728
foreach($deps as $id => $val)
730
if($db_new_dep = DBfetch(DBselect('select t.triggerid from triggers t,functions f,items i '.
731
' where t.templateid='.$val.' and f.triggerid=t.triggerid '.
732
' and f.itemid=i.itemid and i.hostid='.$hostid)))
733
$deps[$id] = $db_new_dep['triggerid'];
738
/******************************************************************************
740
* Comments: !!! Don't forget sync code with C !!! *
742
******************************************************************************/
743
function copy_trigger_to_host($triggerid, $hostid, $copy_mode = false)
355
745
$trigger = get_trigger_by_triggerid($triggerid);
358
$db_deps = DBexecute("select * from trigger_depends where triggerid_down=".$triggerid);
359
while($db_dep = DBfetch($db_deps))
360
array_push($deps, $db_dep["triggerid_up"]);
747
$deps = replace_template_dependences(
748
get_trigger_dependences_by_triggerid($triggerid),
362
751
$host_triggers = get_triggers_by_hostid($hostid, "no");
363
752
while($host_trigger = DBfetch($host_triggers))
907
* Function: implode_exp
910
* Translate localhost:procload.last(0)>10 to {12}>10
911
* And create database representation.
914
* Eugene Grigorjev (eugene.grigorjev@zabbix.com)
916
* Comments: !!! Don't forget sync code with C !!!
499
919
function implode_exp ($expression, $triggerid)
500
# Translate localhost:procload.last(0)>10 to {12}>10
502
// echo "Expression:$expression<br>";
505
for($i=0,$max=strlen($expression); $i<$max; $i++)
921
global $ZBX_TR_EXPR_ALLOWED_MACROS, $ZBX_TR_EXPR_REPLACE_TO;
923
$short_exp = $expression;
925
/* Replace all {server:key.function(param)} and {MACRO} with '$ZBX_TR_EXPR_REPLACE_TO' */
926
/* build short expression {12}>10 */
927
while(ereg(ZBX_EREG_EXPRESSION_TOKEN_FORMAT, $expr, $arr))
507
if($expression[$i] == '{')
519
if( ($expression[$i] == '}')&&($state=="") )
521
// echo "HOST:$host<BR>";
522
// echo "KEY:$key<BR>";
523
// echo "FUNCTION:$function<BR>";
524
// echo "PARAMETER:$parameter<BR>";
527
$res=DBselect("select i.itemid from items i,hosts h".
528
" where i.key_=".zbx_dbstr($key).
529
" and h.host=".zbx_dbstr($host).
530
" and h.hostid=i.hostid");
533
$itemid=$row["itemid"];
535
$res=DBexecute("insert into functions (itemid,triggerid,function,parameter)".
536
" values ($itemid,$triggerid,".zbx_dbstr($function).",".
537
zbx_dbstr($parameter).")");
542
$functionid=DBinsert_id($res,"functions","functionid");
544
$exp=$exp.'{'.$functionid.'}';
548
if($expression[$i] == '(')
550
if($state == "FUNCTION")
556
if($expression[$i] == ')')
558
if($state == "PARAMETER")
564
if(($expression[$i] == ':') && ($state == "HOST"))
569
if($expression[$i] == '.')
576
// Support for '.' in KEY
577
if($state == "FUNCTION")
580
$key=$key.".".$function;
587
$host=$host.$expression[$i];
592
$key=$key.$expression[$i];
595
if($state == "FUNCTION")
597
$function=$function.$expression[$i];
600
if($state == "PARAMETER")
602
$parameter=$parameter.$expression[$i];
605
$exp=$exp.$expression[$i];
929
if ( $arr[ZBX_EXPRESSION_MACRO_ID] && !isset($ZBX_TR_EXPR_ALLOWED_MACROS[$arr[ZBX_EXPRESSION_MACRO_ID]]) )
931
error('[ie] Unknown macro ['.$arr[ZBX_EXPRESSION_MACRO_ID].']');
934
else if( !$arr[ZBX_EXPRESSION_MACRO_ID] )
936
$s_expr = &$arr[ZBX_EXPRESSION_SIMPLE_EXPRESSION_ID];
937
$host = &$arr[ZBX_EXPRESSION_SIMPLE_EXPRESSION_ID + ZBX_SIMPLE_EXPRESSION_HOST_ID];
938
$key = &$arr[ZBX_EXPRESSION_SIMPLE_EXPRESSION_ID + ZBX_SIMPLE_EXPRESSION_KEY_ID];
939
$function = &$arr[ZBX_EXPRESSION_SIMPLE_EXPRESSION_ID + ZBX_SIMPLE_EXPRESSION_FUNCTION_NAME_ID];
940
$parameter = &$arr[ZBX_EXPRESSION_SIMPLE_EXPRESSION_ID + ZBX_SIMPLE_EXPRESSION_FUNCTION_PARAM_ID];
942
$item = DBfetch(DBselect('select i.itemid from items i,hosts h'.
943
' where i.key_='.zbx_dbstr($key).
944
' and h.host='.zbx_dbstr($host).
945
' and h.hostid=i.hostid'));
947
$item = $item["itemid"];
949
$functionid = get_dbid("functions","functionid");
951
if ( !DBexecute('insert into functions (functionid,itemid,triggerid,function,parameter)'.
952
' values ('.$functionid.','.$item.','.$triggerid.','.zbx_dbstr($function).','.
953
zbx_dbstr($parameter).')'))
957
$short_exp = str_replace($s_expr,'{'.$functionid.'}',$short_exp);
958
$expr = str_replace($s_expr,$ZBX_TR_EXPR_REPLACE_TO,$expr);
961
$expr = $arr[ZBX_EXPRESSION_LEFT_ID].$ZBX_TR_EXPR_REPLACE_TO.$arr[ZBX_EXPRESSION_RIGHT_ID];
610
967
function update_trigger_comments($triggerid,$comments)
612
if(!check_right("Trigger comment","U",$triggerid))
614
error("Insufficient permissions");
618
969
return DBexecute("update triggers set comments=".zbx_dbstr($comments).
619
970
" where triggerid=$triggerid");
630
981
update_trigger_status($db_chd_trigger["triggerid"],$status);
633
if(!check_right_on_trigger("U",$triggerid))
635
error("Insufficient permissions");
638
add_alarm($triggerid,TRIGGER_VALUE_UNKNOWN);
984
add_event($triggerid,TRIGGER_VALUE_UNKNOWN);
639
985
return DBexecute("update triggers set status=$status where triggerid=$triggerid");
642
988
# "Processor load on {HOSTNAME} is 5" to "Processor load on www.sf.net is 5"
989
function expand_trigger_description_by_data($row)
993
if(is_null($row["host"])) $row["host"] = "{HOSTNAME}";
994
$description = str_replace("{HOSTNAME}", $row["host"],$row["description"]);
998
$description = "*ERROR*";
1000
return $description;
643
1003
function expand_trigger_description_simple($triggerid)
645
$result=DBselect("select distinct t.description,h.host".
646
" from triggers t,functions f,items i,hosts h".
647
" where t.triggerid=$triggerid and f.triggerid=t.triggerid".
648
" and f.itemid=i.itemid and i.hostid=h.hostid");
651
$row = DBfetch($result);
654
$description = str_replace("{HOSTNAME}", $row["host"],$row["description"]);
658
$result = DBselect("select description from triggers where triggerid=$triggerid");
659
$row = DBfetch($result);
660
$description = $row["description"];
1005
return expand_trigger_description_by_data(
1007
DBselect("select distinct t.description,h.host".
1008
" from triggers t left join functions f on t.triggerid=f.triggerid ".
1009
" left join items i on f.itemid=i.itemid ".
1010
" left join hosts h on i.hostid=h.hostid ".
1011
" where t.triggerid=$triggerid")
666
# "Processor load on %s is 5" to "Processor load on www.sf.net is 5"
667
1016
function expand_trigger_description($triggerid)
669
1018
$description=expand_trigger_description_simple($triggerid);
682
1031
while($row=DBfetch($result))
684
if(!add_alarm($row["triggerid"],TRIGGER_VALUE_UNKNOWN,$now)) continue;
1033
if(!add_event($row["triggerid"],TRIGGER_VALUE_UNKNOWN,$now)) continue;
686
1035
DBexecute('update triggers set value='.TRIGGER_VALUE_UNKNOWN.' where triggerid='.$row["triggerid"]);
690
function add_alarm($triggerid, $value, $time=NULL)
1039
/******************************************************************************
1041
* Comments: !!! Don't forget sync code with C !!! *
1043
******************************************************************************/
1044
function add_event($triggerid, $value, $time=NULL)
692
1046
if(is_null($time)) $time = time();
694
$result = DBselect('select value from alarms where triggerid='.$triggerid.' order by clock desc',1);
1048
$result = DBselect('select value,clock from events where objectid='.$triggerid.' and object='.EVENT_OBJECT_TRIGGER.
1049
' order by clock desc',1);
695
1050
$last_value = DBfetch($result);
698
1053
if($value == $last_value['value'])
701
$result = DBexecute('insert into alarms(triggerid,clock,value) values('.$triggerid.','.$time.','.$value.')');
1056
$eventid = get_dbid("events","eventid");
1057
$result = DBexecute('insert into events(eventid,source,object,objectid,clock,value) '.
1058
' values('.$eventid.','.EVENT_SOURCE_TRIGGERS.','.EVENT_OBJECT_TRIGGER.','.$triggerid.','.$time.','.$value.')');
702
1059
if($value == TRIGGER_VALUE_FALSE || $value == TRIGGER_VALUE_TRUE)
704
$alarm_id = DBinsert_id($result,'alarms','alarmid');
705
1061
DBexesute('update alerts set retries=3,error=\'Trigger changed its status. WIll not send repeats.\''.
706
1062
' where triggerid='.$triggerid.' and repeats>0 and status='.ALERT_STATUS_NOT_SENT);
787
1147
# Update Trigger definition
1149
/******************************************************************************
1151
* Comments: !!! Don't forget sync code with C !!! *
1153
******************************************************************************/
789
1154
function update_trigger($triggerid,$expression=NULL,$description=NULL,$priority=NULL,$status=NULL,
790
1155
$comments=NULL,$url=NULL,$deps=array(),$templateid=0)
792
if(!check_right_on_trigger("U",$triggerid))
794
error("Insufficient permissions");
798
1157
$trigger = get_trigger_by_triggerid($triggerid);
799
1158
$trig_hosts = get_hosts_by_triggerid($triggerid);
800
1159
$trig_host = DBfetch($trig_hosts);
802
1161
if(is_null($expression))
1163
/* Restore expression */
804
1164
$expression = explode_exp($trigger["expression"],0);
808
if(validate_expression($expression))
1167
if ( !validate_expression($expression) )
812
1170
$exp_hosts = get_hosts_by_expression($expression);
813
$chd_hosts = get_hosts_by_templateid($trig_host["hostid"]);
1173
$chd_hosts = get_hosts_by_templateid($trig_host["hostid"]);
815
if(DBfetch($chd_hosts))
817
$exp_host = DBfetch($exp_hosts);
818
$db_chd_triggers = get_triggers_by_templateid($triggerid);
819
while($db_chd_trigger = DBfetch($db_chd_triggers))
1175
if(DBfetch($chd_hosts))
821
$chd_trig_hosts = get_hosts_by_triggerid($db_chd_trigger["triggerid"]);
822
$chd_trig_host = DBfetch($chd_trig_hosts);
1177
$exp_host = DBfetch($exp_hosts);
1178
$db_chd_triggers = get_triggers_by_templateid($triggerid);
1179
while($db_chd_trigger = DBfetch($db_chd_triggers))
1181
$chd_trig_hosts = get_hosts_by_triggerid($db_chd_trigger["triggerid"]);
1182
$chd_trig_host = DBfetch($chd_trig_hosts);
824
$newexpression = str_replace(
825
"{".$exp_host["host"].":",
826
"{".$chd_trig_host["host"].":",
830
$db_chd_trigger["triggerid"],
1184
$newexpression = str_replace(
1185
"{".$exp_host["host"].":",
1186
"{".$chd_trig_host["host"].":",
1190
$db_chd_trigger["triggerid"],
1197
replace_template_dependences($deps, $chd_trig_host['hostid']),
874
1236
$trig_host = DBfetch($trig_hosts);
877
$msg .= " from host '".$trig_host["host"]."'";
1239
$msg .= " for host '".$trig_host["host"]."'";
884
function check_right_on_trigger($permission,$triggerid)
886
$result=DBselect("select distinct h.hostid from functions f,items i,hosts h".
887
" where h.hostid=i.hostid and i.itemid=f.itemid and f.triggerid=$triggerid");
888
while($row=DBfetch($result))
889
if(check_right("Host",$permission,$row["hostid"]))
1246
function check_right_on_trigger_by_triggerid($permission,$triggerid,$accessible_hosts=null)
1248
$trigger_data = DBfetch(DBselect('select expression from triggers where triggerid='.$triggerid));
1250
if(!$trigger_data) return false;
1252
return check_right_on_trigger_by_expression($permission, explode_exp($trigger_data['expression'], 0), $accessible_hosts);
1255
function check_right_on_trigger_by_expression($permission,$expression,$accessible_hosts=null)
1257
if(is_null($accessible_hosts))
1259
global $USER_DETAILS;
1260
$accessible_hosts = get_accessible_hosts_by_user($USER_DETAILS, $permission, null, PERM_RES_IDS_ARRAY);
1262
if(!is_array($accessible_hosts)) $accessible_hosts = explode(',', $accessible_hosts);
1264
$db_hosts = get_hosts_by_expression($expression);
1265
while($host_data = DBfetch($db_hosts))
1267
if(!in_array($host_data['hostid'], $accessible_hosts)) return false;
1273
/******************************************************************************
1275
* Comments: !!! Don't forget sync code with C !!! *
1277
******************************************************************************/
895
1278
function delete_dependencies_by_triggerid($triggerid)
897
$db_deps = DBselect("select triggerid_up, triggerid_down from trigger_depends".
898
" where triggerid_down=".$triggerid);
1280
$db_deps = DBselect('select triggerid_up, triggerid_down from trigger_depends'.
1281
' where triggerid_down='.$triggerid);
899
1282
while($db_dep = DBfetch($db_deps))
901
delete_trigger_dependency($db_dep["triggerid_down"],$db_dep["triggerid_up"]);
906
function delete_trigger_dependency($triggerid_down, $triggerid_up)
908
$result = DBexecute("select triggerid_up from trigger_depends".
909
" where triggerid_up=$triggerid_up and triggerid_down=$triggerid_down");
910
while($row=DBfetch($result))
912
DBexecute("update triggers set dep_level=dep_level-1".
913
" where triggerid=".$row["triggerid_up"]);
916
DBexecute("delete from trigger_depends".
917
" where triggerid_up=$triggerid_up and triggerid_down=$triggerid_down");
1284
DBexecute('update triggers set dep_level=dep_level-1 where triggerid='.$db_dep['triggerid_up']);
1285
DBexecute('delete from trigger_depends'.
1286
' where triggerid_up='.$db_dep['triggerid_up'].
1287
' and triggerid_down='.$db_dep['triggerid_down']);
1292
/******************************************************************************
1294
* Comments: !!! Don't forget sync code with C !!! *
1296
******************************************************************************/
922
1297
function insert_dependency($triggerid_down,$triggerid_up)
924
$result=DBexecute("insert into trigger_depends (triggerid_down,triggerid_up)".
925
" values ($triggerid_down,$triggerid_up)");
1299
$triggerdepid = get_dbid("trigger_depends","triggerdepid");
1300
$result=DBexecute("insert into trigger_depends (triggerdepid,triggerid_down,triggerid_up)".
1301
" values ($triggerdepid,$triggerid_down,$triggerid_up)");
1013
1413
return strcmp($expr1,$trig2["expression"]);
1016
function delete_template_triggers_by_hostid($hostid)
1417
* Function: delete_template_triggers
1420
* Delete template triggers
1423
* Eugene Grigorjev (eugene.grigorjev@zabbix.com)
1425
* Comments: !!! Don't forget sync code with C !!!
1428
function delete_template_triggers($hostid, $templateid = null, $unlink_mode = false)
1018
1430
$triggers = get_triggers_by_hostid($hostid);
1019
1431
while($trigger = DBfetch($triggers))
1021
1433
if($trigger["templateid"]==0) continue;
1022
delete_trigger($trigger["triggerid"]);
1435
if($templateid != null)
1437
if( !is_array($templateid))
1438
$templateid = array($templateid);
1440
$db_tmp_hosts = get_hosts_by_triggerid($trigger["templateid"]);
1441
$tmp_host = DBfetch($db_tmp_hosts);
1443
if( !in_array($tmp_host["hostid"], $templateid) )
1449
if(DBexecute("update triggers set templateid=0 where triggerid=".$trigger["triggerid"]))
1451
info("Trigger '".$trigger["description"]."' unlinked");
1456
delete_trigger($trigger["triggerid"]);
1028
function sync_triggers_with_template($hostid)
1464
* Function: copy_template_triggers
1467
* Copy triggers from template
1470
* Eugene Grigorjev (eugene.grigorjev@zabbix.com)
1472
* Comments: !!! Don't forget sync code with C !!!
1475
function copy_template_triggers($hostid, $templateid = null, $copy_mode = false)
1030
$host = get_host_by_hostid($hostid);
1031
$triggers = get_triggers_by_hostid($host["templateid"]);
1477
if(null == $templateid)
1479
$templateid = array_keys(get_templates_by_hostid($hostid));
1482
if(is_array($templateid))
1484
foreach($templateid as $id)
1485
copy_template_triggers($hostid, $id, $copy_mode); // attention recursion
1489
$triggers = get_triggers_by_hostid($templateid);
1032
1490
while($trigger = DBfetch($triggers))
1034
copy_trigger_to_host($trigger["triggerid"], $hostid);
1038
function get_triggers_overview($groupid)
1492
copy_trigger_to_host($trigger["triggerid"], $hostid, $copy_mode);
1495
update_template_dependences_for_host($hostid);
1499
* Function: update_template_dependences_for_host
1502
* Update template triggers
1505
* Eugene Grigorjev (eugene.grigorjev@zabbix.com)
1507
* Comments: !!! Don't forget sync code with C !!!
1510
function update_template_dependences_for_host($hostid)
1512
$db_triggers = get_triggers_by_hostid($hostid);
1513
while($trigger_data = DBfetch($db_triggers))
1515
$db_chd_triggers = get_triggers_by_templateid($trigger_data['triggerid']);
1516
while($chd_trigger_data = DBfetch($db_chd_triggers))
1517
update_trigger($chd_trigger_data['triggerid'],
1518
/*$expression*/ NULL,
1519
/*$description*/ NULL,
1524
replace_template_dependences(
1525
get_trigger_dependences_by_triggerid($trigger_data['triggerid']),
1527
$trigger_data['triggerid']);
1533
* Function: get_triggers_overview
1536
* Retrive table with overview of triggers
1539
* Eugene Grigorjev (eugene.grigorjev@zabbix.com)
1541
* Comments: !!! Don't forget sync code with C !!!
1544
function get_triggers_overview($groupid, $nodeid)
1546
global $USER_DETAILS;
1040
1548
$table = new CTableInfo(S_NO_TRIGGERS_DEFINED);
1041
1549
if($groupid > 0)
1076
1589
$table_row = array(nbsp($descr));
1077
1590
foreach($hosts as $hostname)
1080
1596
if(isset($trhosts[$hostname]))
1082
if($trhosts[$hostname]['value'] == TRIGGER_VALUE_FALSE) $style = 'normal';
1083
elseif($trhosts[$hostname]['value'] == TRIGGER_VALUE_UNKNOWN) $style = 'unknown_trigger';
1084
else $style = 'high';
1086
if((time(NULL)-$trhosts[$hostname]['lastchange'])<300) $style .= '_blink1';
1087
elseif((time(NULL)-$trhosts[$hostname]['lastchange'])<900) $style .= '_blink2';
1089
array_push($table_row,new CCol(SPACE,$style));
1599
switch($trhosts[$hostname]['value'])
1601
case TRIGGER_VALUE_TRUE:
1602
$css_class = get_severity_style($trhosts[$hostname]['priority']);
1603
if( ($ack = get_last_event_by_triggerid($trhosts[$hostname]['triggerid'])) )
1604
$ack_menu = array(S_ACKNOWLEDGE, 'acknow.php?eventid='.$ack['eventid'], array('tw'=>'_blank'));
1606
if ( 1 == $ack['acknowledged'] )
1607
$ack = new CImg('images/general/tick.png','ack');
1612
case TRIGGER_VALUE_FALSE:
1613
$css_class = 'normal';
1616
$css_class = 'unknown_trigger';
1619
$style = 'cursor: pointer; ';
1621
if((time(NULL)-$trhosts[$hostname]['lastchange'])<300)
1622
$style .= 'background-image: url(images/gradients/blink1.gif); '.
1623
'background-position: top left; '.
1624
'background-repeat: repeate;';
1625
elseif((time(NULL)-$trhosts[$hostname]['lastchange'])<900)
1626
$style .= 'background-image: url(images/gradients/blink2.gif); '.
1627
'background-position: top left; '.
1628
'background-repeat: repeate;';
1631
$tr_ov_menu = array(
1632
/* name, url, (target [tw], statusbar [sb]), css, submenu */
1633
array(S_TRIGGER, null, null,
1634
array('outer'=> array('pum_oheader'), 'inner'=>array('pum_iheader'))
1636
array(S_EVENTS, 'tr_events.php?triggerid='.$trhosts[$hostname]['triggerid'], array('tw'=>'_blank'))
1639
if(isset($ack_menu)) $tr_ov_menu[] = $ack_menu;
1641
$db_items = DBselect('select distinct i.itemid, i.description, i.key_, i.value_type '.
1642
' from items i, functions f '.
1643
' where f.itemid=i.itemid and f.triggerid='.$trhosts[$hostname]['triggerid']);
1645
while($item_data = DBfetch($db_items))
1647
$description = item_description($item_data['description'], $item_data['key_']);
1648
switch($item_data['value_type'])
1650
case ITEM_VALUE_TYPE_UINT64:
1651
case ITEM_VALUE_TYPE_FLOAT:
1652
$action = 'showgraph';
1653
$status_bar = S_SHOW_GRAPH_OF_ITEM.' \''.$description.'\'';
1655
case ITEM_VALUE_TYPE_LOG:
1656
case ITEM_VALUE_TYPE_STR:
1657
case ITEM_VALUE_TYPE_TEXT:
1659
$action = 'showlatest';
1660
$status_bar = S_SHOW_VALUES_OF_ITEM.' \''.$description.'\'';
1664
if(strlen($description) > 25) $description = substr($description,0,22).'...';
1666
$item_menu[$action][] = array(
1668
'history.php?action='.$action.'&itemid='.$item_data['itemid'].'&period=3600',
1669
array('tw'=>'_blank', 'sb'=>$status_bar));
1671
if(isset($item_menu['showgraph']))
1673
$tr_ov_menu[] = array(S_GRAPHS, null, null,
1674
array('outer'=> array('pum_oheader'), 'inner'=>array('pum_iheader'))
1676
$tr_ov_menu = array_merge($tr_ov_menu, $item_menu['showgraph']);
1678
if(isset($item_menu['showlatest']))
1680
$tr_ov_menu[] = array(S_VALUES, null, null,
1681
array('outer'=> array('pum_oheader'), 'inner'=>array('pum_iheader'))
1683
$tr_ov_menu = array_merge($tr_ov_menu, $item_menu['showlatest']);
1689
$status_col = new CCol(array(SPACE, $ack),$css_class);
1692
$status_col->AddOption('style', $style);
1695
if(isset($tr_ov_menu))
1697
$tr_ov_menu = new CPUMenu($tr_ov_menu,170);
1698
$status_col->OnClick($tr_ov_menu->GetOnActionJS());
1699
$status_col->AddAction('onmouseover',
1700
'this.old_border=this.style.border; this.style.border=\'1px dotted #0C0CF0\'');
1701
$status_col->AddAction('onmouseout', 'this.style.border=this.old_border;');
1703
array_push($table_row,$status_col);
1091
1705
$table->AddRow($table_row);
1710
function get_function_by_functionid($functionid)
1712
$result=DBselect("select * from functions where functionid=$functionid");
1713
$row=DBfetch($result);
1720
error("No function with functionid=[$functionid]");
1725
function calculate_availability($triggerid,$period_start,$period_end)
1727
$sql='select count(*) as cnt,min(clock) as minn,max(clock) as maxx from events '.
1728
' where objectid='.$triggerid.' and object='.EVENT_OBJECT_TRIGGER;
1730
if($period_start!=0) $sql .= ' and clock>='.$period_start;
1731
if($period_end!=0) $sql .= ' and clock<='.$period_end;
1733
$row=DBfetch(DBselect($sql));
1741
if(($period_start==0)&&($period_end==0))
1748
$ret["true_time"] = 0;
1749
$ret["false_time"] = 0;
1750
$ret["unknown_time"] = 0;
1753
$ret["unknown"] = 100;
1758
$result=DBselect('select clock,value from events where objectid='.$triggerid.' and object='.EVENT_OBJECT_TRIGGER
1759
.' and clock>='.$min.' and clock<='.$max);
1767
if(($period_start==0)&&($period_end==0))
1772
while($row=DBfetch($result))
1774
$clock=$row["clock"];
1775
$value=$row["value"];
1794
$unknown_time+=$diff;
1809
$unknown_time+=$diff;
1817
$trigger = get_trigger_by_triggerid($triggerid);
1818
$state = $trigger['value'];
1823
$false_time=$false_time+$max-$time;
1827
$true_time=$true_time+$max-$time;
1831
$unknown_time=$unknown_time+$max-$time;
1834
$total_time=$true_time+$false_time+$unknown_time;
1838
$ret["true_time"] = 0;
1839
$ret["false_time"] = 0;
1840
$ret["unknown_time"] = 0;
1843
$ret["unknown"] = 100;
1847
$ret["true_time"] = $true_time;
1848
$ret["false_time"] = $false_time;
1849
$ret["unknown_time"] = $unknown_time;
1850
$ret["true"] = (100*$true_time)/$total_time;
1851
$ret["false"] = (100*$false_time)/$total_time;
1852
$ret["unknown"] = (100*$unknown_time)/$total_time;