日志記錄的時候,有沒有什么辦法能將一次請求相關(guān)的日志按照順序羅列出來。 包括中間手動記錄的日志。以及可能的異步執(zhí)行的日志
目前用webman/log日志插件,只能保證默認(rèn)的請求及SQl日志在一起。 自己記錄一些日志的話。 不同請求的日志就會串在一起,很難排查一個請求完整的邏輯。
有沒有什么辦法能將一次請求的日志按照順序排列。 甚至是異步執(zhí)行的邏輯里面的日志。
例如在一開始搞個 request_id 所有的日志中都包含這個request_id 。 目前沒想到什么優(yōu)雅的方式在整個請求生命周期中傳遞這個request_id
這里寫問題具體描述
日志用Monolog自定義一個Handler,handler里的write方法里調(diào)用生成一個保存在Context里的request_id,類似這樣
handler:
protected function write(LogRecord $record): void
{
$record['formatted']['extra']['request_id'] = RequestIdHolder::getId();
$this->connection->table($this->collection)->insert($record['formatted']);
}
RequestIdHolder
public static function getId(): string
{
//上下文獲取
$requestId = Context::get(self::REQUEST_ID);
if (is_null($requestId)) {
$requestId = self::getUniqueId();
}
return $requestId;
}
謝謝大佬回復(fù)。 webman中的 Monolog 如何在配置文件中增加自定義的 processer 預(yù)處理下日志呢? 我看文檔里面也沒有相關(guān)寫法。 http://www.symfonychina.com/doc/current/logging/processors.html 我想按照這個用法,自定義一個processor,結(jié)合context 插入一個 request_id
配置文件里面沒找到寫法
return [
'default' => [
'handlers' => [
[
'class' => Monolog\Handler\RotatingFileHandler::class,
'constructor' => [
runtime_path() . '/logs/webman.log',
7, //$maxFiles
Monolog\Logger::DEBUG,
],
'formatter' => [
'class' => Monolog\Formatter\LineFormatter::class,
'constructor' => [null, 'Y-m-d H:i:s', true],
],
'processors' => [
xxxxx::class, // 是在這里配置嗎?
]
]
],
],
];
我這樣寫了不生效
搞定了,分享下
LogProcessor 定義一個日志處理器
<?php
namespace support;
use Monolog\Processor\ProcessorInterface;
class LogProcessor implements ProcessorInterface
{
public function __invoke(array $record): array
{
$key = 'request_id';
if (is_null(Context::get($key))) {
Context::set($key, md5(uniqid() . mt_rand(0, 1000000)));
}
$record['extra'][$key] = Context::get($key);
return $record;
}
}
config/log.php 配置文件
<?php
return [
'default' => [
'handlers' => [
[
'class' => Monolog\Handler\RotatingFileHandler::class,
'constructor' => [
runtime_path() . '/logs/webman.log',
7, //$maxFiles
Monolog\Logger::DEBUG,
],
'formatter' => [
'class' => Monolog\Formatter\LineFormatter::class,
'constructor' => [null, 'Y-m-d H:i:s', true],
],
]
],
'processors' => [
[
'class' => support\LogProcessor::class,
'constructor' => []
]
]
],
];
添加 processors 到配置文件中
測試記錄的日志如下
[2024-11-22 10:53:38] default.WARNING: 你好啊 {"a":1,"b":2} {"request_id":"fbd5b1e266516c2e47bfdf2909f11512"}
[2024-11-22 10:53:38] default.INFO: 127.0.0.1 GET localhost:8787/admin/user/test [41.9690ms] [webman/log]
[SQL] [connection:default] select `id`, `name`, `phone` from `admin_account` where `phone` is not null order by `id` asc limit 10 [10.25 ms]
[] {"request_id":"fbd5b1e266516c2e47bfdf2909f11512"}
[2024-11-22 10:54:06] default.INFO: hello [] {"request_id":"796681486b0d06e11bf15dc5d19f05e3"}
[2024-11-22 10:54:07] default.INFO: hello [] {"request_id":"796681486b0d06e11bf15dc5d19f05e3"}
[2024-11-22 10:54:08] default.WARNING: 你好啊 {"a":1,"b":2} {"request_id":"2f46f2f44895a4615b65198477a78dd6"}
[2024-11-22 10:54:08] default.INFO: 127.0.0.1 GET localhost:8787/admin/user/test [12.3229ms] [webman/log]
[SQL] [connection:default] select `id`, `name`, `phone` from `admin_account` where `phone` is not null order by `id` asc limit 10 [9.1 ms]
[] {"request_id":"2f46f2f44895a4615b65198477a78dd6"}
[2024-11-22 10:54:08] default.INFO: hello [] {"request_id":"796681486b0d06e11bf15dc5d19f05e3"}
[2024-11-22 10:54:09] default.WARNING: 你好啊 {"a":1,"b":2} {"request_id":"8d0321512b6d826d1b6f4d9b96ac8a5c"}
[2024-11-22 10:54:09] default.INFO: 127.0.0.1 GET localhost:8787/admin/user/test [3.91101ms] [webman/log]
[SQL] [connection:default] select `id`, `name`, `phone` from `admin_account` where `phone` is not null order by `id` asc limit 10 [3.26 ms]
[] {"request_id":"8d0321512b6d826d1b6f4d9b96ac8a5c"}
[2024-11-22 10:54:09] default.INFO: hello [] {"request_id":"796681486b0d06e11bf15dc5d19f05e3"}
[2024-11-22 10:54:09] default.WARNING: 你好啊 {"a":1,"b":2} {"request_id":"01cbfa3e8ff72b95b70ab0e542d16ed2"}
[2024-11-22 10:54:09] default.INFO: 127.0.0.1 GET localhost:8787/admin/user/test [3.79085ms] [webman/log]
[SQL] [connection:default] select `id`, `name`, `phone` from `admin_account` where `phone` is not null order by `id` asc limit 10 [3.34 ms]
[] {"request_id":"01cbfa3e8ff72b95b70ab0e542d16ed2"}
[2024-11-22 10:54:10] default.INFO: hello [] {"request_id":"796681486b0d06e11bf15dc5d19f05e3"}
[2024-11-22 10:54:11] default.INFO: hello [] {"request_id":"796681486b0d06e11bf15dc5d19f05e3"}
[2024-11-22 10:54:12] default.INFO: hello [] {"request_id":"796681486b0d06e11bf15dc5d19f05e3"}
[2024-11-22 10:54:13] default.INFO: hello [] {"request_id":"796681486b0d06e11bf15dc5d19f05e3"}
[2024-11-22 10:54:14] default.INFO: hello [] {"request_id":"796681486b0d06e11bf15dc5d19f05e3"}
[2024-11-22 10:54:15] default.INFO: hello [] {"request_id":"796681486b0d06e11bf15dc5d19f05e3"}
[2024-11-22 10:54:15] default.INFO: 127.0.0.1 GET localhost:8787/admin/user/get [10050.3ms] [webman/log]
[SQL] [connection:default] select count(*) as aggregate from `admin_account` [3.88 ms]
[SQL] [connection:default] select count(*) as aggregate from `admin_account` [3.96 ms]
[SQL] [connection:default] select count(*) as aggregate from `admin_account` [4.08 ms]
[SQL] [connection:default] select count(*) as aggregate from `admin_account` [4.17 ms]
[SQL] [connection:default] select count(*) as aggregate from `admin_account` [3.88 ms]
[SQL] [connection:default] select count(*) as aggregate from `admin_account` [4.12 ms]
[SQL] [connection:default] select count(*) as aggregate from `admin_account` [4.25 ms]
[SQL] [connection:default] select count(*) as aggregate from `admin_account` [3.93 ms]
[SQL] [connection:default] select count(*) as aggregate from `admin_account` [4.07 ms]
[SQL] [connection:default] select count(*) as aggregate from `admin_account` [3.48 ms]
[] {"request_id":"796681486b0d06e11bf15dc5d19f05e3"}
日志效果,例如其中 request_id : 796681486b0d06e11bf15dc5d19f05e3 是循環(huán)執(zhí)行,用于測試被其它請求打斷。 可以根據(jù)這個搜索所有相關(guān)日志。結(jié)合其它日志分析工具。 結(jié)合request_id,以及日志時間。 分析單次請求的所有日志