bitrix-logger

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Logging in Bitrix (PSR-3)

Bitrix中的日志系统(PSR-3)

Bitrix follows the PSR-3 standard. In code, inject
\Psr\Log\LoggerInterface
, and in
.settings.php
, configure the specific implementation. Direct calls to
AddMessage2Log
are legacy; in new code, write via DI logger.
Bitrix遵循PSR-3标准。在代码中,注入
\Psr\Log\LoggerInterface
,并在
.settings.php
中配置具体的实现。直接调用
AddMessage2Log
属于旧写法;在新代码中,应通过DI日志器进行日志记录。

Built-in Implementations

内置实现

All are in the
\Bitrix\Main\Diag\
namespace:
ClassPurpose
Logger
Abstract base class;
Logger::create('id', $params)
creates a logger via factory
FileLogger
Into a file, with auto-rotation when
$maxLogSize
is exceeded (default 1 MB)
SysLogger
Into system
syslog
via
openlog
/
syslog
EventLogger
Into
b_event_log
table (Admin Panel → Event Log)
LogFormatter
Default formatter: interpolates
{placeholder}
, renders exceptions and stacks
JsonLinesFormatter
From 25.300.0; one JSON line per entry, convenient for ELK/Loki
Levels are constants of
\Psr\Log\LogLevel::*
(
emergency
,
alert
,
critical
,
error
,
warning
,
notice
,
info
,
debug
).
所有实现均位于
\Bitrix\Main\Diag\
命名空间下:
用途
Logger
抽象基类;
Logger::create('id', $params)
通过工厂方法创建日志器
FileLogger
将日志写入文件,当超过
$maxLogSize
时自动轮转(默认1 MB)
SysLogger
通过
openlog
/
syslog
将日志写入系统
syslog
EventLogger
将日志写入
b_event_log
表(后台管理 → 事件日志)
LogFormatter
默认格式化器:解析
{placeholder}
占位符,渲染异常和调用栈
JsonLinesFormatter
从版本25.300.0开始支持;每条日志为一行JSON,适用于ELK/Loki等系统
日志级别为
\Psr\Log\LogLevel::*
的常量(
emergency
alert
critical
error
warning
notice
info
debug
)。

Service with Logger (DI — Recommended)

结合日志器的服务(DI——推荐方式)

php
<?php declare(strict_types=1);

namespace Vendor\Module\Application\Service;

use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;

final class PostService
{
    public function __construct(
        private readonly LoggerInterface $logger = new NullLogger(),
    ) {}

    public function publish(int $postId): void
    {
        try
        {
            // ...
            $this->logger->info('Post {id} published', ['id' => $postId]);
        }
        catch (\Throwable $e)
        {
            $this->logger->error('Publish failed for post {id}: {exception}', [
                'id' => $postId,
                'exception' => $e,
            ]);
            throw $e;
        }
    }
}
Registration in
/local/modules/vendor.module/.settings.php
:
php
'services' => [
    'value' => [
        \Vendor\Module\Application\Service\PostService::class => [
            'constructor' => static fn (): \Vendor\Module\Application\Service\PostService =>
                new \Vendor\Module\Application\Service\PostService(
                    new \Bitrix\Main\Diag\FileLogger('/var/log/bitrix/post-service.log'),
                ),
        ],
    ],
    'readonly' => true,
],
php
<?php declare(strict_types=1);

namespace Vendor\Module\Application\Service;

use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;

final class PostService
{
    public function __construct(
        private readonly LoggerInterface $logger = new NullLogger(),
    ) {}

    public function publish(int $postId): void
    {
        try
        {
            // ...
            $this->logger->info('Post {id} published', ['id' => $postId]);
        }
        catch (\Throwable $e)
        {
            $this->logger->error('Publish failed for post {id}: {exception}', [
                'id' => $postId,
                'exception' => $e,
            ]);
            throw $e;
        }
    }
}
/local/modules/vendor.module/.settings.php
中注册:
php
'services' => [
    'value' => [
        \Vendor\Module\Application\Service\PostService::class => [
            'constructor' => static fn (): \Vendor\Module\Application\Service\PostService =>
                new \Vendor\Module\Application\Service\PostService(
                    new \Bitrix\Main\Diag\FileLogger('/var/log/bitrix/post-service.log'),
                ),
        ],
    ],
    'readonly' => true,
],

PSR-3 Placeholders

PSR-3占位符

Message is a template with
{key}
, values are taken from
$context
:
php
$logger->warning('User {userId} tried {action} on post {postId}', [
    'userId' => $uid, 'action' => 'delete', 'postId' => $pid,
]);
Special keys understood by
LogFormatter
:
  • {date}
    — current time (interpolated automatically).
  • {host}
    — HTTP_HOST (automatic).
  • {delimiter}
    — entry separator (automatic).
  • {exception}
    \Throwable
    object → formats class, message, stack trace.
  • {trace}
    — manual stack trace:
    Diag\Helper::getBackTrace(6, DEBUG_BACKTRACE_IGNORE_ARGS, 3)
    .
