Більшість пакетів для аудиту можуть показати, коли поле змінилося і хто його змінив. Але вони втрачають контекст, коли зміна відбувається через дві черги після запиту, що її ініціював. Yammi Audit Log від RomaLytar вирішує цю проблему: поряд зі значеннями "до" і "після" він записує, хто виконав зміну, хто її ініціював, та correlation ID, який пов'язує запит, завдання, команду або заплановане завдання в єдиний ланцюг.
Аудит без змін у моделях
Немає потреби додавати трейти, імплементувати інтерфейси чи реєструвати обсервери. Після встановлення пакета та виконання міграцій записи Eloquent автоматично потрапляють в аудит-лог для всіх моделей:
User::first()->update(['name' => 'Eric']);
Це оновлення вже зафіксоване в журналі аудиту без будь-яких змін у моделі User. За замовчуванням захоплюються всі моделі, але можна перемкнути режим на opt-in у config/audit-log.php, якщо потрібно відстежувати лише певний набір:
'capture' => ['mode' => env('AUDIT_LOG_CAPTURE_MODE', 'all')], // all | opt_in
'retention' => ['days' => env('AUDIT_LOG_RETENTION_DAYS', 180)],
'write' => ['async' => env('AUDIT_LOG_WRITE_ASYNC', false)],
Важливе застереження: пакет підключається до подій моделей Eloquent, тому прямі оновлення через Query Builder не захоплюються автоматично і мають бути записані явно.
Збереження інформації про актора через черги
Це та частина, яка виділяє Yammi серед типових рішень для аудиту. Коли користувач диспатчить завдання, яке пізніше модифікує модель, звичайний аудит-трейл приписує зміну воркеру черги, бо саме цей процес виконав запис. Yammi проносить оригінальну ідентичність через весь ланцюг, тому запис розрізняє актора, який виконав зміну, та особу, яка її ініціювала. Correlation ID потім групує всі записи, що належать до одного робочого процесу, дозволяючи відтворити каскад змін, що охоплює контролер, чергове завдання та заплановану команду, замість того щоб розглядати їх як непов'язані рядки.
Записаний контекст також відзначає, де відбулася зміна - чи то HTTP-запит, чергове завдання, artisan-команда чи планувальник, що корисно, коли та сама модель записується з кількох точок входу.
Створений, щоб не заважати
Шлях запису спроектований так, щоб аудит не призводив до відмови запиту чи уповільнення. Кожна зміна - це один insert плюс пакетний індекс полів, що змінилися, і ці записи полів потрапляють у виділену індексовану таблицю, тому пошук за полем не означає сканування JSON-колонок. Записи можна відправляти в чергу, якщо не хочеться платити за них у реальному часі:
'write' => ['async' => env('AUDIT_LOG_WRITE_ASYNC', false)],
Шлях захоплення також fail-open, тому якщо сам запис аудиту видає помилку, базова операція все одно проходить замість того, щоб забрати з собою весь запит.
Опціональні рівні криміналістики та відповідності вимогам
Поза основним трейлом, Yammi постачається з набором підсистем, які залишаються неактивними, поки їх не увімкнути. Режим цілісності додає ланцюг хешів, стійкий до підробки, щоб можна було виявити постфактум, чи були змінені збережені записи, а перегляд "машини часу" відтворює стан запису в минулому. Є інструменти GDPR для звітів суб'єктів та обробки збереження, виявлення аномалій, стримінг до SIEM, сповіщення в Slack та вебхуки, підтримка мультитенантності. Опціональна панель керування доступна через окрему команду:
composer require romalytar/yammi-audit-log-laravel
php artisan migrate
php artisan audit-log:ui enable
Панель та функції цілісності, криміналістики та відповідності вимогам - всі opt-in, що тримає базову установку близькою до простого журналу змін і дозволяє додавати важчий механізм лише там, де додаток дійсно цього потребує.
Сумісність та підтримка
Yammi працює на PHP 8.1+ та Laravel від 9 до 13 версії, підтримує будь-яку базу даних, з якою працює Laravel. Документацію та вихідний код можна знайти на GitHub.