В современной разработке критически важно отслеживать состояние всех компонентов приложения. Особенно это актуально для production-окружений, где каждая минута простоя может стоить денег и репутации. Сегодня я хочу рассказать о пакете Laravel Monitor — инструменте для комплексного мониторинга здоровья Laravel-приложений.

Что такое Laravel Monitor?

Laravel Monitor — это пакет для Laravel, который позволяет отслеживать состояние различных компонентов вашего приложения: базы данных, Redis, файловых хранилищ, Horizon, Node.js окружения и даже проверять безопасность зависимостей через Security Checker.

Пакет предоставляет:

  • ✅ Команду Artisan для проверки всех компонентов

  • ✅ REST API для получения данных о состоянии системы

  • ✅ Возможность сохранения результатов в базу данных

  • ✅ Интеграцию с системами мониторинга (Zabbix, Nagios и т.д.)

Установка и настройка

Установка через Composer

composer require adb/laravel-monitor

Публикация конфигурации

php artisan vendor:publish --tag=monitor

После публикации в проекте появится файл config/monitor.php со следующей структурой:

<?php
use Adb\LaravelMonitor\Enums\MonitorEnum;

return [
    'config' => [
        MonitorEnum::PROJECT => true,    // PHP и Laravel версии
        MonitorEnum::DB => true,          // Подключения к БД
        MonitorEnum::REDIS => true,       // Redis соединения
        MonitorEnum::NODE => false,       // Node.js и npm
        MonitorEnum::HORIZON => true,     // Laravel Horizon
        MonitorEnum::STORAGES => false,   // Файловые хранилища
        MonitorEnum::SECURITY => false,   // Проверка безопасности пакетов
    ],

    'api_token' => env('API_TOKEN'),

    'routes' => [
        'prefix' => 'api/monitor',
        'middleware' => ['api', 'monitor.auth.api'],
        'as' => 'api.monitor.',
    ],

    'connections_db' => [
        'mongodb'
    ],
    
    'connections_redis' => [
        'default'
    ],
    
    'discs' => array_filter(explode(',', env('DISCS_FOR_MONITOR', '')), function($disk) {
        return !empty(trim($disk));
    }),
    
    'save_to_db' => false,
];

Настройка окружения

В файле .env добавьте:

# Токен для API доступа
API_TOKEN=your-secret-token-here

# Список дисков для проверки (через запятую)
DISCS_FOR_MONITOR=local,input1,archive

Использование

Команда Artisan

Основной способ использования пакета — через команду monitor:info:

# Проверка всех включенных компонентов
php artisan monitor:info

# Проверка конкретного компонента
php artisan monitor:info project
php artisan monitor:info db
php artisan monitor:info redis
php artisan monitor:info horizon
php artisan monitor:info storages
php artisan monitor:info security
php artisan monitor:info node

Пример вывода

{
    "project": {
        "php": "8.3.30",
        "laravel": "10.48.0"
    },
    "db": {
        "mongodb": {
            "driver": "mongodb",
            "host": "localhost",
            "name": "mongodb",
            "db": "my_database",
            "success": true
        }
    },
    "redis": {
        "default": {
            "redis_name": "default",
            "redis_version": "7.4.2",
            "os": "Linux 6.10.14-linuxkit aarch64",
            "port": "6379",
            "host": "redis",
            "success": true
        }
    },
    "horizon": {
        "success": true
    }
}

Интеграция с системами мониторинга

Сохранение в файл для Zabbix

php artisan monitor:info > /tmp/monitor.json

Автоматизация через Task Scheduler

В файле app/Console/Kernel.php:

protected function schedule(Schedule $schedule)
{
    $schedule->command('monitor:info')
        ->everyThirtyMinutes()
        ->sendOutputTo('/tmp/monitor.json');
}

Или для более частых проверок:

$schedule->command('monitor:info')
    ->everyFiveMinutes()
    ->sendOutputTo('/tmp/monitor.json')
    ->emailOutputOnFailure('admin@example.com');

REST API

Пакет предоставляет REST API для получения последних данных о состоянии системы.

Настройка сохранения в БД

Для активации API необходимо включить сохранение результатов в базу данных:

// config/monitor.php
'save_to_db' => true,

Затем примените миграцию:

php artisan migrate

Использование API

Endpoint: POST /api/monitor/monitor

