179 lines
5.7 KiB
PHP
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');
|
|
}
|
|
} |