mirvmon/src/Controllers/ServerDetailController.php

198 lines
7.5 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
// src/Controllers/ServerDetailController.php
namespace App\Controllers;
use App\Models\Model;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Views\Twig;
class ServerDetailController extends Model
{
private $twig;
public function __construct(Twig $twig)
{
parent::__construct();
$this->twig = $twig;
}
public function show(Request $request, Response $response, $args)
{
$id = $args['id'];
// Получаем информацию о сервере
$stmt = $this->pdo->prepare("
SELECT s.*, sg.name as group_name, sg.icon as group_icon, sg.color as group_color
FROM servers s
LEFT JOIN server_groups sg ON s.group_id = sg.id
WHERE s.id = :id
");
$stmt->execute([':id' => $id]);
$server = $stmt->fetch();
if (!$server) {
return $response->withHeader('Location', '/servers')->withStatus(302);
}
// Получаем период для выборки метрик
$period = $request->getQueryParams()['period'] ?? '24h';
// Определяем интервал времени в зависимости от периода
$interval = match($period) {
'7d' => 'INTERVAL 7 DAY',
'30d' => 'INTERVAL 30 DAY',
default => 'INTERVAL 24 HOUR'
};
// Получаем последние метрики для этого сервера
$stmt = $this->pdo->prepare("
SELECT sm.value, mn.name, mn.unit, sm.created_at
FROM server_metrics sm
JOIN metric_names mn ON sm.metric_name_id = mn.id
WHERE sm.server_id = :id
AND sm.created_at >= DATE_SUB(NOW(), {$interval})
ORDER BY sm.created_at DESC
");
$stmt->execute([':id' => $id]);
$metrics = $stmt->fetchAll();
// Группируем метрики по типу (CPU, RAM, Disk)
$groupedMetrics = [];
foreach ($metrics as $metric) {
$metricName = $metric['name'];
if (!isset($groupedMetrics[$metricName])) {
$groupedMetrics[$metricName] = [];
}
$groupedMetrics[$metricName][] = $metric;
}
// Получаем текущие пороговые значения для сервера
$stmt = $this->pdo->prepare("
SELECT mt.warning_threshold, mt.critical_threshold, mt.duration, mn.name
FROM metric_thresholds mt
JOIN metric_names mn ON mt.metric_name_id = mn.id
WHERE mt.server_id = :id
");
$stmt->execute([':id' => $id]);
$existingThresholds = [];
foreach ($stmt->fetchAll() as $threshold) {
$existingThresholds[$threshold['name']] = [
'warning' => $threshold['warning_threshold'],
'critical' => $threshold['critical_threshold'],
'duration' => $threshold['duration']
];
}
// Получаем все типы метрик
$stmt = $this->pdo->query("SELECT id, name, unit FROM metric_names WHERE name NOT LIKE '%\_proc' ORDER BY name");
$allMetricTypes = $stmt->fetchAll();
// Получаем список сервисов
$stmt = $this->pdo->prepare("
SELECT service_name, status, load_state, active_state, sub_state
FROM service_status
WHERE server_id = :server_id
ORDER BY service_name
");
$stmt->execute([':server_id' => $id]);
$allServices = $stmt->fetchAll();
// Получаем список сервисов для мониторинга из конфигурации агента
$stmt = $this->pdo->prepare("
SELECT monitor_services FROM agent_configs WHERE server_id = :server_id
");
$stmt->execute([':server_id' => $id]);
$agentConfig = $stmt->fetch();
$monitorServices = [];
if ($agentConfig && !empty($agentConfig['monitor_services'])) {
$monitorServices = json_decode($agentConfig['monitor_services'], true) ?? [];
}
$templateData = [
'title' => 'Сервер: ' . $server['name'],
'server' => $server,
'metrics' => $groupedMetrics,
'allMetricTypes' => $allMetricTypes,
'existingThresholds' => $existingThresholds,
'allServices' => $allServices,
'monitorServices' => $monitorServices,
'period' => $period,
'request' => $request->getQueryParams()
];
return $this->twig->render($response, 'servers/detail.twig', $templateData);
}
public function saveThresholds(Request $request, Response $response, $args)
{
$id = $args['id'];
$params = $request->getParsedBody();
// Получаем все типы метрик
$stmt = $this->pdo->query("SELECT id, name FROM metric_names WHERE name NOT LIKE '%\_proc' ORDER BY name");
$metricTypes = $stmt->fetchAll();
// Удаляем старые пороги для этого сервера
$stmt = $this->pdo->prepare("DELETE FROM metric_thresholds WHERE server_id = :server_id");
$stmt->execute([':server_id' => $id]);
// Добавляем новые пороги
$insertStmt = $this->pdo->prepare("
INSERT INTO metric_thresholds (server_id, metric_name_id, warning_threshold, critical_threshold, duration)
VALUES (:server_id, :metric_name_id, :warning_threshold, :critical_threshold, :duration)
");
foreach ($metricTypes as $metricType) {
$warning = $params[$metricType['name'] . '_warning'] ?? '';
$critical = $params[$metricType['name'] . '_critical'] ?? '';
$duration = $params[$metricType['name'] . '_duration'] ?? 0;
if ($warning !== '' && $critical !== '') {
$insertStmt->execute([
':server_id' => $id,
':metric_name_id' => $metricType['id'],
':warning_threshold' => $warning,
':critical_threshold' => $critical,
':duration' => $duration
]);
}
}
// Возвращаемся на страницу сервера
return $response->withHeader('Location', "/servers/{$id}")->withStatus(302);
}
public function saveServices(Request $request, Response $response, $args)
{
$id = $args['id'];
$params = $request->getParsedBody();
// Получаем список сервисов для мониторинга
$services = $params['services'] ?? [];
if (is_string($services)) {
$services = json_decode($services, true) ?? [];
}
// Обновляем конфигурацию агента
$stmt = $this->pdo->prepare("
INSERT INTO agent_configs (server_id, interval_seconds, monitor_services, enabled)
VALUES (:server_id, 60, :services, TRUE)
ON DUPLICATE KEY UPDATE
monitor_services = VALUES(monitor_services),
updated_at = CURRENT_TIMESTAMP
");
$stmt->execute([
':server_id' => $id,
':services' => json_encode($services)
]);
// Возвращаемся на страницу сервера
return $response->withHeader('Location', "/servers/{$id}?tab=services")->withStatus(302);
}
}