Функции ведения логов Laravel позволяют нам регистрировать различные события, которые могут оказаться полезными при анализе. Но может возникнуть проблема, когда у вас есть большой файл логов с огромным количеством данных.
Помочь в этом может Elasticsearch - мощный инструмент для большого спектра задач, но его также можно использовать для хранения, мониторинга и анализа логов.
Отправлять данные можно через Logstash - инструмент, который умеет принимать и парсить логи из многих источников, но для небольшого проекта мы можем сохранять их в базу данных Elasticsearch напрямую.
Установка пакета
Для начала нужно установить пакет elasticsearch:
composer require elasticsearch/elasticsearch
Добавление провайдера
В директории /app/Providers/
добавляем новый провайдер, создаем файл ElkServiceProvider.php
<?php
namespace App\Providers;
use Elasticsearch\Client;
use Elasticsearch\ClientBuilder;
use Illuminate\Support\ServiceProvider;
use Monolog\Formatter\ElasticsearchFormatter;
/**
* Class ElkServiceProvider
*
* @package App\Providers
*/
class ElkServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton(Client::class, function ($app) {
$url = $this->getHost();
return ClientBuilder::create()->setHosts([$url])->build();
});
$this->app->bind(ElasticsearchFormatter::class, function ($app) {
return new ElasticsearchFormatter($this->getIndexName(), $this->getIndexType());
});
}
/**
* Текущее окружение
*
* @return string
*/
protected function getEnvironmentName(): string
{
return env('APP_ENV', 'production');
}
/**
* Тип индекса
*
* @return string
*/
public function getIndexType(): string
{
$env = $this->getEnvironmentName();
return config(sprintf('elk.%s.type', $env));
}
/**
* Имя индекса
*
* @return string
*/
public function getIndexName(): string
{
$env = $this->getEnvironmentName();
return config(sprintf('elk.%s.index', $env));
}
/**
* Хост
*
* @return string
*/
public function getHost(): string
{
$env = $this->getEnvironmentName();
$schema = config(sprintf('elk.%s.schema', $env));
$domain = config(sprintf('elk.%s.domain', $env));
$port = config(sprintf('elk.%s.port', $env));
return $this->buildUrl($schema, $domain, $port);
}
/**
* Сформировать путь к elk
*
* @param string $schema
* @param string $domain
* @param string $port
*
* @return string
*/
protected function buildUrl(string $schema, string $domain, string $port): string
{
return sprintf('%s://%s:%s', $schema, $domain, $port);
}
}
И регистрируем его в /config/app.php
, в секции providers
:
<?php
return [
...
'providers' => [
/*
* Application Service Providers...
*/
App\Providers\ElkServiceProvider::class,
]
...
]
Настройка
Далее создаем конфигурационный файл с настройками /config/elk.php
Для примера у нас будет 2 индекса: один для production версии, второй для локальной. Индексы делаем с ротацией каждый день.
Также прописываем протокол, IP адрес сервера и порт.
Логи будут сохраняться в нужный индекс, в зависимости от переменной APP_ENV
, которая устанавливается в .env
файле.
<?php
return [
'production' => [
'schema' => 'http',
'domain' => '123.456.78.90',
'port' => '9201',
'index' => 'laravel-production-' . date('Y.m.d'),
'type' => '_doc'
],
'local' => [
'schema' => 'http',
'domain' => '123.456.78.90',
'port' => '9201',
'index' => 'laravel-local-' . date('Y.m.d'),
'type' => '_doc'
]
];
Использование
Теперь вы можете сохранять логи в Elasticsearch, указав канал custom
.
Например:
<?php
use Illuminate\Support\Facades\Log;
Log::channel('custom')->error('Не удалось отправить уведомление', $data);