有没有办法将日志根据请求整合在一起

henian

问题描述

日志记录的时候,有没有什么办法能将一次请求相关的日志按照顺序罗列出来。 包括中间手动记录的日志。以及可能的异步执行的日志

目前用webman/log日志插件,只能保证默认的请求及SQl日志在一起。 自己记录一些日志的话。 不同请求的日志就会串在一起,很难排查一个请求完整的逻辑。

有没有什么办法能将一次请求的日志按照顺序排列。 甚至是异步执行的逻辑里面的日志。
例如在一开始搞个 request_id 所有的日志中都包含这个request_id 。 目前没想到什么优雅的方式在整个请求生命周期中传递这个request_id

这里写问题具体描述

226 2 3
2个回答

Jinson

日志用Monolog自定义一个Handler,handler里的write方法里调用生成一个保存在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;
}
  • henian 2024-11-22

    Context::get 这个用法哪里有相关文档吗? 我看wenman里面有这个对象,但是不知道生命周期是什么。文档里面没看到相关说明

  • walkor 2024-11-22

    Context生命周期和请求周期是一致的

  • henian 2024-11-22

    谢谢大佬回复。 webman中的 Monolog 如何在配置文件中增加自定义的 processer 预处理下日志呢? 我看文档里面也没有相关写法。 http://www.symfonychina.com/doc/current/logging/processors.html 我想按照这个用法,自定义一个processor,结合context 插入一个 request_id

  • walkor 2024-11-22

    config/log.php 里配置 processers

  • henian 2024-11-22

    配置文件里面没找到写法

    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, // 是在这里配置吗?
    ]
    ]
    ],
    ],
    ];

    我这样写了不生效

  • walkor 2024-11-22

    vendor/workerman/webman-framework/src/support/Log.php
    我不记得了,你研究下源码

  • henian 2024-11-22

    好的,谢谢

henian

搞定了,分享下

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 是循环执行,用于测试被其它请求打断。 可以根据这个搜索所有相关日志。结合其它日志分析工具。 结合request_id,以及日志时间。 分析单次请求的所有日志

  • 暂无评论
×
🔝