Уявіть: клієнт повідомляє, що хтось змінив ціни на сайті, а хто і коли — невідомо. Без системи аудиту ви витрачаєте години на копання в логах сервера, але не знаходите винуватця. Або гірше — регулятор запитує журнал змін за два роки, а його просто немає. Ми стикалися з цим не раз. Тому впроваджуємо систему аудиту дій користувачів, яка фіксує кожну значущу подію: хто, що, коли і з якого IP.
Без такої системи відновлення ланцюжка подій перетворюється на археологію, а кожен запит регулятора загрожує штрафом до 4% річного обороту. Наша система не лише фіксує події, але й дозволяє швидко фільтрувати журнал за десятком параметрів, економлячи години роботи адміністратора. Наприклад, у великого e-commerce проекту щодня генерується до 50 000 записів аудиту, і без автофільтрації пошук інциденту займав би дні.
Які проблеми вирішує аудит користувачів?
Система аудиту дій користувачів вирішує проблему відсутності прозорості: без журналу неможливо зрозуміти, хто змінив важливі дані або видалив запис. Аудит дає повну картину.
- Регуляторні ризики. 152-ФЗ та GDPR вимагають відстежувати доступ до персональних даних. Порушення — штрафи до 4% обороту.
- Продуктивність. Синхронний запис у кожен запит вбиває БД. Ми використовуємо черги та пакетну вставку — це знижує навантаження на 80%.
- Довгий пошук інцидентів. Без фільтрації за користувачем, подією і датою знайти потрібний запис — голка в копиці сіна.
Що і як логувати
Обов'язкові події
| Подія | Обов'язковість | Рекомендований метод |
|---|---|---|
| Вхід/вихід | Обов'язково | Laravel Events |
| Невдалі спроби входу | Обов'язково | Laravel Events |
| Зміна паролю, email | Обов'язково | Observer моделі User |
| Зміна прав доступу, ролей | Обов'язково | Observer або пакет |
| CRUD критичних сутностей | Обов'язково | Пакет Auditing |
| Платіжні операції | Обов'язково | Observer або подія |
| Експорт даних | Обов'язково | Middleware |
| Перегляд чужих даних | Опціонально | Middleware |
| API-запити до адмінки | Опціонально | Middleware |
Структура таблиці аудиту
CREATE TABLE audit_logs (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT REFERENCES users(id) ON DELETE SET NULL,
event VARCHAR(100) NOT NULL, -- 'user.password_changed'
subject_type VARCHAR(100), -- 'App\\Models\\User'
subject_id BIGINT, -- ID зміненої сутності
old_values JSONB, -- стан до
new_values JSONB, -- стан після
ip_address INET,
user_agent TEXT,
session_id VARCHAR(100),
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE INDEX idx_audit_user ON audit_logs(user_id);
CREATE INDEX idx_audit_event ON audit_logs(event);
CREATE INDEX idx_audit_subject ON audit_logs(subject_type, subject_id);
CREATE INDEX idx_audit_created ON audit_logs(created_at DESC);
Оскільки таблиця аудиту може зростати до сотень гігабайт, важливо правильно індексувати поля. Ми використовуємо індекси на user_id, event, subject_type+subject_id та created_at DESC — це прискорює типові запити в 20 разів.
Як швидко знайти потрібну подію в журналі?
З правильно налаштованими індексами та фільтрацією пошук запису займає секунди. Додайте інтерфейс з вибором дат, користувача і типу події — і адміністратор перестане витрачати години на ручний перегляд логів. Ми реалізуємо таку панель за пару днів.
Як реалізувати систему аудиту
Використання готового пакету
Пакет owen-it/laravel-auditing — найпоширеніший вибір. Підходить для 80% проектів. Налаштування займає годину.
// composer require owen-it/laravel-auditing
// В моделі
use OwenIt\Auditing\Contracts\Auditable;
class User extends Model implements Auditable
{
use \OwenIt\Auditing\Auditable;
// Виключити з аудиту чутливі поля
protected $auditExclude = ['password', 'remember_token'];
// Тільки при певних подіях
protected $auditEvents = ['created', 'updated', 'deleted'];
}Пакет прискорює впровадження в 4 рази порівняно з кастомною реалізацією. Однак для нестандартних сценаріїв (логування невдалих входів, API-запитів) краще підходить Observer.
Кастомний Observer
// app/Observers/AuditObserver.php
class AuditObserver {
public function updated(Model $model): void {
if (!$model->wasChanged()) return;
AuditLog::create([
'user_id' => auth()->id(),
'event' => strtolower(class_basename($model)) . '.updated',
'subject_type' => get_class($model),
'subject_id' => $model->getKey(),
'old_values' => $model->getOriginal(),
'new_values' => $model->getChanges(),
'ip_address' => request()->ip(),
'user_agent' => request()->userAgent(),
]);
}
}
// Реєстрація в AppServiceProvider
User::observe(AuditObserver::class);
Order::observe(AuditObserver::class);
Middleware та події автентифікації
Приклад middleware для HTTP-запитів
// app/Http/Middleware/AuditRequests.php
class AuditRequests
{
private array $auditedRoutes = [
'admin.*',
'api.users.*',
'api.settings.*',
];
public function handle(Request $request, Closure $next): Response
{
$response = $next($request);
if ($this->shouldAudit($request)) {
AuditLog::create([
'user_id' => auth()->id(),
'event' => 'http.' . strtolower($request->method()),
'new_values' => [
'url' => $request->url(),
'method' => $request->method(),
'status' => $response->status(),
],
'ip_address' => $request->ip(),
]);
}
return $response;
}
} Чому асинхронний запис аудиту критичний?
Синхронний запис у кожному запиті — навантаження на БД. Рішення:
- Асинхронний запис через черги — відправка задачі
WriteAuditLogна чергуaudit. - Пакетна вставка — накопичувати записи в Redis, скидати раз на хвилину.
- Окрема БД для аудиту — ізолює навантаження.
// Асинхронний запис через черги
dispatch(new WriteAuditLog($data))->onQueue('audit');
// Пакетна вставка — накопичувати в Redis, скидати раз на хвилину
Redis::rpush('audit_queue', json_encode($data));
// Окрема БД для аудиту
// config/database.php
'audit' => [
'driver' => 'pgsql',
'database' => 'audit_db',
// ...
] Порівняння підходів: пакет vs кастом
| Критерій | owen-it/laravel-auditing | Кастомний Observer |
|---|---|---|
| Час впровадження | 1 година | 4-8 годин |
| Гнучкість | Обмежена | Повна |
| Документація | Відмінна | Немає |
| Оновлення | Активні | Самі |
| Продуктивність | Хороша (є конфіги) | Залежить від реалізації |
Для типового проекту обираємо пакет. Якщо потрібна нестандартна логіка — зв'яжіться з нами для консультації.
Процес і терміни впровадження
Що входить у роботу
- Проектування схеми аудиту під ваші сутності
- Реалізація логування (пакет або кастом)
- Налаштування асинхронного запису через черги
- Інтерфейс перегляду з фільтрацією за користувачем, подією, часовим діапазоном, сутністю
- Ротація логів (Artisan-команда)
- Документація та міграції
- Навчання адміністраторів
- Гарантія 6 місяців
Терміни реалізації
- Базова модель + Observer для ключових сутностей — від 2 до 3 днів
- Повноцінна система з чергами, ротацією та UI — від 5 до 7 днів
Точний термін залежить від кількості моделей та складності бізнес-логіки. Ми оцінимо ваш проект — просто зв'яжіться з нами. Досвід роботи з Laravel понад 5 років, реалізували аудит для 20+ проектів. Гарантуємо відповідність вимогам 152-ФЗ та GDPR.
Зв'яжіться з нами для оцінки вашого проекту. Замовте впровадження системи аудиту вже сьогодні.







