Skip to content

[8.x] 关于当前日志打印时间不是真实写入时间问题 #3142

Open
@NHZEX

Description

@NHZEX

功能请求与问题

当前 tp 里 log 如果没开实时输出,输出log行上的时间是按save时的时间来算的,不是打日志那一刻的真实时间。当前这个设计比较反直觉,日志的打印时间是个排除问题的关键因素,应该总是如实反映。

既然新版本的的日志数据结构改了,不如考虑下让日志时间变为真实的打印时间。

if (!empty($msg) || 0 === $msg) {
$this->log[] = [$type, $msg];
if ($this->event) {

描述您想要的解决方案

  1. 在 Channel->record 里记录打日志一刻的真实时间。
  2. 日志的 $context 往下传递,允许各个驱动获得完整日志上下文自主二次处理。
  3. 日志行直接封装为 LogRecord 对象,参考 https://github.com/Seldaek/monolog/blob/2e97231b969e0ffdeff03329b808945b4ba55e38/src/Monolog/LogRecord.php#L29-L39

基于当前新版的我使用的方案

    public function record($msg, string $type = 'info', array $context = [], bool $lazy = true)
    {
        if ($this->close || (!empty($this->allow) && !\in_array($type, $this->allow))) {
            return $this;
        }

       // 也许在这里就把日志行转换为 LogRecord 对象,后面的扩展与传递都更加规范和统一
        if ($msg instanceof \Stringable) {
            $msg = (string) $msg;
        }

        if (\is_string($msg) && !empty($context)) {
            $replace = [];
            foreach ($context as $key => $val) {
                $replace['{'.$key.'}'] = $val;
            }

            $msg = strtr($msg, $replace);
        }

        $context["\0_i"] = $this->count++;
        $context["\0_t"] = new \DateTimeImmutable();

        if ('' === $msg) {
            $msg = '"(empty string)"';
        } elseif (null === $msg) {
            $msg = '"(null)"';
        }

        if (!empty($msg) || 0 === $msg) {
            $this->log[] = [$type, $msg, $context];
            if ($this->event) {
                $this->event->trigger(new LogRecord($type, $msg));
            }
        }

        if (!$this->lazy || !$lazy) {
            $this->save();
        }

        return $this;
    }

描述您考虑过的替代方案
或许考虑上成熟的日志库:monolog/monolog

其它信息

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions