Multiple logging (pool of loggers) for Laravel
<?php namespace App\Services\Log;
use Illuminate\Support\Manager;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use Psr\Log\LoggerInterface;
use Illuminate\Contracts\Logging\Log as LogContract;
class WritersPool extends Manager implements LogContract, LoggerInterface
{
protected $defaultLoggerName;
/**
* Get the default driver name.
*
* @return string
*/
public function getDefaultDriver()
{
return $this->defaultLoggerName;
}
/**
* Set the default logger.
*
* @param string $name
* @param LogContract $writer
*
* @return string
*/
public function setDefaultLogger($name, LogContract $writer)
{
$this->defaultLoggerName = $name;
$this->drivers[$name] = $writer;
}
/**
* Get a logger instance by name.
*
* @param string|null $logger
*
* @return mixed
*/
public function logger($logger = null)
{
return $this->driver($logger);
}
/**
* Register a file logger creator.
*
* @param $name
* @param $path
* @param string $level
* @param int|null $days
*/
public function addFileLogger($name, $path, $level = 'debug', $days = null)
{
$this->extend($name, function () use ($name, $path, $level, $days) {
$handler = null === $days
? new StreamHandler($path, $level)
: new RotatingFileHandler($path, $days, $level);
$handler->setFormatter(new LineFormatter(null, null, true, true));
return new Logger($name, [$handler]);
});
}
/**
* System is unusable.
*
* @param string $message
* @param array $context
*
* @return null
*/
public function emergency($message, array $context = [])
{
$this->logger()->emergency($message, $context);
}
/**
* Log an alert message to the logs.
*
* @param string $message
* @param array $context
*
* @return void
*/
public function alert($message, array $context = [])
{
$this->logger()->alert($message, $context);
}
/**
* Log a critical message to the logs.
*
* @param string $message
* @param array $context
*
* @return void
*/
public function critical($message, array $context = [])
{
$this->logger()->critical($message, $context);
}
/**
* Log an error message to the logs.
*
* @param string $message
* @param array $context
*
* @return void
*/
public function error($message, array $context = [])
{
$this->logger()->error($message, $context);
}
/**
* Log a warning message to the logs.
*
* @param string $message
* @param array $context
*
* @return void
*/
public function warning($message, array $context = [])
{
$this->logger()->warning($message, $context);
}
/**
* Log a notice to the logs.
*
* @param string $message
* @param array $context
*
* @return void
*/
public function notice($message, array $context = [])
{
$this->logger()->notice($message, $context);
}
/**
* Log an informational message to the logs.
*
* @param string $message
* @param array $context
*
* @return void
*/
public function info($message, array $context = [])
{
$this->logger()->info($message, $context);
}
/**
* Log a debug message to the logs.
*
* @param string $message
* @param array $context
*
* @return void
*/
public function debug($message, array $context = [])
{
$this->logger()->debug($message, $context);
}
/**
* Log a message to the logs.
*
* @param string $level
* @param string $message
* @param array $context
*
* @return void
*/
public function log($level, $message, array $context = [])
{
$this->logger()->log($message, $context);
}
/**
* Register a file log handler.
*
* @param string $path
* @param string $level
*
* @return void
*/
public function useFiles($path, $level = 'debug')
{
$this->logger()->useFiles($path, $level);
}
/**
* Register a daily file log handler.
*
* @param string $path
* @param int $days
* @param string $level
*
* @return void
*/
public function useDailyFiles($path, $days = 0, $level = 'debug')
{
$this->logger()->useDailyFiles($path, $days, $level);
}
}
<?php namespace App\Providers;
use App\Services\Log\WritersPool;
use Illuminate\Support\ServiceProvider;
use Monolog\Handler\RavenHandler;
use Psr\Log\LogLevel;
class LoggingServiceProvider extends ServiceProvider
{
public function boot()
{
}
/**
* Перерегистрируем сервис логирования в тот который умеет работать с несколькими логерами.
*
*/
public function register()
{
$pool = new WritersPool($this->app);
$this->registerDefaultLogger($pool);
$this->registerOtherLoggers($pool);
$this->app->instance('log', $pool);
$this->configureHandlers();
}
/**
* Установка главного логера, создаваемого фреймворком как логера по умолчанию.
*
* @param WritersPool $pool
*/
private function registerDefaultLogger(WritersPool $pool)
{
$base_writer = $this->app->make('log');
$pool->setDefaultLogger('laravel', $base_writer);
}
/**
* Регистрация дополнительных логеров указанных в конфигурации.
*
* @param WritersPool $pool
*/
private function registerOtherLoggers(WritersPool $pool)
{
$loggers = $this->app->make('config')->get('app.loggers', []);
foreach ($loggers as $log => $config) {
if (is_string($config)) {
$config = ['file' => $config];
}
$pool->addFileLogger(
$log,
array_get($config, 'file'),
array_get($config, 'level', $this->getBaseLogLevel()),
array_get($config, 'days')
);
}
}
/**
* Конфигурирование обработчиков логов.
*/
protected function configureHandlers()
{
//можно добавить обработчики, например sentry
}
/**
* Основной уровень логирования для логгеров у которых он не конкретезирован.
*/
protected function getBaseLogLevel()
{
return $this->app->make('config')->get('app.debug') ? LogLevel::DEBUG : LogLevel::INFO;
}
}