You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel如何向Google Stackdriver日志注入自定义进程ID?

解决Laravel中Google Cloud Logging注入PID的问题

我来帮你搞定这个问题!你遇到的核心问题是:你的stackdriver日志通道没有应用ProcessorTap处理逻辑,而你只在本地的single通道里配置了tap。下面分步骤给你解决方案:

原因分析

Laravel的tap配置是用来在日志实例初始化后,对其进行额外修改的机制。但你当前的stackdriver通道是通过custom驱动+CreateStackdriverLogger类手动创建Monolog实例的,而且没有给这个通道添加tap配置,所以你的PID处理器根本没作用在Stackdriver的日志链路上。另外,Stackdriver使用的PsrHandler会把日志转发到Google的PSR日志客户端,Monolog的LineFormatter对它来说是无效的(Google会自己处理日志格式),但你添加到extra或context里的PID会被保留并发送到Google日志服务。

方案一:给Stackdriver通道添加Tap配置

这是最贴合你现有代码结构的方案:

1. 更新config/logging.php的Stackdriver通道

给stackdriver数组加上tap配置,让Laravel初始化这个通道时应用你的处理器:

'stackdriver' => [
    'driver' => 'custom',
    'via' => App\Logging\CreateStackdriverLogger::class,
    'level' => 'debug',
    'tap' => [App\Logging\ProcessorTap::class], // 新增这一行
],

2. 调整ProcessorTap.php适配Stackdriver

因为Stackdriver不需要Monolog的LineFormatter,我们可以给处理器加个判断,只给本地日志通道设置格式,避免无效操作:

namespace App\Logging;

use Illuminate\Log\Logger;
use Illuminate\Support\Arr;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\StreamHandler; // 导入StreamHandler类

class ProcessorTap
{
    public function __invoke($logger)
    {
        foreach ($logger->getHandlers() as $handler) {
            // 给所有通道添加PID处理器
            $handler->pushProcessor([$this, 'processLogRecord']);

            // 只给本地文件日志设置自定义格式
            if ($handler instanceof StreamHandler) {
                $handler->setFormatter($this->getLogFormatter());
                $handler->pushProcessor(function ($record) {
                    return Arr::add($record, 'prefix', getmypid());
                });
            }
        }
    }

    public function processLogRecord(array $record): array
    {
        $record['extra'] += [
            'pid' => getmypid(),
        ];

        return $record;
    }

    protected function getLogFormatter()
    {
        $format = "[%datetime%] %channel%.%level_name%: %prefix%.%message% %context% %extra%\n";
        return new LineFormatter($format, null, true, true);
    }
}

方案二:直接在CreateStackdriverLogger中添加处理器

如果你不想依赖Laravel的tap机制,也可以直接在创建Stackdriver Logger的过程中注入处理器,这样更直观:

修改CreateStackdriverLogger.php:

use Google\Cloud\Logging\LoggingClient;
use Monolog\Handler\PsrHandler;
use Monolog\Logger;
use App\Logging\ProcessorTap; // 导入你的处理器类

class CreateStackdriverLogger
{
    /**
     * Create a custom Monolog instance.
     *
     * @param array $config
     * @return \Monolog\Logger
     */
    public function __invoke(array $config)
    {
        $logName = isset($config['logName']) ? $config['logName'] : 'app';
        $psrLogger = LoggingClient::psrBatchLogger($logName);
        $handler = new PsrHandler($psrLogger);
        $logger = new Logger($logName, [$handler]);

        // 直接添加PID处理器到Stackdriver Logger
        $processor = new ProcessorTap();
        $logger->pushProcessor([$processor, 'processLogRecord']);

        return $logger;
    }
}

测试验证

修改完成后,记得清理配置缓存:

php artisan config:clear

然后触发一条日志(比如Log::debug('Test log with PID');),去Google Cloud Console的Logging页面查看这条日志的详情。你会在jsonPayload字段下找到extra.pid,里面就是当前进程的ID啦!

内容的提问来源于stack exchange,提问作者JimmyJige

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 10:08:14