Files
thetool/application/DeviceMonitoring/DeviceMonitoringController.php
2025-06-29 20:33:54 +02:00

179 lines
5.7 KiB
PHP

<?php
class DeviceMonitoringController extends mfBaseController
{
private string $ZABBIX_API_URL = ZABBIX_API_URL;
private string $ZABBIX_API_KEY = ZABBIX_API_KEY;
private ?Zabbix $zabbix = null;
protected function init(): void
{
$this->needlogin = true;
$me = new User();
$me->loadMe();
$this->layout()->set("me", $me);
$this->me = $me;
if (!$this->me->is("Admin")) {
http_response_code(403);
self::returnJson(['success' => false, 'message' => 'Permission denied']);
die();
}
if (defined('ZABBIX_API_URL') && defined('ZABBIX_API_KEY') && ZABBIX_API_URL && ZABBIX_API_KEY) {
$this->zabbix = new Zabbix($this->ZABBIX_API_URL, $this->ZABBIX_API_KEY);
} else {
http_response_code(500);
self::returnJson(['error' => 'Zabbix API is not configured on the server.']);
die();
}
$this->postData = json_decode(file_get_contents('php://input'), true) ?? [];
}
/**
* Gets a list of all available interfaces, grouping Sent/Received items.
*/
protected function listInterfacesAction()
{
$hostId = $this->request->hostId;
$items = $this->zabbix->getHostInterfaceItems($hostId);
$interfaces = [];
foreach ($items as $item) {
$baseName = preg_replace('/:\s*Bits\s*(sent|received)$/i', '', $item['name']);
$direction = str_contains(strtolower($item['name']), 'received') ? 'rx' : 'tx';
if (!isset($interfaces[$baseName])) {
$interfaces[$baseName] = ['name' => $baseName, 'rx' => null, 'tx' => null];
}
$interfaces[$baseName][$direction] = $item;
}
$sortedInterfaces = array_values($interfaces);
usort($sortedInterfaces, fn($a, $b) => strcmp($a['name'], $b['name']));
self::returnJson($sortedInterfaces);
}
/**
* Gets historical data for a specific list of item IDs.
*/
protected function interfaceDataAction()
{
$itemIds = $this->postData['itemIds'] ?? [];
if (empty($itemIds)) {
self::returnJson([]);
return;
}
$timeRange = $this->postData['timeRange'] ?? '24h';
$time_from = strtotime('-' . str_replace(['m', 'h', 'd'], [' minutes', ' hours', ' days'], $timeRange));
$params = [
'itemids' => $itemIds,
'output' => 'extend',
'history' => 3, // Numeric (unsigned)
'sortfield' => 'clock',
'sortorder' => 'ASC',
'time_from' => $time_from,
];
$history = $this->zabbix->zabbixRequest('history.get', $params)['result'] ?? [];
$historyByItemId = [];
foreach ($history as $point) {
$historyByItemId[$point['itemid']][] = [
'x' => intval($point['clock']) * 1000,
'y' => round(floatval($point['value']) / 1000000, 2)
];
}
self::returnJson($historyByItemId);
}
/**
* Gets general monitoring data (Uptime, Ping, Temp).
*/
protected function generalDataAction() {
$hostId = $this->request->hostId;
$itemsToFetch = [
'ping' => $this->zabbix->getICMPItems($hostId),
'uptime' => $this->zabbix->getUptimeItems($hostId),
];
$itemIds = [];
$itemMap = [];
foreach ($itemsToFetch as $type => $items) {
if (!empty($items)) {
foreach($items as $item) {
$itemIds[] = $item['itemid'];
$itemMap[$item['itemid']] = ['type' => $type, 'name' => $item['name'], 'units' => $item['units']];
}
}
}
$values = [];
if(!empty($itemIds)) {
$history = $this->zabbix->getItemValues($itemIds, 1);
foreach($history as $h) {
$info = $itemMap[$h['itemid']];
$values[$info['type']][] = ['name' => $info['name'], 'value' => $h['value'], 'clock' => $h['clock'], 'units' => $info['units']];
}
}
self::returnJson($values);
}
/**
* Gets Zabbix problems (triggers) for the host.
*/
protected function getProblemsAction() {
$hostId = $this->request->hostId;
$problems = $this->zabbix->zabbixRequest('problem.get', [
'hostids' => $hostId,
'output' => 'extend',
'recent' => true, // Use boolean true
'sortfield' => ['eventid'],
'sortorder' => 'DESC'
])['result'] ?? [];
self::returnJson($problems);
}
/**
* Forces a Zabbix item check and returns the latest value for live graphs.
*/
protected function liveDataAction() {
$itemId = $this->request->itemId;
if(empty($itemId)) {
http_response_code(400);
self::returnJson(['error' => 'Item ID is required.']);
return;
}
$this->zabbix->createTask($itemId);
sleep(3);
$history = $this->zabbix->getItemValues([$itemId], 1);
if(empty($history)) {
self::returnJson(null);
return;
}
$point = $history[0];
$formattedPoint = [
'x' => intval($point['clock']) * 1000,
'y' => round(floatval($point['value']) / 1000000, 2)
];
self::returnJson($formattedPoint);
}
/**
* Renders a dedicated HTML page for the live graph popup.
*/
public function liveGraphPageAction() {
$this->layout(false);
$this->layout()->set('API_BASE_URL', self::getUrl("DeviceMonitoring"));
$this->layout()->setTemplate('Device/LiveGraph');
}
}