Laravel: Пишем кастомный драйвер для логирования в базу данных
На одном из проектов по созданию CRM системы мне понадобилось сделать логи удобными для пользователей и более того, добавить по ним поиск и пред заготовленные фильтры.
Конечно можно добиться подобного поведения и просто читая файл логов, но зачем такие муки, особенно когда файл очень большой и чтение с диска потребляет неприлично много ресурсов сервера. Конечно же я решил переложить эту нагрузку на PostgreSQL.
Создание драйвера
Механизм логирования встроенный в Laravel использует Monolog под капотом. Расширением на его основе мы и займёмся в этой заметке.
Что бы создать новый драйвер легирования просто создаём новый инстанс от Monolog Logger и создаём в нем обработчик.
namespace App\Services;
use Monolog\Logger;
class DatabaseLogger
{
public function __invoke(array $config)
{
return new Logger('Database', [
new DatabaseHandler(),
]);
}
}
В обработке мы создаём новое сообщение, которое по сути является обычной моделью Eloquent. Теперь у вас есть поля по которым вы можете сделать поиск, группировку и прочие полезности для вашего пользователя.
namespace App\Services;
use Monolog\Handler\AbstractProcessingHandler;
use App\Models\LogMessage;
class DatabaseHandler extends AbstractProcessingHandler
{
protected function write(array $record): void
{
LogMessage::create([
'level' => $record['level'],
'level_name' => $record['level_name'],
'message' => $record['message'],
'logged_at' => $record['datetime'],
'context' => $record['context'],
'extra' => $record['extra'],
]);
}
}
Подключение драйвера
Что бы подключить только что созданный драйвер, подключите новый канал в config/logging.php и вуаля, ваш кастомный драйвер готов к использованию.
use App\Services\DatabaseLogger;
return [
'channels' => [
'db' => [
'driver' => 'custom',
'via' => DatabaseLogger::class,
],
]
]
Не забудьте создать вашу модель LogMessage и её миграцию:
php artisan make:model LogMessage -m
Теперь вы просто можете вызывать запись в этот канал вот таким образом:
Log::channel('db')->info('Your message');
Из неочивидных профитов — вы можете конвертировать тело сообщения в JSON что сделает поиск по логам ещё более удобным при помощи встроенных в PostgreSQL механизмов работы с JSON данными.