graylog_codeigniter 不支持 codeigniter 4,因其基于 ci 2.x 的 log 类,与 ci 4 的 psr-3 日志系统(如 filehandler)完全不兼容,错误包括 class 'ci_log' not found;ci 4 用户应使用 monolog/monolog + graylog2/gelf-php,通过 gelfhandler 发送标准 gelf 格式日志至 graylog。

Graylog_CodeIgniter 扩展不支持 CodeIgniter 4
如果你正在用 CodeIgniter 4,Graylog_CodeIgniter 这个扩展根本跑不起来——它只适配 CI 2.x 和部分 CI 3.0 早期版本。CI 4 的日志系统已重构为 CodeIgniter\Log\Handlers\FileHandler 等可插拔 Handler,而 Graylog_CodeIgniter 仍基于 CI 2 的 Log 类重写,类名、方法签名、加载机制全不兼容。
常见错误现象:Class 'CI_Log' not found 或 Call to undefined method CodeIgniter\Log\Logger::write_log()。别折腾 autoload 或别名映射,底层契约已断裂。
- CI 3.1.11+ 用户:可尝试用社区维护的 fork(如
graylog-ci3),但需手动替换system/core/Log.php并禁用原生日志写入 - CI 4 用户:必须改用 PSR-3 兼容方案,比如
monolog/monolog+graylog2/gelf-php - 所有版本都绕不开 GELF 协议:Graylog 只认 GELF 格式(UDP/TCP/HTTP),原始
error_log()或文件内容直接发过去会被丢弃
用 Monolog + GelfHandler 发送日志到 Graylog(CI 4 推荐路径)
CI 4 默认日志系统不支持外发,但允许注入自定义 Logger 实例。最稳的方式是用 monolog/monolog 替换默认 Logger,并挂载 GelfHandler。
实操步骤:
- 执行
composer require monolog/monolog graylog2/gelf-php - 在
app/Config/Logger.php中关闭默认 FileHandler:$this->threshold = 0; - 在
app/Services.php中重写logger服务,返回 Monolog 实例并添加GelfHandler - 确保 Graylog 输入配置为 GELF UDP(端口 12201)或 GELF HTTP(端口 12202),且防火墙放行
关键代码片段(app/Services.php):
public static function logger($getShared = true)
{
if ($getShared) {
return static::getSharedInstance('logger');
}
$logger = new \Monolog\Logger('ci4');
$gelfHandler = new \Monolog\Handler\GelfHandler(
new \Gelf\Publisher(new \Gelf\Transport\UdpTransport('graylog-host', 12201))
);
$logger->pushHandler($gelfHandler);
return $logger;
}
CI 3 下强行接入 Graylog_CodeIgniter 的风险点
即使你降级到 CI 3.0.6,Graylog_CodeIgniter 仍有三个硬伤:
- 它把所有日志强制转成
emergency级别发往 Graylog,丢失debug/info等分级能力 - 不支持 TLS 或认证,明文走 UDP,内网尚可,上云环境会被安全组拦截或审计驳回
-
$_SERVER['REMOTE_ADDR']等字段直接拼进 message 字段,没走 GELF 的additional层,Graylog 里无法做字段提取和过滤
如果必须用,至少补一手:在 application/libraries/Graylog.php 的 send() 方法里,用 json_encode() 构造完整 GELF 结构体,而非字符串拼接。
Graylog 端必须校验的三项配置
本地代码发得再对,Graylog 收不到就是白搭。上线前盯死这三处:
- Inputs 页面确认对应输入处于
Running状态,不是Failed或Paused;点开详情看Last received message时间戳是否实时更新 - 检查 Input 的
Bind address:设为0.0.0.0而非127.0.0.1,否则容器或跨主机场景收不到 - UDP 输入默认有
Maximum message size(通常 8192 字节),CI 日志若含大堆$_POST或异常 trace,会静默截断——调高到32768更稳妥
真正卡住人的往往不是代码怎么写,而是某台机器的 SELinux 拦了 UDP,或是 Docker 网络模式没暴露 12201 端口。先 nc -u graylog-host 12201 测通不通,再查代码。