Авторизация: Bearer Token

Заголовки:

Authorization: Bearer your-api-token-from-env
Content-Type: application/json

Пример запроса:

curl -X POST https://your-domain.com/api/monitor/monitor \
  -H "Authorization: Bearer your-api-token" \
  -H "Content-Type: application/json"

Ответ:

{
    "project": {
        "php": "8.3.30",
        "laravel": "10.48.0"
    },
    "db": {
        "mongodb": {
            "driver": "mongodb",
            "host": "localhost",
            "db": "my_database",
            "success": true
        }
    },
    "redis": {
        "default": {
            "redis_version": "7.4.2",
            "success": true
        }
    },
    "horizon": {
        "success": true
    },
    "created_at": "2025-02-04T14:27:56.000000Z",
    "updated_at": "2025-02-04T14:27:56.000000Z"
}

Компоненты мониторинга

1. Project (Проект)

Проверяет версии PHP и Laravel:

{
    "project": {
        "php": "8.3.30",
        "laravel": "10.48.0"
    }
}

2. Database (База данных)

Проверяет доступность и конфигурацию подключений к БД. Поддерживает любые драйверы Laravel (MySQL, PostgreSQL, MongoDB и т.д.):

{
    "db": {
        "mongodb": {
            "driver": "mongodb",
            "host": "localhost",
            "db": "database",
            "success": true
        },
        "mysql": {
            "driver": "mysql",
            "host": "127.0.0.1",
            "database": "laravel",
            "success": true
        }
    }
}

3. Redis

Проверяет подключения к Redis и получает информацию о версии:

{
    "redis": {
        "default": {
            "redis_name": "default",
            "redis_version": "7.4.2",
            "os": "Linux 6.10.14-linuxkit aarch64",
            "port": "6379",
            "host": "redis",
            "success": true
        }
    }
}

4. Horizon

Проверяет статус Laravel Horizon:

{
    "horizon": {
        "success": true
    }
}

5. Storages (Файловые хранилища)

Проверяет доступность настроенных дисков из config/filesystems.php:

{
    "storages": {
        "local": true,
        "input": true,
        "archive": true
    }
}

6. Node.js

Проверяет наличие и версии Node.js и npm:

{
    "node": {
        "node": {
            "version": "v20.11.0",
            "success": true
        },
        "npm": {
            "version": "10.2.4",
            "success": true
        }
    }
}

7. Security (Безопасность)

Проверяет уязвимости в зависимостях через Enlightn Security Checker:

{
    "security": {
        "erusev/parsedown": {
            "version": "1.7.1",
            "time": "2018-03-08T01:11:30+00:00",
            "advisories": [
                {
                    "title": "Class-Name Injection",
                    "link": "https://github.com/erusev/parsedown/issues/699",
                    "cve": "CVE-2019-10905"
                }
            ]
        }
    }
}

Архитектура пакета

Пакет построен на принципах SOLID и использует:

  • Dependency Injection — все зависимости инжектируются через конструкторы

  • Interface Segregation — используется MonitorInterface для абстракции

  • Service Layer — бизнес-логика вынесена в сервисы

  • Enum для констант — все константы вынесены в MonitorEnum

Структура классов

Adb\LaravelPulse\
├── Console\Commands\MonitorCommand        # Artisan команда monitor:info
├── Enums\MonitorEnum                       # Константы компонентов
├── Exceptions\ApiException                 # Кастомные исключения
├── Http\
│   ├── Controllers\Api\MonitorController  # API контроллер
│   └── Middleware\ApiAuth                  # Middleware для авторизации
├── Models\
│   ├── LaravelMonitor                     # Фасад (SQL/MongoDB)
│   ├── LaravelMonitorFactory              # Выбор реализации по типу БД
│   ├── LaravelMonitorInterface            # Интерфейс модели
│   ├── LaravelMonitorSQL                  # Реализация для SQL
│   ├── LaravelMonitorMongoDB              # Реализация для MongoDB (Laravel 10+)
│   └── LaravelMonitorMongoDBLegacy        # Реализация для MongoDB (Laravel 9-)
├── Providers\ServiceProvider              # Service Provider
└── Services\
    ├── Monitor                             # Реализация проверок компонентов
    ├── MonitorInterface                    # Интерфейс проверок
    └── MonitorService                      # Сервис-оркестратор

