Категории

Как я добавил мониторинг системных сервисов в свою IoT-суперпанель

2025-09-17 18:24:51 | IOT умный дом
Как добавить мониторинг сервисов в IoT-панель на Raspberry Pi

У меня есть веб-панель на Raspberry Pi, которая показывает данные с датчиков, автоматизации, графики и статус самой малинки. Но однажды я понял — я не вижу, работают ли вообще мои ключевые сервисы: iot-automation.service и mqtt-to-mysql.service. А если упадут — я узнаю слишком поздно.

Решил добавить простую, но важную фичу — карточку со статусами сервисов прямо в блок мониторинга RPi. Без лишних движений — только PHP + systemd.

📌 Что делаем

🛠️ Что добавить в PHP-код (перед началом HTML)

// === Проверка статусов системных сервисов ===
$services_to_check = [
    'iot-automation.service',
    'mqtt-to-mysql.service',
    // можно добавить другие: 'mosquitto.service', 'nginx.service' и т.д.
];

$service_statuses = [];

foreach ($services_to_check as $service) {
    // ВАЖНО: если www-data не имеет прав — добавь sudo
    // и настрой /etc/sudoers: www-data ALL=(ALL) NOPASSWD: /bin/systemctl is-active *
    $command = "systemctl is-active " . escapeshellarg($service) . " 2>&1";
    $status = trim(shell_exec($command));
    $is_active = ($status === 'active');

    $service_statuses[] = [
        'name' => $service,
        'status' => $status,
        'is_active' => $is_active,
        'color' => $is_active ? 'ok' : 'critical'  // используем уже существующие CSS-классы
    ];
}

🧩 Куда вставить карточку в HTML

Вставляем внутрь блока

, рядом с карточками "Статус железа" и "Анализ логов".

Вот как выглядит финальная структура (уже с вставленной карточкой):


<!-- Raspberry Pi Monitoring Card -->
<?php if ($rpi_data): ?>
<div class="group-section" id="rpi-monitor">
    <h2 onclick="toggleGroup(this)">
         Raspberry Pi Статус
        <span class="arrow">▼</span>
    </h2>
    <div class="grid group-content" id="group-content-rpi-monitor">

        <!-- Карточка: Статус железа -->
        <div class="card">
            <?php
            $temp = floatval($rpi_data['cpu_temp'] ?? 0);
            $temp_class = $temp > 70 ? 'critical' : ($temp > 60 ? 'warning' : 'ok');
            $disk = floatval($rpi_data['disk_usage'] ?? 0);
            $disk_class = $disk > 90 ? 'critical' : ($disk > 60 ? 'warning' : 'ok');
            ?>

            <div class="title">🖥️ Статус железа</div>
            <hr>

            <div class="value">🌡️ Температура CPU: <strong class="<?= $temp_class ?>"><?= htmlspecialchars($rpi_data['cpu_temp']) ?>°C</strong></div>
            <div class="value">⚡ Загрузка CPU: <strong><?= htmlspecialchars($rpi_data['cpu_load']) ?>%</strong></div>
            <div class="value">🧠 Память: <strong><?= htmlspecialchars($rpi_data['mem_used']) ?>MB / <?= htmlspecialchars($rpi_data['mem_total']) ?>MB</strong></div>
            <div class="value">💽 Диск: <strong class="<?= $disk_class ?>"><?= htmlspecialchars($rpi_data['disk_usage']) ?>%</strong></div>
            <div class="value">🔋 Напряжение ядра: <strong><?= htmlspecialchars($rpi_data['volt_core'] ?? 'N/A') ?>V</strong></div>

            <hr>

            <div class="timestamp">🏠 IP: <?= htmlspecialchars($rpi_data['ip_addresses']) ?></div>
            <div class="timestamp">⏱️ Uptime: <?= htmlspecialchars($rpi_data['uptime']) ?></div>
            <div class="timestamp">🕒 Последнее обновление: <?= htmlspecialchars($rpi_data['timestamp']) ?></div>
        </div>

        <!-- Карточка: Анализ логов -->
        <?php if (!empty($log_stats)): ?>
        <div class="card">
            <div class="title">📊 Анализ логов (<?= date('Y-m-d') ?>)</div>
            <hr>
            <div class="value">
                <?php foreach ($log_stats as $keyword => $count): ?>
                    <div><?= ucfirst(htmlspecialchars($keyword)) ?>: <strong><?= $count ?></strong></div>
                <?php endforeach; ?>
            </div>
            <small class="timestamp">Обновляется каждый час</small>
        </div>
        <?php endif; ?>

        <!-- Карточка: Активность сервисов (впихиваем сюда!) -->
        <div class="card">
            <div class="title">🔧 Активность сервисов</div>
            <?php foreach ($service_statuses as $svc): ?>
                <div class="value">
                    <strong><?= htmlspecialchars($svc['name']) ?>:</strong>
                    <span class="<?= $svc['color'] ?>">
                        <?= $svc['is_active'] ? '✅' : '❌' ?> <?= htmlspecialchars($svc['status']) ?>
                    </span>
                </div>
            <?php endforeach; ?>
            <div class="timestamp">🕒 Проверено: <?= date('H:i:s') ?></div>
        </div>

    </div> <!-- .group-content -->
</div> <!-- .group-section -->
<?php endif; ?>

🔐 Важно: права для www-data

Если при выполнении команды ничего не возвращается или пишет "permission denied" — нужно дать права веб-серверу.

Открой sudo visudo и добавь строку:

www-data ALL=(ALL) NOPASSWD: /bin/systemctl is-active *

Теперь PHP сможет проверять статусы без пароля.

💡 Зачем это

  • Видишь сразу — живы ли твои демоны.
  • Не надо лезть в консоль или писать отдельные скрипты.
  • Цветовая индикация — сразу бросается в глаза, если что-то упало.
  • Интегрировано в существующий интерфейс — ничего не ломается.

🚀 Что дальше

  • Добавить кнопки "Перезапустить" с подтверждением (через AJAX + PHP-скрипт с sudo systemctl restart).
  • Логировать последние 5 строк лога сервиса при падении.
  • Отправлять телеграм-уведомление, если сервис упал (через cron или прямо в PHP).

Но даже в таком виде — уже полезно. Я теперь вижу всё на одной панели: и датчики, и RPi, и сервисы. И сплю спокойно.

Комментарии

Пока нет комментариев. Будьте первым!

Оставить комментарий

← Назад к списку статей

Важно: Блог-эксперимент

Внимание: Cтатьи здесь сгенерированны через нейросеть, не правил ошибки, да и не до этого пока. Блог только запустил. Просто чтобы вы знали и не запускали ядерный реактор по моим статьям ))
НО!
Каждый кейс я делал минимум один раз. Сервера стоят, клиенты довольны, дата-центры не горят.

Если у вас есть вопросы, или Нашли неточность? пишите в коментах — вместе поправим и сделаем статью более качественной. Я лично объясню нюансы из практики.

Посетителей сегодня: 0


© Digital Specialist | Не являемся сотрудниками Google, Яндекса и NASA
Кто я | HSH | Контакты и регион