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

Seldaek/monolog中NativeMailerHandler与DeduplicationHandler搭配失效问题

问题分析与解决方案

核心原因

你的问题大概率出在Monolog版本差异或批量发送机制未触发上:

  • 若使用Monolog 1.x版本,DeduplicationHandler的flush()方法仅会清除内部缓存,不会转发调用被包裹的NativeMailerHandler的flush()。而NativeMailerHandler继承自MailHandler,默认会批量缓存日志记录,只有调用flush()时才会实际发送邮件。
  • 单独使用NativeMailerHandler时,Logger的析构函数会自动触发flushHandlers()完成邮件发送;但被DeduplicationHandler包裹后,DeduplicationHandler的flush()不执行转发,导致邮件始终停留在缓存中无法发出。

解决方案

方案1:升级到Monolog 2.x+版本

Monolog 2.x及后续版本修复了这个问题,DeduplicationHandler的flush()方法会主动调用被包裹handler的flush(),自动触发邮件发送,无需修改现有代码。

方案2:修改NativeMailerHandler的批量发送配置

将NativeMailerHandler的batchSize设为1,让每条符合级别的日志立即发送,无需等待flush():

$mailHandler = new NativeMailerHandler(
    $_ENV['ERROR_NOTIFICATION_EMAIL'],
    'Error from My Site',
    'no-reply@mydomain',
    Level::Error
);
$mailHandler->setBatchSize(1); // 新增该行,强制单条记录立即发送

方案3:手动触发日志刷新

在脚本执行结束或合适的时机,手动调用Logger的flushHandlers(),确保所有handler完成处理:

// 在脚本逻辑末尾添加
$logger->flushHandlers();

方案4:自定义DeduplicationHandler(针对Monolog 1.x)

若无法升级版本,可创建自定义子类重写flush()方法,转发调用子handler的刷新逻辑:

class CustomDeduplicationHandler extends DeduplicationHandler
{
    public function flush()
    {
        $this->handler->flush(); // 触发子handler的邮件发送
        parent::flush(); // 执行父类的缓存清除逻辑
    }
}

// 替换原代码中的DeduplicationHandler使用
$handlers = [
    new CustomDeduplicationHandler($streamHandler),
    new CustomDeduplicationHandler($mailHandler)
];

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 21:43:15