Laravel 记录日志也是用了monolog/log ,只是在上面加了一层可配置和包裹了一层
测试代码
Log::channel('zip')->info(' begin');
对应日志配置
'zip' => [
'driver' => 'daily',
'path' => storage_path('logs/zip/zip.log'),
'formatter' => \App\System\Logger\Formatter\IntrospectionFormatter::class,
],
配置可以传入 驱动,日志路径,日志格式,创建日志文件的权限,文件锁等。
最后请求结束,类析构的时候才会fclose对应的文件流
1. 首先laravel在启动的时候会有
class LogServiceProvider extends ServiceProvider
{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->singleton('log', function () {
return new LogManager($this->app);
});
}
}
将log注册进去
然后调用方直接用门面模式就可以LogManager类
Illuminate\Log\LogManager
/**
* Get a log channel instance.
*
* @param string|null $channel
* @return mixed
*/
public function channel($channel = null)
{
return $this->driver($channel);
}
/**
* Get a log driver instance.
*
* @param string|null $driver
* @return mixed
*/
public function driver($driver = null)
{
return $this->get($driver ?? $this->getDefaultDriver());
}
/**
* Attempt to get the log from the local cache.
*
* @param string $name
* @return \Psr\Log\LoggerInterface
*/
protected function get($name)
{
try {
return $this->channels[$name] ?? with($this->resolve($name), function ($logger) use ($name) {
return $this->channels[$name] = $this->tap($name, new Logger($logger, $this->app['events']));
});
} catch (Throwable $e) {
return tap($this->createEmergencyLogger(), function ($logger) use ($e) {
$logger->emergency('Unable to create configured logger. Using emergency logger.', [
'exception' => $e,
]);
});
}
}
/**
* Resolve the given log instance by name.
*
* @param string $name
* @return \Psr\Log\LoggerInterface
*
* @throws \InvalidArgumentException
*/
protected function resolve($name)
{
$config = $this->configurationFor($name);
if (is_null($config)) {
throw new InvalidArgumentException("Log [{$name}] is not defined.");
}
if (isset($this->customCreators[$config['driver']])) {
return $this->callCustomCreator($config);
}
$driverMethod = 'create'.ucfirst($config['driver']).'Driver';
if (method_exists($this, $driverMethod)) {
return $this->{$driverMethod}($config);
}
throw new InvalidArgumentException("Driver [{$config['driver']}] is not supported.");
}
最终还是生成了monolog类
/**
* Create an instance of the daily file log driver.
*
* @param array $config
* @return \Psr\Log\LoggerInterface
*/
protected function createDailyDriver(array $config)
{
return new Monolog($this->parseChannel($config), [
$this->prepareHandler(new RotatingFileHandler(
$config['path'], $config['days'] ?? 7, $this->level($config),
$config['bubble'] ?? true, $config['permission'] ?? null, $config['locking'] ?? false
), $config),
]);
}
Illuminate\Log\Logger
/**
* Log an informational message to the logs.
*
* @param string $message
* @param array $context
* @return void
*/
public function info($message, array $context = [])
{
$this->writeLog(__FUNCTION__, $message, $context);
}
/**
* Write a message to the log.
*
* @param string $level
* @param string $message
* @param array $context
* @return void
*/
protected function writeLog($level, $message, $context)
{
$this->fireLogEvent($level, $message = $this->formatMessage($message), $context);
$this->logger->{$level}($message, $context);
}
最后还是掉了monolog\log->info
Monolog\Logger
/**
* Adds a log record at the INFO level.
*
* This method allows for compatibility with common interfaces.
*
* @param string $message The log message
* @param array $context The log context
*/
public function info($message, array $context = []): void
{
$this->addRecord(static::INFO, (string) $message, $context);
}
具体细节,细品