Enable arguments in stack trace:
php
$logger->setFormatter(new \Bitrix\Main\Diag\LogFormatter(showArguments: true, argMaxChars: 120));
日志消息为带有
{key}
的模板,值从
$context
中获取:
php
$logger->warning('User {userId} tried {action} on post {postId}', [
    'userId' => $uid, 'action' => 'delete', 'postId' => $pid,
]);
LogFormatter
支持的特殊键:
  • {date}
    — 当前时间(自动解析)。
  • {host}
    — HTTP_HOST(自动解析)。
  • {delimiter}
    — 日志条目分隔符(自动解析)。
  • {exception}
    \Throwable
    对象 → 格式化类名、消息和调用栈。
  • {trace}
    — 手动调用栈:
    Diag\Helper::getBackTrace(6, DEBUG_BACKTRACE_IGNORE_ARGS, 3)
启用调用栈中的参数显示:
php
$logger->setFormatter(new \Bitrix\Main\Diag\LogFormatter(showArguments: true, argMaxChars: 120));

Configuration via
.settings.php
loggers
section

通过
.settings.php
配置——
loggers

Allows overriding loggers for named kernel points (
main.HttpClient
,
main.Default
,
main.GeoIpManager
) and your own identifiers.
php
return [
    'services' => [
        'value' => [
            'formatter.withArgs' => [
                'className' => \Bitrix\Main\Diag\LogFormatter::class,
                'constructorParams' => [true],
            ],
        ],
        'readonly' => true,
    ],
    'loggers' => [
        'value' => [
            'main.Default' => [
                'constructor' => static fn () => new \Bitrix\Main\Diag\FileLogger(
                    '/var/log/bitrix/app.log', 10 * 1024 * 1024,
                ),
                'level'     => \Psr\Log\LogLevel::INFO,
                'formatter' => 'formatter.withArgs',
            ],

            '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/bitrix/http-' . spl_object_hash($request) . '.log',
                    );
                },
                'level' => \Psr\Log\LogLevel::DEBUG,
            ],

            'vendor.module.myLogger' => [
                'constructor' => static fn () => new \Bitrix\Main\Diag\FileLogger(
                    '/var/log/bitrix/vendor.module.log',
                ),
                'level' => \Psr\Log\LogLevel::DEBUG,
            ],
        ],
        'readonly' => true,
    ],
];
允许覆盖命名内核节点(
main.HttpClient
main.Default
main.GeoIpManager
)和自定义标识的日志器。
php
return [
    'services' => [
        'value' => [
            'formatter.withArgs' => [
                'className' => \Bitrix\Main\Diag\LogFormatter::class,
                'constructorParams' => [true],
            ],
        ],
        'readonly' => true,
    ],
    'loggers' => [
        'value' => [
            'main.Default' => [
                'constructor' => static fn () => new \Bitrix\Main\Diag\FileLogger(
                    '/var/log/bitrix/app.log', 10 * 1024 * 1024,
                ),
                'level'     => \Psr\Log\LogLevel::INFO,
                'formatter' => 'formatter.withArgs',
            ],

            '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/bitrix/http-' . spl_object_hash($request) . '.log',
                    );
                },
                'level' => \Psr\Log\LogLevel::DEBUG,
            ],

            'vendor.module.myLogger' => [
                'constructor' => static fn () => new \Bitrix\Main\Diag\FileLogger(
                    '/var/log/bitrix/vendor.module.log',
                ),
                'level' => \Psr\Log\LogLevel::DEBUG,
            ],
        ],
        'readonly' => true,
    ],
];

Important

注意事项

  • constructor
    closures must be in
    .settings.php
    /
    .settings_extra.php
    — the file is not edited by Admin Panel, closures are not serialized.
  • level
    — threshold level; logger ignores messages below this.
  • formatter
    — key from
    services
    section.
  • Retrieving logger in code:
    php
    $logger = \Bitrix\Main\Diag\Logger::create('vendor.module.myLogger');
    $logger = \Bitrix\Main\Diag\Logger::create('vendor.module.myLogger', [$this, $extraArg]);
  • constructor
    闭包必须放在
    .settings.php
    /
    .settings_extra.php
    中——该文件不会被后台管理面板修改,闭包不会被序列化。
  • level
    — 阈值级别;日志器会忽略低于该级别的消息。
  • formatter
    — 来自
    services
    段的键。
  • 在代码中获取日志器:
    php
    $logger = \Bitrix\Main\Diag\Logger::create('vendor.module.myLogger');
    $logger = \Bitrix\Main\Diag\Logger::create('vendor.module.myLogger', [$this, $extraArg]);

Named Kernel Points

命名内核节点

