Add display_metrics setting per server
- Add display_metrics JSON field to servers table - Update server edit form with metric checkboxes - ServerDetailController now uses server's display_metrics setting - If no metrics selected - show all (backward compatibility) - Removed hardcoded metric names from queries
This commit is contained in:
parent
a11cfb5165
commit
e20354e89d
|
|
@ -141,6 +141,17 @@ class ServerController extends Model
|
|||
$tokenRow = $stmt->fetch();
|
||||
$decryptedToken = $tokenRow ? \App\Utils\EncryptionHelper::decrypt($tokenRow['encrypted_token']) : null;
|
||||
|
||||
// Получаем все метрики которые есть у серве<D0B2><D0B5>а
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT DISTINCT mn.id, mn.name, mn.unit
|
||||
FROM metric_names mn
|
||||
JOIN server_metrics sm ON sm.metric_name_id = mn.id
|
||||
WHERE sm.server_id = :server_id
|
||||
ORDER BY mn.name
|
||||
");
|
||||
$stmt->execute([':server_id' => $id]);
|
||||
$allMetrics = $stmt->fetchAll();
|
||||
|
||||
if (!$server) {
|
||||
return $response->withHeader('Location', '/servers')->withStatus(302);
|
||||
}
|
||||
|
|
@ -149,7 +160,8 @@ class ServerController extends Model
|
|||
'title' => 'Редактировать сервер',
|
||||
'server' => $server,
|
||||
'groups' => $groups,
|
||||
'agent_token' => $decryptedToken
|
||||
'agent_token' => $decryptedToken,
|
||||
'allMetrics' => $allMetrics
|
||||
];
|
||||
|
||||
return $this->twig->render($response, 'servers/edit.twig', $templateData);
|
||||
|
|
@ -160,6 +172,10 @@ class ServerController extends Model
|
|||
$id = $args['id'];
|
||||
$params = $request->getParsedBody();
|
||||
|
||||
// Собираем выбранные метрики
|
||||
$displayMetrics = $params['display_metrics'] ?? [];
|
||||
$displayMetricsJson = json_encode(array_values($displayMetrics));
|
||||
|
||||
$stmt = $this->pdo->prepare("
|
||||
UPDATE servers
|
||||
SET name = :name,
|
||||
|
|
@ -167,7 +183,8 @@ class ServerController extends Model
|
|||
group_id = :group_id,
|
||||
description = :description,
|
||||
offline_timeout = :offline_timeout,
|
||||
notify_on_offline = :notify_on_offline
|
||||
notify_on_offline = :notify_on_offline,
|
||||
display_metrics = :display_metrics
|
||||
WHERE id = :id
|
||||
");
|
||||
|
||||
|
|
@ -178,7 +195,8 @@ class ServerController extends Model
|
|||
':group_id' => $params['group_id'] ?? null,
|
||||
':description' => $params['description'] ?? '',
|
||||
':offline_timeout' => (int)($params['offline_timeout'] ?? 300),
|
||||
':notify_on_offline' => isset($params['notify_on_offline']) ? 1 : 0
|
||||
':notify_on_offline' => isset($params['notify_on_offline']) ? 1 : 0,
|
||||
':display_metrics' => $displayMetricsJson
|
||||
]);
|
||||
|
||||
if ($result) {
|
||||
|
|
|
|||
|
|
@ -38,6 +38,16 @@ class ServerDetailController extends Model
|
|||
return $response->withHeader('Location', '/servers')->withStatus(302);
|
||||
}
|
||||
|
||||
// Получаем настройки отображаемых метрик
|
||||
$displayMetricsSetting = $server['display_metrics'] ?? null;
|
||||
$displayMetrics = null;
|
||||
if ($displayMetricsSetting) {
|
||||
$decoded = json_decode($displayMetricsSetting, true);
|
||||
if (is_array($decoded) && count($decoded) > 0) {
|
||||
$displayMetrics = $decoded;
|
||||
}
|
||||
}
|
||||
|
||||
// Получаем параметры
|
||||
$queryParams = $request->getQueryParams();
|
||||
$startDate = $queryParams['start'] ?? null;
|
||||
|
|
@ -121,6 +131,19 @@ class ServerDetailController extends Model
|
|||
$startStr = $startDate->format('Y-m-d H:i:s');
|
||||
$endStr = $endDate->format('Y-m-d H:i:s');
|
||||
|
||||
// Формируем фильтр метрик из настроек сервера
|
||||
$metricsFilter = '';
|
||||
$metricParams = [];
|
||||
if ($displayMetrics) {
|
||||
$placeholders = [];
|
||||
foreach ($displayMetrics as $i => $m) {
|
||||
$key = ':metric_' . $i;
|
||||
$placeholders[] = $key;
|
||||
$metricParams[$key] = $m;
|
||||
}
|
||||
$metricsFilter = 'AND mn.name IN (' . implode(', ', $placeholders) . ')';
|
||||
}
|
||||
|
||||
// Запрос с агрегацией если нужно
|
||||
if ($groupBy) {
|
||||
// Оптимизированный запрос с подзапросом и LIMIT для больших периодов
|
||||
|
|
@ -140,15 +163,13 @@ class ServerDetailController extends Model
|
|||
LIMIT 200000
|
||||
) sm
|
||||
INNER JOIN metric_names mn ON mn.id = sm.metric_name_id
|
||||
WHERE mn.name IN ('cpu_load', 'ram_used', 'ram_total_gb', 'disk_used', 'disk_used_root',
|
||||
'disk_used_home', 'disk_used_boot', 'disk_total_gb_root', 'disk_total_gb_home',
|
||||
'temp_cpu', 'temp_disk_sda', 'temp_disk_sdb', 'temp_disk_sdc',
|
||||
'net_in_enp4s0', 'net_out_enp4s0', 'disk_used_mnt_data')
|
||||
WHERE 1=1 {$metricsFilter}
|
||||
{$groupBy}
|
||||
ORDER BY time_bucket ASC
|
||||
";
|
||||
$stmt = $this->pdo->prepare($sql);
|
||||
$stmt->execute([':id' => $id, ':start_date' => $startStr, ':end_date' => $endStr]);
|
||||
$executeParams = array_merge([':id' => $id, ':start_date' => $startStr, ':end_date' => $endStr], $metricParams);
|
||||
$stmt->execute($executeParams);
|
||||
} else {
|
||||
$sql = "
|
||||
SELECT sm.value, mn.name, mn.unit, sm.created_at
|
||||
|
|
@ -158,15 +179,13 @@ class ServerDetailController extends Model
|
|||
WHERE sm.server_id = :id
|
||||
AND sm.created_at >= :start_date
|
||||
AND sm.created_at <= :end_date
|
||||
AND mn.name IN ('cpu_load', 'ram_used', 'ram_total_gb', 'disk_used', 'disk_used_root',
|
||||
'disk_used_home', 'disk_used_boot', 'disk_total_gb_root', 'disk_total_gb_home',
|
||||
'temp_cpu', 'temp_disk_sda', 'temp_disk_sdb', 'temp_disk_sdc',
|
||||
'net_in_enp4s0', 'net_out_enp4s0', 'disk_used_mnt_data')
|
||||
{$metricsFilter}
|
||||
ORDER BY sm.created_at ASC
|
||||
LIMIT 5000
|
||||
";
|
||||
$stmt = $this->pdo->prepare($sql);
|
||||
$stmt->execute([':id' => $id, ':start_date' => $startStr, ':end_date' => $endStr]);
|
||||
$executeParams = array_merge([':id' => $id, ':start_date' => $startStr, ':end_date' => $endStr], $metricParams);
|
||||
$stmt->execute($executeParams);
|
||||
}
|
||||
|
||||
$metrics = $stmt->fetchAll();
|
||||
|
|
|
|||
|
|
@ -39,6 +39,29 @@
|
|||
<small class="form-text text-muted">Дополнительная информация о сервере</small>
|
||||
</div>
|
||||
|
||||
{% if allMetrics|length > 0 %}
|
||||
<hr>
|
||||
<h5 class="mb-3"><i class="fas fa-chart-line"></i> Отображаемые метрики</h5>
|
||||
<p class="text-muted small">Выберите метрики, которые будут показываться на графиках. Пустой выбор = все метрики.</p>
|
||||
|
||||
<div class="row mb-3">
|
||||
{% set savedMetrics = server.display_metrics|json_decode ?: [] %}
|
||||
{% for metric in allMetrics %}
|
||||
<div class="col-md-4 col-lg-3 mb-2">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="display_metrics[]"
|
||||
id="metric_{{ metric.name }}" value="{{ metric.name }}"
|
||||
{% if metric.name in savedMetrics %}checked{% endif %}>
|
||||
<label class="form-check-label" for="metric_{{ metric.name }}">
|
||||
{{ metric.name }}
|
||||
{% if metric.unit %}({{ metric.unit }}){% endif %}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<hr>
|
||||
|
||||
<h5 class="mb-3"><i class="fas fa-wifi"></i> Настройки мониторинга недоступности</h5>
|
||||
|
|
|
|||
Loading…
Reference in New Issue