用途
bitrix-logger 用于在 Bitrix 框架中以 PSR-3 标准接入日志能力。业务代码只依赖 Psr\Log\LoggerInterface,由 .settings.php 的 loggers 配置段决定具体实现,避免在业务代码里硬编码 new FileLogger() 之类的写法。AddMessage2Log() 仅作为兼容手段保留。
基线:main 23.0+;已验证:main 26.800.0。
主要能力
内置实现(Bitrix\Main\Diag\)
- FileLogger(string $fileName, ?int $maxSize = null):默认上限 1 MB,超出后重命名为 <file>.old;0 表示不轮转。
- SysLogger(string $prefix = '', int $flags = LOG_ODELAY, int $facility = LOG_USER):写入系统 syslog。
- EventLogger(?string $module, ?string $auditType, ?callable $callback):写入 b_event_log(后台事件日志),仅适合低量场景。
格式化器
- LogFormatter($showArguments = false, $argMaxChars = 30):默认格式化器,支持 {date} {host} {level} {delimiter} {exception} {trace} 等占位符以及 context 键。
- JsonLinesFormatter(自 main 25.300 起;更早版本使用 LogFormatter):只把 $context 写成一行 JSON,消息文本会被丢弃,因此需要把消息内容放进 context。
注意:level 与 formatter 设置只对 Bitrix\Main\Diag\Logger 子类生效,对 Monolog 无效。
使用方式
获取日志器(自 main 26.250 起:LoggerFactory + LoggerRegistry)
use Bitrix\Main\Diag\LoggerFactory;
use Bitrix\Main\Diag\LoggerRegistry;
$logger = (new LoggerFactory())->createById('vendor.module.sync'); // 未启用时为 NullLogger
(new LoggerRegistry())->enable('vendor.module.sync'); // option loggers:logger_is_enabled_<id> = Y
$logger = (new LoggerFactory())->createById('vendor.module.sync', [], false); // 跳过注册表检查
已启用但 loggers 段没有对应条目的 id 会得到默认日志器(LOG_FILENAME 常量)或 NullLogger。以这种方式创建的内核 id 在启用前保持静默,例如:main.Messenger.Receiver、main.Messenger.Requeue、main.config.feature、bizproc.imbot 等。
Logger::create($id, $params)(自 main 26.300 起废弃,是 26.250 之前唯一的 API)在 $id 未配置时返回 null:
$logger = Logger::create('id') ?? new NullLogger();
注入到服务(模块 .settings.php)
\Vendor\Module\Public\Service\SyncService::class => [
'className' => \Vendor\Module\Public\Service\SyncService::class,
'constructorParams' => static fn () => [(new \Bitrix\Main\Diag\LoggerFactory())->createById('vendor.module.sync')],
],
loggers 配置段
应放入 /local/.settings_extra.php:因为闭包无法在内核重写主文件(bitrix-settings)后存活。
'services' => [
'value' => [
'vendor.formatter.json' => ['className' => \Bitrix\Main\Diag\JsonLinesFormatter::class],
],
],
'loggers' => [
'value' => [
'vendor.module.sync' => [
'constructor' => static fn () => new \Bitrix\Main\Diag\FileLogger('/var/log/site/sync.log', 10 * 1024 * 1024),
'level' => \Psr\Log\LogLevel::INFO, // 阈值
'formatter' => 'vendor.formatter.json', // 服务 id
],
'main.HttpClient' => [
'constructor' => static function (\Bitrix\Main\Web\Http\DebugInterface $debug, \Psr\Http\Message\RequestInterface $request) {
$debug->setDebugLevel(\Bitrix\Main\Web\HttpDebug::ALL);
return new \Bitrix\Main\Diag\FileLogger('/var/log/site/http.log');
},
],
],
'readonly' => true,
],
条目形式:constructor 闭包(接收工厂的 $params),或 className + constructorParams(数组,或返回数组的闭包)。
内核日志器 id
| Id | 使用者 | 闭包参数 |
|---|---|---|
| main.Default | AddMessage2Log()、默认日志器 | $logFileName, $showArgs |
| main.HttpClient | HttpClient / PSR-18 handlers | DebugInterface $debug, RequestInterface $request |
| main.GeoIpManager | GeoIP manager | — |
| main.EventLog.SysLogger, main.EventLog.FileLogger | CEventLog 后端 | —, $path, $maxSize |
不存在 main.Mail 或 main.Engine 这两个 id。
写入日志
$this->logger->error('Sync of order {orderId} failed: {exception}', ['orderId' => $id, 'exception' => $e]);
占位符 {key} 取自 context;exception 会渲染类名、消息与堆栈。不带异常时获取堆栈:
'trace' => \Bitrix\Main\Diag\Helper::getBackTrace(6, DEBUG_BACKTRACE_IGNORE_ARGS),
Monolog 集成
执行 composer require monolog/monolog 后,在 constructor 闭包中返回 Monolog\Logger 即可;其 level 与 formatter 需在 Monolog 中设置。
适用场景
- 为 Bitrix 模块与业务服务注入 PSR-3 日志接口,解耦具体实现。
- 需要统一配置日志级别、格式与轮转策略的项目。
- 需要接入内核组件日志(如 HttpClient、GeoIpManager、CEventLog 后端)的排查与审计场景。
限制与注意事项
- level 与 formatter 设置只对 Bitrix\Main\Diag\Logger 子类生效,不作用于 Monolog。
- JsonLinesFormatter 只写 $context,消息文本会被丢弃,调用方需把消息放进 context。
- 闭包形式的配置不能放在会被内核重写的主设置文件中,应使用 /local/.settings_extra.php。
- EventLogger 写入 b_event_log,仅适合低量日志。
- 以 LoggerFactory 创建的内核 id 在显式启用前保持静默。
检查清单
- 服务接收 LoggerInterface(默认 NullLogger),业务代码中不出现 new FileLogger()。
- 日志器 id 以模块 id 为前缀;使用 LoggerFactory 时通过 LoggerRegistry 启用。
- 日志文件放在 DOCUMENT_ROOT 之外,并设置轮转大小。
- 消息与 context 中不出现密码、令牌或个人数据。
- 使用 JsonLinesFormatter 的调用方把消息放入 context。