Практические примеры использования

Интеграция с Zabbix

Создайте скрипт для Zabbix:

#!/bin/bash
# /usr/local/bin/check-laravel-monitor.sh

cd /path/to/your/laravel/project
php artisan monitor:info > /tmp/monitor.json

# Парсинг JSON и отправка в Zabbix
REDIS_STATUS=$(php -r "echo json_decode(file_get_contents('/tmp/monitor.json'))->redis->default->success ? 1 : 0;")
zabbix_sender -z zabbix-server -s laravel-app -k redis.status -o $REDIS_STATUS

Интеграция с Prometheus

Создайте кастомный endpoint для Prometheus метрик:

// routes/web.php
Route::get('/metrics/monitor', function () {
    $monitor = \Adb\LaravelMonitor\Models\LaravelMonitor::latest()->first();

    if (!$monitor) {
        return response('', 204);
    }
    
    $metrics = [];
    $metrics[] = sprintf('laravel_monitor_redis_status %d', 
        $monitor->redis['default']['success'] ?? 0);
    $metrics[] = sprintf('laravel_monitor_db_status %d', 
        $monitor->db['mongodb']['success'] ?? 0);
    $metrics[] = sprintf('laravel_monitor_horizon_status %d', 
        $monitor->horizon['success'] ?? 0);
    
    return response(implode("\n", $metrics), 200)
        ->header('Content-Type', 'text/plain');
});

Уведомления в Telegram

Создайте кастомную команду для отправки уведомлений:

// app/Console/Commands/CheckMonitorAndNotify.php
namespace App\Console\Commands;

use Illuminate\Console\Command;
use Adb\LaravelMonitor\Services\MonitorService;
use Illuminate\Support\Facades\Http;

class CheckMonitorAndNotify extends Command
{
    protected $signature = 'monitor:check-and-notify';
    
    public function handle(MonitorService $service)
    {
        $data = $service->getMonitor('all');
        
        $issues = [];
        if (isset($data['redis']['default']['success']) && !$data['redis']['default']['success']) {
            $issues[] = '❌ Redis недоступен';
        }
        if (isset($data['db']['mongodb']['success']) && !$data['db']['mongodb']['success']) {
            $issues[] = '❌ База данных недоступна';
        }
        if (isset($data['horizon']['success']) && !$data['horizon']['success']) {
            $issues[] = '❌ Horizon не запущен';
        }
        
        if (!empty($issues)) {
            $message = "⚠️ Проблемы в системе:\n" . implode("\n", $issues);
            
            Http::post('https://api.telegram.org/bot' . env('TELEGRAM_BOT_TOKEN') . '/sendMessage', [
                'chat_id' => env('TELEGRAM_CHAT_ID'),
                'text' => $message
            ]);
        }
    }
}

Настройка для разных окружений

Development

// config/monitor.php для dev
'config' => [
    MonitorEnum::PROJECT => true,
    MonitorEnum::DB => true,
    MonitorEnum::REDIS => false,  // Отключаем в dev
    MonitorEnum::HORIZON => false,
    MonitorEnum::STORAGES => false,
    MonitorEnum::SECURITY => false,
    MonitorEnum::NODE => false,
],
'save_to_db' => false,  // Не сохраняем в dev

Production

// config/monitor.php для production
'config' => [
    MonitorEnum::PROJECT => true,
    MonitorEnum::DB => true,
    MonitorEnum::REDIS => true,
    MonitorEnum::HORIZON => true,
    MonitorEnum::STORAGES => true,
    MonitorEnum::SECURITY => true,  // Включаем проверку безопасности
    MonitorEnum::NODE => true,
],
'save_to_db' => true,  // Сохраняем для API

Заключение

Laravel Monitor — это мощный инструмент для мониторинга состояния Laravel-приложений. Он позволяет:

  • ✅ Быстро диагностировать проблемы с компонентами системы

  • ✅ Интегрироваться с существующими системами мониторинга

  • ✅ Получать данные через удобный REST API

  • ✅ Автоматизировать проверки через Task Scheduler

  • ✅ Отслеживать безопасность зависимостей

Пакет активно развивается и поддерживается. Исходный код доступен на GitFlic.

Если у вас есть вопросы или предложения по улучшению пакета — создавайте issues в репозитории. Буду рад обратной связи!


Полезные ссылки: