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

Laravel(Monolog)日志传递可选自定义参数的实现问题

Laravel 8 自定义Monolog MySQL处理器添加可选Domain ID参数方案

核心思路

利用Monolog的context参数传递可选的domain_id,同时修改数据库表和处理器代码,将domain_id存入单独字段,方便后续检索。

步骤1:修正日志调用方式

Laravel日志方法的第二个参数要求是关联数组(即context),需把domain_id放在数组中传递:

// 带domain_id的日志
Log::info("New record created for domain", ['domain_id' => $domain_id]);

// 不带domain_id的常规日志不受影响
Log::info("System initialization completed");

步骤2:更新数据库表结构

给log_entries表添加可选的domain_id字段(允许为null),通过迁移实现:

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddDomainIdToLogEntriesTable extends Migration
{
    public function up()
    {
        Schema::table('log_entries', function (Blueprint $table) {
            $table->unsignedBigInteger('domain_id')->nullable()->after('message');
            // 可选:添加索引提升检索速度
            $table->index('domain_id');
        });
    }

    public function down()
    {
        Schema::table('log_entries', function (Blueprint $table) {
            $table->dropIndex(['domain_id']);
            $table->dropColumn('domain_id');
        });
    }
}

执行迁移:

php artisan migrate

步骤3:修改自定义MySQL处理器

在MySQLLoggingHandler的write方法中,从$record['context']提取domain_id并存入数据库:

namespace App\Logging;
use DB;
use Illuminate\Support\Facades\Auth;
use Monolog\Logger;
use Monolog\Handler\AbstractProcessingHandler;

class MySQLLoggingHandler extends AbstractProcessingHandler{

    public function __construct($level = Logger::DEBUG, $bubble = true) {
        parent::__construct($level, $bubble);
    }

    protected function write(array $record):void
    {
        $remote_addr = $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';
        $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown';
        
        $data = array(
            'message'           => $record['message'],
            'domain_id'         => $record['context']['domain_id'] ?? null, // 新增提取domain_id的逻辑
            'context'           => json_encode($record['context']),
            'level'             => $record['level'],
            'level_name'        => $record['level_name'],
            'channel'           => $record['channel'],
            'record_datetime'   => $record['datetime']->format('Y-m-d H:i:s'),
            'extra'             => json_encode($record['extra']),
            'formatted'         => $record['formatted'],
            'remote_addr'       => $remote_addr,
            'user_agent'        => $user_agent,
            'created_at'        => date("Y-m-d H:i:s"),
        );
        DB::connection()->table('log_entries')->insert($data);
    }
}

这里用PHP 8的??空合并运算符简化了空值判断,同时保留原有context的存储,不影响其他上下文数据的记录。

效果验证

现在可以直接通过domain_id字段快速检索对应日志:

// 查询某个domain的所有日志
$logs = DB::table('log_entries')->where('domain_id', 123)->get();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 13:27:42