Use Monolog for logging
Symfony comes with an external library - called Monolog - that allows you to create logs that can be stored in a variety of different places.
Record a message ¶
To record a message, remove the logger
service from the container in the controller:
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', )); // ...}
The logger service has different methods for different log levels/priorities. You can configure the logger to do different things based on the level of the message (such as sending an email when an error occurs).
Refer to LoggerInterface for a complete list of logger methods.
Where the log is stored ¶
The configuration information for storing the log where is located in a specific environment Configuration files: config_dev.yml
and config_prod.yml
.
When you are in the dev
environment, the log file entry is written into the var/logs/dev.log
file by default. In the prod
environment, the log is written to var/logs/prod.log
, but only encounters an error or high Occurs only when priority logs are logged (such as error()
, critical()
, alert()
or emergency()
).
To control the storage location, you need to configure different handlers (controllers) to control the log entry points (entries), modify them if necessary, and finally store them.
Handlers: Write logs to different locations ¶
logger comes with a set of handlers, each of which is used to write logs Entries are written to different locations (e.g., files, databases, Slack, etc.).
You also can configure the "channels" of the log, which are like categories. Each channel can have its own handlers, which means you can log different information to different places. Refer to How to write log information to different files.
Symfony presets some handlers in the config_dev.yml
and config_prod.yml
files. Check them out to see real-world use cases.
The following example uses two handlers: stream
(for writing files) and syslog
, the latter uses syslog
Function to complete the log:
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:<!-- app/config/config.xml --><?xml version="1.0" encoding="UTF-8" ?><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="file_log" type="stream" path="%kernel.logs_dir%/%kernel.environment%.log" level="debug" /> <monolog:handler name="syslog_handler" type="syslog" level="error" /> </monolog:config></container>
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', ), ),));
This example defines a group of handlers, which will be called in the order in which they are defined.
Handlers that can modify the log entry ¶
Instead of writing the log to a file somewhere, Some handlers can be used to "in Filter and modify logs before sending them to other handlers. A built-in powerful handler named fingers_crossed
is used by default in the prod
environment. It stores all log information during the request process, but only passes them to the second handler if a piece of information reaches the action_level
level. Look at the following routine:
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:<!-- app/config/config.xml --><?xml version="1.0" encoding="UTF-8" ?><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="filter_for_errors" type="fingers_crossed" action-level="error" handler="file_log" /> <monolog:handler name="file_log" type="stream" path="%kernel.logs_dir%/%kernel.environment%.log" level="debug" /> <monolog:handler name="syslog_handler" type="syslog" level="error" /> </monolog:config></container>
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', ), ),));
Now, if a log entry (log entry, translation annotation: "a log file located somewhere") encounters an error
or higher level ( information), then all log entries of the request will be saved into a file through the file_log
handler. This means your log files will contain all relevant details of the problematic request - which makes debugging much easier!
The handler named "file_log" will not be included in the controller stack because it is used as a nested controller of the fingers_crossed
handler .
If you want to overwrite the monolog
configuration information through another configuration file, you need to redefine the entire handlers
stack (controller stack). The configuration information in these two files cannot be merged because the order (of handlers) is critical and the order cannot be controlled once merged.
All built-in handlers ¶
Monolog has built-in Many handlers for sending log emails, sending them to Loggly, or notifying you in Slack . These functions are documented in the MonologBundle. Please refer to Monolog Configuration for a complete list.
How to flip your log files ¶
Over time, whether it is a development environment or a production environment, the log files will become extremely huge . A best practice in the solution is to use a Linux command such as logrotate to reverse the log file before it becomes huge.
Another option is to use the rotating_file
handler to tell Monolog to rotate the log file. This controller creates new log files every day and automatically deletes old ones. To use it, set the type
option in the controller to 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:<!-- app/config/config_dev.xml --><?xml version="1.0" encoding="UTF-8" ?><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> <!-- "max_files": max number of log files to keep defaults to zero, which means infinite files --> <monolog:handler name="main" type="rotating_file" path="%kernel.logs_dir%/%kernel.environment%.log" level="debug" max_files="10" /> </monolog:config></container>
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