mirror of
https://github.com/zhamao-robot/zhamao-logger.git
synced 2026-03-17 20:44:52 +08:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
26dc5fa8c3 | ||
|
|
e75fa01ca5 | ||
|
|
b28c0c26d5 | ||
|
|
2551b3e1db | ||
|
|
81ab0b98f6 | ||
|
|
1d7427abd8 | ||
|
|
1b7e343493 | ||
|
|
97ee152121 | ||
|
|
11156c65a2 |
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "zhamao/logger",
|
||||
"description": "Another Console Logger for CLI Applications",
|
||||
"description": "Another Colorful Console Logger for CLI Applications",
|
||||
"type": "library",
|
||||
"license": "Apache-2.0",
|
||||
"autoload": {
|
||||
@ -16,7 +16,7 @@
|
||||
"authors": [
|
||||
{
|
||||
"name": "jerry",
|
||||
"email": "admin@zhamao.me"
|
||||
"email": "github@cwcc.me"
|
||||
},
|
||||
{
|
||||
"name": "sunxyw",
|
||||
|
||||
@ -10,7 +10,7 @@ use Psr\Log\LogLevel;
|
||||
|
||||
class ConsoleLogger extends AbstractLogger
|
||||
{
|
||||
public const VERSION = '1.1.0';
|
||||
public const VERSION = '1.1.5';
|
||||
|
||||
/**
|
||||
* 日志输出格式
|
||||
@ -93,13 +93,15 @@ class ConsoleLogger extends AbstractLogger
|
||||
*/
|
||||
protected $decorated;
|
||||
|
||||
protected $use_stderr = false;
|
||||
|
||||
/**
|
||||
* 创建一个 ConsoleLogger 实例
|
||||
*
|
||||
* @param string $level 日志等级
|
||||
* @param null|resource $stream
|
||||
*/
|
||||
public function __construct(string $level = LogLevel::INFO, $stream = null, bool $decorated = true)
|
||||
public function __construct(string $level = LogLevel::INFO, $stream = null, bool $decorated = true, bool $use_stderr = false)
|
||||
{
|
||||
$this->decorated = $decorated;
|
||||
self::$log_level = $this->castLogLevel($level);
|
||||
@ -113,12 +115,18 @@ class ConsoleLogger extends AbstractLogger
|
||||
if (($stat['mode'] & 0170000) === 0100000) { // whether is regular file
|
||||
$this->decorated = false;
|
||||
} else {
|
||||
$this->decorated =
|
||||
PHP_OS_FAMILY !== 'Windows' // linux or unix
|
||||
$this->decorated
|
||||
= PHP_OS_FAMILY !== 'Windows' // linux or unix
|
||||
&& function_exists('posix_isatty')
|
||||
&& posix_isatty($stream); // whether is interactive terminal
|
||||
}
|
||||
$this->stream = $stream;
|
||||
$this->use_stderr = $use_stderr;
|
||||
}
|
||||
|
||||
public function setLevel(string $level): void
|
||||
{
|
||||
self::$log_level = $this->castLogLevel($level);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -162,7 +170,7 @@ class ConsoleLogger extends AbstractLogger
|
||||
{
|
||||
$log = 'Stack trace:' . PHP_EOL;
|
||||
$trace = debug_backtrace();
|
||||
//array_shift($trace);
|
||||
// array_shift($trace);
|
||||
foreach ($trace as $i => $t) {
|
||||
if (!isset($t['file'])) {
|
||||
$t['file'] = 'unknown';
|
||||
@ -171,6 +179,7 @@ class ConsoleLogger extends AbstractLogger
|
||||
$t['line'] = 0;
|
||||
}
|
||||
$log .= "#{$i} {$t['file']}({$t['line']}): ";
|
||||
/* @phpstan-ignore-next-line */
|
||||
if (isset($t['object']) && is_object($t['object'])) {
|
||||
$log .= get_class($t['object']) . '->';
|
||||
}
|
||||
@ -203,30 +212,30 @@ class ConsoleLogger extends AbstractLogger
|
||||
return ConsoleColor::apply($styles, $string)->__toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function log($level, $message, array $context = []): void
|
||||
{
|
||||
$level = $this->castLogLevel($level);
|
||||
|
||||
if (!$this->shouldLog($level)) {
|
||||
return;
|
||||
}
|
||||
$log_replace = [
|
||||
'%date%' => date(self::$date_format),
|
||||
'%level%' => strtoupper(substr(self::$levels[$level], 0, 4)),
|
||||
'%body%' => $message,
|
||||
'%level_short%' => strtoupper(substr(self::$levels[$level], 0, 1)),
|
||||
];
|
||||
|
||||
$output = str_replace(
|
||||
['%date%', '%level%', '%body%'],
|
||||
[date(self::$date_format), strtoupper(substr(self::$levels[$level], 0, 4)), $message],
|
||||
self::$format
|
||||
);
|
||||
$output = str_replace(array_keys($log_replace), array_values($log_replace), self::$format);
|
||||
$output = $this->interpolate($output, array_merge($this->static_context, $context));
|
||||
|
||||
foreach ($this->log_callbacks as $callback) {
|
||||
if ($callback($level, $output, $message, $context) === false) {
|
||||
if ($callback($level, $output, $message, $context, $this->shouldLog($level)) === false) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->shouldLog($level)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->decorated) {
|
||||
$output = $this->colorize($output, $level) . PHP_EOL;
|
||||
} else {
|
||||
@ -237,21 +246,30 @@ class ConsoleLogger extends AbstractLogger
|
||||
fwrite($this->stream, $output);
|
||||
fflush($this->stream);
|
||||
} else {
|
||||
// use plain text output
|
||||
echo $output;
|
||||
if ($level <= 4 && $this->use_stderr) {
|
||||
fwrite(STDERR, $output);
|
||||
} else {
|
||||
// use plain text output
|
||||
echo $output;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function setDecorated(bool $decorated): void
|
||||
{
|
||||
$this->decorated = $decorated;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换日志等级
|
||||
*/
|
||||
private function castLogLevel(string $level): int
|
||||
protected function castLogLevel(string $level): int
|
||||
{
|
||||
if (in_array($level, self::$levels, true)) {
|
||||
return array_flip(self::$levels)[$level];
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException('无效的日志等级');
|
||||
throw new InvalidArgumentException('Invalid log level: ' . $level);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -259,7 +277,7 @@ class ConsoleLogger extends AbstractLogger
|
||||
*
|
||||
* @param mixed $item 日志内容
|
||||
*/
|
||||
private function stringify($item): string
|
||||
protected function stringify($item): string
|
||||
{
|
||||
switch (true) {
|
||||
case is_callable($item):
|
||||
@ -293,7 +311,7 @@ class ConsoleLogger extends AbstractLogger
|
||||
/**
|
||||
* 判断是否应该记录该等级日志
|
||||
*/
|
||||
private function shouldLog(int $level): bool
|
||||
protected function shouldLog(int $level): bool
|
||||
{
|
||||
return $level <= self::$log_level;
|
||||
}
|
||||
@ -304,7 +322,7 @@ class ConsoleLogger extends AbstractLogger
|
||||
* @param string $message 日志内容
|
||||
* @param array $context 变量列表
|
||||
*/
|
||||
private function interpolate(string $message, array $context = []): string
|
||||
protected function interpolate(string $message, array $context = []): string
|
||||
{
|
||||
$replace = [];
|
||||
foreach ($context as $key => $value) {
|
||||
|
||||
@ -137,8 +137,8 @@ class TablePrinter
|
||||
$line_data[$current_line] = [
|
||||
'used' => $valid_width - $k_len - 2 - $partial_v_len,
|
||||
'can_put_second' => false,
|
||||
'lines' => $k . ': ' .
|
||||
ConsoleColor::apply([$this->value_color], $partial_v . str_pad('', $valid_width - $k_len - 2 - $partial_v_len, '.')),
|
||||
'lines' => $k . ': '
|
||||
. ConsoleColor::apply([$this->value_color], $partial_v . str_pad('', $valid_width - $k_len - 2 - $partial_v_len, '.')),
|
||||
];
|
||||
++$current_line;
|
||||
// 下一个参数
|
||||
@ -237,7 +237,12 @@ class TablePrinter
|
||||
}
|
||||
} else {
|
||||
$size = exec('stty size 2>/dev/null');
|
||||
$size = (int) explode(' ', trim($size))[1];
|
||||
// in case stty is not available
|
||||
if (empty($size)) {
|
||||
$size = 0;
|
||||
} else {
|
||||
$size = (int) explode(' ', trim($size))[1];
|
||||
}
|
||||
}
|
||||
if (empty($size)) {
|
||||
return $this->terminal_size = 79;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user