我刚刚切换到 monolog,想将我的消息记录到 PHP 控制台而不是文件。对于某些人来说,这似乎是显而易见的,但我花了一些时间才弄清楚如何做到这一点,而且我在 SO 上找不到类似的问题/答案。
Monolog 的 Github readme 上的示例仅显示如何使用文件:
<?php
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
// create a log channel
$log = new Logger('name');
$log->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING)); // <<< uses a file
// add records to the log
$log->addWarning('Foo');
$log->addError('Bar');
但它没有说明如何将消息记录到控制台。在 Google 上搜索后,我要么找到了 Symfony 的帮助页面,要么找到了人们寻找登录浏览器控制台的方法的问题。
StreamHandler
,因此可以传入流(而不是文件的路径)。默认情况下,PHP 中回显的所有内容都会写入php://stdout / php://output,因此我们可以简单地使用其中之一作为
StreamHandler
的流:
<?php
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
// create a log channel
$log = new Logger('name');
$log->pushHandler(new StreamHandler('php://stdout', Logger::WARNING)); // <<< uses a stream
// add records to the log
$log->warning('Foo');
$log->error('Bar');
希望这可以节省一些时间:)
use Monolog\Logger;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\StreamHandler;
$output = "[%datetime%] %channel%.%level_name%: %message%\n";
$formatter = new LineFormatter($output);
$streamHandler = new StreamHandler('php://stdout', Logger::DEBUG);
$streamHandler->setFormatter($formatter);
$logger = new Logger('LoggerName');
$logger->pushHandler($streamHandler);
php://output
$logger = new Logger('');
$logger->pushHandler(new StreamHandler('php://output', Logger::DEBUG));
$logger->debug('my message', ['var1', 'var2']);
因为我认为标准输出在网络请求期间不起作用。
Symphony 令人惊叹的 VarDumper 将日志的 context
漂亮地打印到控制台。这就是我能够做到这一点的方法:
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\StreamHandler;
use Monolog\LogRecord;
use Symfony\Component\VarDumper\VarDumper;
use Symfony\Component\VarDumper\Caster\ScalarStub;
class MonologCommandLineHandler extends StreamHandler
{
public function __construct(
?string $stream = 'php://output',
...$args
) {
parent::__construct($stream, ...$args);
$this->setFormatter(new LineFormatter("%message%\n"));
}
/**
* Invoked every time a log is written
*/
protected function write(LogRecord $record): void
{
/** Bail early if not on the command line */
if (!$this->isOnCommandLine()) {
return;
}
parent::write($record);
/** Dump the record's `context` if present */
if (!empty($record->context)) {
$this->dump($record->context);
}
}
/**
* Check if currently on the command line
*/
private function isOnCommandLine(): bool
{
return in_array(\PHP_SAPI, ['cli', 'phpdbg', 'embed'], true);
}
/**
* Dump something using Symphony's VarDumper
*/
private function dump(mixed ...$vars): void
{
if (!$vars) {
VarDumper::dump(new ScalarStub('🐛'));
return;
}
if (array_key_exists(0, $vars) && count($vars) === 1) {
VarDumper::dump(var: $vars[0]);
} else {
foreach ($vars as $key => $value) {
VarDumper::dump(
var: $value,
label: is_int($key) ? $key + 1 : $key
);
}
}
}
}
像这样使用它:
use Monolog\Logger;
$logger = new Logger($name);
$logger->pushHandler(new MonologCommandLineHandler());