Anomaly Alert Builder
Creates alerts when a metric exceeds expected ranges or changes sharply.
Function signature
ogBuildAnomalyAlerts(values = array(), options = array())
Categories
- Analytics and Reports
Parameters
valuesNumeric values or rows with value/label keys.optionsOptions: min, max, percent_change_limit. Recognized keys: `max`, `min`, `percent_change_limit`.Return value
Short public-safe status message.
- alerts
- alert_count
Compatibility
Existing function name and call order preserved; metadata signature corrected to source.
Minimum PHP version: 7.4
Security notes
Validate request method, identity, permissions, policy arrays, URLs, signatures, and caller-owned allowlists before use; keep secrets and internal paths out of public output.
Code
<?php
/*
* Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
* Free for personal and internal use. Paid project use requires visible credit
* to Jeffery L. Paris. Corporate use requires a paid license fee unless a
* separate written license states otherwise.
*/
/**
* Creates alerts when metric values exceed configured ranges or change sharply.
*
* @param array $values Numeric values or rows with value/label keys.
* @param array $options Options: min, max, percent_change_limit.
* @return array Anomaly alert list.
*/
function ogBuildAnomalyAlerts($values = array(), $options = array()) {
$result = array(
'success' => false,
'message' => '',
'data' => array()
);
if (!is_array($values)) {
$result['message'] = 'Values must be an array.';
return $result;
}
if (!is_array($options)) {
$options = array();
}
$minimum_limit = null;
$maximum_limit = null;
$change_limit = 50;
if (isset($options['min']) && is_numeric($options['min'])) {
$minimum_limit = (float)$options['min'];
}
if (isset($options['max']) && is_numeric($options['max'])) {
$maximum_limit = (float)$options['max'];
}
if (!empty($options['percent_change_limit']) && is_numeric($options['percent_change_limit'])) {
$change_limit = (float)$options['percent_change_limit'];
}
$alerts = array();
$previous = null;
foreach ($values as $index => $row) {
$label = (string)$index;
$value = null;
if (is_array($row)) {
if (!empty($row['label'])) {
$label = (string)$row['label'];
}
if (isset($row['value']) && is_numeric($row['value'])) {
$value = (float)$row['value'];
}
} elseif (is_numeric($row)) {
$value = (float)$row;
}
if ($value === null) {
continue;
}
if ($minimum_limit !== null && $value < $minimum_limit) {
$alerts[] = array('label' => $label, 'type' => 'below_minimum', 'value' => $value, 'limit' => $minimum_limit);
}
if ($maximum_limit !== null && $value > $maximum_limit) {
$alerts[] = array('label' => $label, 'type' => 'above_maximum', 'value' => $value, 'limit' => $maximum_limit);
}
if ($previous !== null && $previous != 0) {
$change = (($value - $previous) / abs($previous)) * 100;
if (abs($change) >= $change_limit) {
$alerts[] = array('label' => $label, 'type' => 'sharp_change', 'value' => $value, 'percent_change' => $change);
}
}
$previous = $value;
}
$result['success'] = true;
$result['message'] = 'Anomaly alerts built.';
$result['data'] = array('alerts' => $alerts, 'alert_count' => count($alerts));
return $result;
}