如何把日志信息写入不同的文件中

3.4 版本
维护中的版本

Symfony框架把日志信息组织到频道(channel)中。默认时,有几个现成频道,包括 doctrine, event, security, request 以及更多。channel被输出到日志信息中,同时也可以把不同频道下的信息直接应用到不同的位置/文件中去。

默认时,Symfony把每一条信息记录到一个单一文件中(不管其所在频道是什么)。

每一个channel都对应着容器中的(使用 debug:container 命令可以查看完整列表)一个logger service (monolog.logger.XXX),并且这些服务会被注入到其他服务中。

把Channel切换到不同的handler 

现在,假设你希望在 security 频道下写入一个不同的文件。要实现它,只需创建一个全新handler,再将其配置成仅记录 security channel下的信息。你可以在所有环境下向 config.yml 添加此配置,或者只对 config_prod.yml 添加以便只在 prod 环境下生效:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# app/config/config.yml
monolog:
    handlers:
        security:
            # log all messages (since debug is the lowest level)
            # 记录所有信息(因为调试是最低的级别)
            level:    debug
            type:     stream
            path:     "%kernel.logs_dir%/security.log"
            channels: [security]
 
        # an example of *not* logging security channel messages for this handler
        # 关于此handler的一个 *不*记录security channel下的信息 的例子
        main:
            # ...
            # channels: ['!security']
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!-- app/config/config.xml -->
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:monolog="http://symfony.com/schema/dic/monolog"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd
        http://symfony.com/schema/dic/monolog
        http://symfony.com/schema/dic/monolog/monolog-1.0.xsd"
>
    <monolog:config>
        <monolog:handler name="security" type="stream" path="%kernel.logs_dir%/security.log">
            <monolog:channels>
                <monolog:channel>security</monolog:channel>
            </monolog:channels>
        </monolog:handler>
 
        <monolog:handler name="main" type="stream" path="%kernel.logs_dir%/main.log">
            <!-- ... -->
            <monolog:channels>
                <monolog:channel>!security</monolog:channel>
            </monolog:channels>
        </monolog:handler>
    </monolog:config>
</container>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// app/config/config.php
$container->loadFromExtension('monolog', array(
    'handlers' => array(
        'security' => array(
            'type'     => 'stream',
            'path'     => '%kernel.logs_dir%/security.log',
            'channels' => array(
                'security',
            ),
        ),
        'main'     => array(
            // ...
            'channels' => array(
                '!security',
            ),
        ),
    ),
));

channels 配置选项仅服务于顶级handler。那些组内嵌套的、buffer缓冲、filter过滤器、fingers crossed或诸如此类的handler,将忽略此配置,并且会处理每一条传给它们的信息。

YAML协议 

你可以通过多种形式来指定配置信息:

1
2
3
4
5
6
7
8
9
10
channels: ~    # Include all the channels
               # 包括全部频道
channels: foo  # Include only channel 'foo'
               # 只包括 'foo' 频道
channels: '!foo' # Include all channels, except 'foo'
                 # 包括除了 'foo' 之外的全部频道
channels: [foo, bar]   # Include only channels 'foo' and 'bar'
                       # 只包括 'foo' 和 'bar' 频道
channels: ['!foo', '!bar'] # Include all channels, except 'foo' and 'bar'
                           # 包括除了'foo' 和 'bar'之外的全部频道

创建你自己的频道 

你可以每次修改一个monolog的日志频道,将其指向一个服务。这是通过下面的 configuration 来完成的,或者,通过给你的服务打上 monolog.logger 标签,然后指定“此服务应当对哪个频道做日志”。有了这个标签,被注入到那个服务的logger就被预先配置来使用你指定的频道了。

创建附加频道却不使用标签服务 

你也可以配置附加频道,毋须对你的服务打标签:

1
2
3
# app/config/config.yml
monolog:
    channels: ['foo', 'bar']
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- app/config/config.xml -->
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:monolog="http://symfony.com/schema/dic/monolog"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd
        http://symfony.com/schema/dic/monolog
        http://symfony.com/schema/dic/monolog/monolog-1.0.xsd"
>
    <monolog:config>
        <monolog:channel>foo</monolog:channel>
        <monolog:channel>bar</monolog:channel>
    </monolog:config>
</container>
1
2
3
4
5
6
7
// app/config/config.php
$container->loadFromExtension('monolog', array(
    'channels' => array(
        'foo',
        'bar',
    ),
));

有了这个,现在你就可以通过自动注册的 monolog.logger.foo logger service,来向 foo 频道发送日志信息了。

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)