IDUsed InFactory Parameters
main.Default
AddMessage2Log
, general default
LOG_FILENAME
,
$showArgs
main.HttpClient
Bitrix\Main\Web\HttpClient
(including legacy and PSR-18)
DebugInterface $debug
,
RequestInterface $request
main.GeoIpManager
Bitrix\Main\Service\GeoIp\Manager
main.EventLog.SysLogger
CEventLog
→ syslog path
main.EventLog.FileLogger
CEventLog
→ file path
$path
,
$maxSize
There are no named loggers
main.Mail
or
main.Engine
. Prefer
constructor
closures for
FileLogger
(see examples above) over
className
/
settings
arrays.
Configuring these loggers redirects all kernel calls — convenient for auditing external calls (see example in
bitrix-http-client
).
ID使用场景工厂参数
main.Default
AddMessage2Log
、通用默认日志
LOG_FILENAME
,
$showArgs
main.HttpClient
Bitrix\Main\Web\HttpClient
(包括旧版和PSR-18实现)
DebugInterface $debug
,
RequestInterface $request
main.GeoIpManager
Bitrix\Main\Service\GeoIp\Manager
main.EventLog.SysLogger
CEventLog
→ syslog路径
main.EventLog.FileLogger
CEventLog
→ 文件路径
$path
,
$maxSize
不存在名为
main.Mail
main.Engine
的日志器。相比
className
/
settings
数组,更推荐为
FileLogger
使用
constructor
闭包(见上方示例)。
配置这些日志器会重定向所有内核调用——便于审计外部调用(见
bitrix-http-client
示例)。

LoggerAware + Factory

LoggerAware + 工厂

For classes that should be supplied with a logger "by identifier":
php
final class Indexer implements \Psr\Log\LoggerAwareInterface
{
    use \Psr\Log\LoggerAwareTrait;

    public function run(): void
    {
        $this->ensureLogger()->info('Indexing started');
    }

    private function ensureLogger(): \Psr\Log\LoggerInterface
    {
        if ($this->logger === null)
        {
            $this->setLogger(\Bitrix\Main\Diag\Logger::create('vendor.module.indexer', [$this]));
        }
        return $this->logger;
    }
}
对于需要通过“标识”注入日志器的类:
php
final class Indexer implements \Psr\Log\LoggerAwareInterface
{
    use \Psr\Log\LoggerAwareTrait;

    public function run(): void
    {
        $this->ensureLogger()->info('Indexing started');
    }

    private function ensureLogger(): \Psr\Log\LoggerInterface
    {
        if ($this->logger === null)
        {
            $this->setLogger(\Bitrix\Main\Diag\Logger::create('vendor.module.indexer', [$this]));
        }
        return $this->logger;
    }
}

Monolog via Composer

通过Composer集成Monolog

bash
composer require monolog/monolog
Integration into
.settings.php
:
php
'loggers' => [
    'value' => [
        'vendor.module.external' => [
            'constructor' => static function () {
                $log = new \Monolog\Logger('vendor.module');
                $log->pushHandler(new \Monolog\Handler\StreamHandler('/var/log/bitrix/monolog.log'));
                return $log;
            },
            'level' => \Psr\Log\LogLevel::DEBUG,
        ],
    ],
],
bash
composer require monolog/monolog
.settings.php
中集成:
php
'loggers' => [
    'value' => [
        'vendor.module.external' => [
            'constructor' => static function () {
                $log = new \Monolog\Logger('vendor.module');
                $log->pushHandler(new \Monolog\Handler\StreamHandler('/var/log/bitrix/monolog.log'));
                return $log;
            },
            'level' => \Psr\Log\LogLevel::DEBUG,
        ],
    ],
],

Checklist

检查清单

  • PSR-3 standard followed (placeholders, context, exception key).
  • Loggers are configured via
    .settings.php
    rather than hardcoded in services.
  • Threshold
    level
    is set for each environment.
  • Loggers for external integrations (
    HttpClient
    ) are redirected to separate files for audit.
  • For heavy load,
    JsonLinesFormatter
    is used for external collectors.
  • Logs are stored outside
    DOCUMENT_ROOT
    or protected by
    .htaccess
    .
  • Sensitive data (passwords, tokens) are stripped from context before logging.
Link
exception_handling.log
in
.settings.php
with named loggers for unified error tracking. See skill
bitrix-settings
.
  • 遵循PSR-3标准(占位符、上下文、exception键)。
  • 日志器通过
    .settings.php
    配置,而非硬编码在服务中。
  • 为每个环境设置阈值
    level
  • 将外部集成(
    HttpClient
    )的日志器重定向到单独文件以便审计。
  • 高负载场景下,为外部收集器使用
    JsonLinesFormatter
  • 日志存储在
    DOCUMENT_ROOT
    之外,或通过
    .htaccess
    保护。
  • 日志记录前从上下文中移除敏感数据(密码、令牌)。
.settings.php
中的
exception_handling.log
与命名日志器关联,实现统一错误追踪。详见技能
bitrix-settings