Symfony2 中国語マニュアル /使用Monolog做日志

使用Monolog做日志

Symfony自带了一个外部库 - 叫做Monolog- 它允许你创建“可以存放在各种不同地方”的日志。

记录一条信息

要记录一条信息,从控制器中的容器取出logger服务:

public function indexAction(){ $logger = $this->get('logger'); $logger->info('I just got the logger'); $logger->error('An error occurred'); $logger->critical('I left the oven on!', array( // include extra "context" info in your logs / 在日志中附带额外的“上下文”信息 'cause' => 'in_hurry', )); // ...}

logger 服务针对不同的日志等级/优先级拥有不同的方法。你可以基于信息的 等级 来配置logger去做不同的事(如 有错误发生时发送邮件)。

参考LoggerInterface以了解logger的全部方法列表。

日志被存在哪里

对于把日志存放于何处的配置信息,位于特定的environment配置文件:config_dev.ymlconfig_prod.yml之中。

当你处于dev环境时,日志文件入口被默认写进了var/logs/dev.log文件。在prod环境下,日志被写入var/logs/prod.log,但却在请求过程中遇到错误或是遇到高优先级日志时才会发生(如error(),critical(),alert()emergency())。

要控制存放位置,你要配置不同的handlers(控制器)来控制日志入口点(entries),必要时修改它们,最终存储它们。

Handlers: 把日志写入不同的位置

logger自带了一组handlers,每一种都用于把日志入口写入到不同的位置(如,文件,数据库,Slack等)。

能配置日志的 "channels"(频道),这就像分类。每个频道可以有其自己的handlers,这意味着你可以把不同的信息记录到不同的地方。参考如何把日志信息写入不同的文件中

Symfony在config_dev.ymlconfig_prod.yml文件中预置了一些handlers。要了解真实用例不妨查看它们。

下例使用了两个handlers:stream(用于写入文件) 和syslog,后者使用syslog函数来完成日志:

YAML:# app/config/config.ymlmonolog: handlers: # this "file_log" key could be anything # 这个 "file_log" 键可以是任何(合法)字符 file_log: type: stream # log to var/logs/(environment).log # 写入到 var/logs/(environment).log path: "%kernel.logs_dir%/%kernel.environment%.log" # log *all* messages (debug is lowest level) # 把 *全部* 信息写入(debug是最低级别) level: debug syslog_handler: type: syslog # log error-level messages and higher # 记录 error-level(ERROR级别)或更高级别(的信息) level: error
XML:    
PHP:// app/config/config.php$container->loadFromExtension('monolog', array( 'handlers' => array( 'file_log' => array( 'type' => 'stream', 'path' => '%kernel.logs_dir%/%kernel.environment%.log', 'level' => 'debug', ), 'syslog_handler' => array( 'type' => 'syslog', 'level' => 'error', ), ),));

本例定义了一handler,它们会按照各自被定义的顺序被调用。

可修改日志入口的handlers

并非将日志写入某处的文件,一些handlers可用于“在将日志发送到其他handlers之前”过滤和修改它们。一个内置的名为fingers_crossed的强大handleris默认用于prod环境下。它在请求过程中存储全部日志信息,却只是将它们传入第二个handler,如果某条信息达到action_level级别的话。看以下例程:

YAML:# app/config/config.ymlmonolog: handlers: filter_for_errors: type: fingers_crossed # if *one* log is error or higher, pass *all* to file_log # 如果 *一条* 日志是error或更高(的级别),把它们 *全部* 传入file_log action_level: error handler: file_log # now passed *all* logs, but only if one log is error or higher # 现在传入了 *全部* 日志,但只是那些error或更高级别的 file_log: type: stream path: "%kernel.logs_dir%/%kernel.environment%.log" # still passed *all* logs, and still only logs error or higher # 仍然传入了 *全部* 日志,并且仍然都是error或更高级别的 syslog_handler: type: syslog level: error
XML:     
PHP:// app/config/config.php$container->loadFromExtension('monolog', array( 'handlers' => array( 'filter_for_errors' => array( 'type' => 'fingers_crossed', 'action_level' => 'error', 'handler' => 'file_log', ), 'file_log' => array( 'type' => 'stream', 'path' => '%kernel.logs_dir%/%kernel.environment%.log', 'level' => 'debug', ), 'syslog_handler' => array( 'type' => 'syslog', 'level' => 'error', ), ),));

现在,如果某一日志入口(log entry,译注:即“位于某处的日志文件”)遇到了error或更高级别的(信息),则该请求的所有日志入口将通过file_loghandler被存成一个文件。这意味着你的日志文件将包含问题请求的全部相关细节 - 这令调试变得更容易!

名为 "file_log" 的handler将不包括在控制器堆栈中,因为它是作为fingers_crossedhandler的嵌套控制器来使用。

如果你希望通过另一个配置文件来覆写monolog配置信息,你需要重新定义整个handlersstack(控制器堆栈)。这两个文件中的配置信息不能被合并,因为(handler的)顺序很关键,一旦合并就无法控制顺序。

所有的内置handler

Monolog内置了许多用于发送日志邮件的handlers,把它们发送到Loggly,或者在Slack中通知你。这些功能在MonologBundle中都有文档。完整的列表请参考Monolog Configuration

如何翻转你的日志文件

时间一长,不管是开发环境还是生产环境,日志文件会变得极为巨大。解决方案中的一个最佳实践是使用诸如logrotate这种Linux command来在日志文件巨型化之前反转之。

另一个选项是使用rotating_filehandler来令Monolog去反转日志文件。这个控制器每天会创建新的日志文件,并自动删除旧的。要使用它,把控制器中的type选项设为rotating_file即可:

PHP:// app/config/config_dev.php$container->loadFromExtension('monolog', array( 'handlers' => array( 'main' => array( 'type' => 'rotating_file', 'path' => "%kernel.logs_dir%/%kernel.environment%.log", 'level' => 'debug', // max number of log files to keep // defaults to zero, which means infinite files 'max_files' => 10, ), ),));
XAML:    
YAML:# app/config/config_dev.ymlmonolog: handlers: main: type: rotating_file path: '%kernel.logs_dir%/%kernel.environment%.log' level: debug # max number of log files to keep # defaults to zero, which means infinite files # 要保留的日志文件的最大数量,默认是零,即,无限个文件 max_files: 10