Logs
Index
ใTipใ
- The log handling
Handler
includesMonolog\Handler\StreamHandler
andMonolog\Handler\RotatingFileHandler
, where the configuration is for a processor that rotates based on the date. - Logs of
INFO
level and above will be written to the info log, and logs ofERROR
level and above will be written to the error log. The logs are split by day. Hyperf
has referenced some content frommonolog
. For more details, see: Monolog.
Install Dependencies
composer require hyperf/logger
Log Config
config/autoload/logger.php
<?php
declare(strict_types=1);
use Monolog\Level;
return [
'default' => [
'handlers' => [
// ่ฎฐๅฝINFO็บงๅซๅไปฅไธ็ญ็บงๆฅๅฟ
[
'class' => Monolog\Handler\RotatingFileHandler::class,
'constructor' => [
'filename' => BASE_PATH . '/runtime/logs/info.log',
'level' => Level::Info,
],
'formatter' => [
'class' => Monolog\Formatter\LineFormatter::class,
'constructor' => [
'format' => "[%datetime%]|[%channel%]|[%level_name%]|[%message%]|[%context%]\n",
'dateFormat' => 'Y-m-d H:i:s',
'allowInlineLineBreaks' => true,
],
],
],
// ่ฎฐๅฝERRORๅไปฅไธๆฅๅฟ
[
'class' => Monolog\Handler\RotatingFileHandler::class,
'constructor' => [
'filename' => BASE_PATH . '/runtime/logs/error.log',
'level' => Level::Error,
],
'formatter' => [
'class' => Monolog\Formatter\LineFormatter::class,
'constructor' => [
'format' => "[%datetime%]|[%channel%]|[%level_name%]|[%message%]|[%context%]\n",
'dateFormat' => 'Y-m-d H:i:s',
'allowInlineLineBreaks' => true,
],
],
],
],
],
];
Example:
Encapsulation Of The Call.
<?php
declare(strict_types=1);
namespace App\Lib\Log;
use App\Constants\ConstCode;
use App\Job\ReportLogJob;
use App\Lib\RedisQueue\RedisQueueFactory;
use Carbon\Carbon;
use Hyperf\Context\ApplicationContext;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Coroutine\Coroutine;
use Hyperf\Logger\LoggerFactory;
use Hyperf\Stringable\Str;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
/**
* @method static void info(string $msg, array $content = [], string $straceString = '')
* @method static void warning(string $msg, array $content = [], string $straceString = '')
* @method static void error(string $msg, array $content = [], string $straceString = '')
* @method static void alert(string $msg, array $content = [], string $straceString = '')
* @method static void critical(string $msg, array $content = [], string $straceString = '')
* @method static void emergency(string $msg, array $content = [], string $straceString = '')
* @method static void notice(string $msg, array $content = [], string $straceString = '')
*/
class Log
{
/**
* ้ๆ่ฐ็จ.
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public static function __callStatic(string $level, array $args = []): void
{
// ่ทๅๆ่ฟไธคๅฑ็่ฐ็จๆ ไฟกๆฏ
[$headTrace, $lastTrace] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
// ้ๆ่ฐ็จๅๆฐๅค็
[$message, $context, $traceString] = [
$args[0] ?? '',
$args[1] ?? [],
$args[2] ?? '',
];
// ่็นchannel
$channel = "{$lastTrace['class']}@{$lastTrace['function']}";
// ๅฝๅๆฅๆ
$nowDate = Carbon::now()->toDateTimeString();
// string context
$contextString = json_encode($context, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
// ๅผๆญฅ้ๅๅๅ
ฅๆฐๆฎๅบ(ๅฏไปฅ็จๅ
ถไปๆนๅผๆฟไปฃๆฅๅฟไธๆฅ)
$jobParams = [
'level' => Str::upper($level),
'class' => $lastTrace['class'],
'function' => $lastTrace['function'],
'message' => $message,
'context' => $contextString,
'file' => $headTrace['file'],
'line' => $headTrace['line'],
'trace' => $traceString,
];
Coroutine::create(function () use ($jobParams) {
$job = new ReportLogJob(uniqid(), $jobParams);
RedisQueueFactory::safePush($job, ConstCode::LOCK_QUEUE_NAME, 0);
});
// CLI่พๅบ
$stdoutMessage = $traceString === '' ?
"[{$nowDate}][{$channel}][{$message}]" :
"[{$nowDate}][{$channel}][{$message}]\n{$traceString}";
static::stdout()->{$level}($stdoutMessage);
// DISK่พๅบ
static::get($channel)->{$level}($message, $context);
}
/**
* ่ทๅLoggerๅฎไพ.
* @throws ContainerExceptionInterface|NotFoundExceptionInterface
*/
public static function get(string $channel = ''): LoggerInterface
{
return ApplicationContext::getContainer()->get(LoggerFactory::class)->get($channel);
}
/**
* CLI ๆฅๅฟๅฎไพ.
* @throws ContainerExceptionInterface|NotFoundExceptionInterface
*/
public static function stdout(): StdoutLoggerInterface
{
return ApplicationContext::getContainer()->get(StdoutLoggerInterface::class);
}
}