This article mainly introduces the logs in the PHP Yii Framework. log analysis is the basis for daily website maintenance. Yii provides powerful log functions. For more information, see
Yii page-level log enabled
In Main. php, add,
The following shows the page log array ('class' => 'weblogroute ', 'levels' => 'track', // The level is 'category' => 'system. db. * '// only displays information about the database, including database connection and database execution statements ),
Complete:
'Log' => array ('class' => 'clogrouter', 'Routes '=> array ('class' => 'cfilelogroute ', 'levels' => 'Error, warning',), // The page log array ('class' => 'cweblogroute ', 'levels' => 'track ', // trace 'categories '=> 'system. db. * '// only displays information about the database, including database connection and database execution statements ), // uncomment the following to show log messages on web pages/* array ('class' => 'cweblogroute ',),*/),),
Expand the log component of Yii2
<? Php/*** author: forecho
* CreateTime: 2015/12/22 18:13 * description: */namespace common \ components; use Yii; use yii \ helpers \ FileHelper; class FileTarget extends \ yii \ log \ FileTarget {/*** @ var bool whether to enable the log prefix (@ app/runtime/logs/error/20151223_app.log) */public $ enableDatePrefix = false;/*** @ var bool enable the log level directory */public $ enableCategoryDir = false; private $ _ logFilePath = ''; public function init () {if ($ this-> logFile = Null) {$ this-> logFile = Yii: $ app-> getRuntimePath (). '/logs/app. log';} else {$ this-> logFile = Yii: getAlias ($ this-> logFile );} $ this-> _ logFilePath = dirname ($ this-> logFile); // enable the log prefix if ($ this-> enableDatePrefix) {$ filename = basename ($ this-> logFile); $ this-> logFile = $ this-> _ logFilePath. '/'. date ('ymmd '). '_'. $ filename;} if (! Is_dir ($ this-> _ logFilePath) {FileHelper: createDirectory ($ this-> _ logFilePath, $ this-> dirMode, true );} if ($ this-> maxLogFiles <1) {$ this-> maxLogFiles = 1;} if ($ this-> maxFileSize <1) {$ this-> maxFileSize = 1 ;}}}
Use the following in the configuration file:
'Components' => ['log' => ['tracelevel' => YII_DEBUG? 3: 0, 'targets' => [/*** error level Log: This method is called to record relevant information when a critical problem needs to be resolved immediately occurs. * Usage: Yii: error () */['class' => 'common \ components \ FileTarget ', // log level 'levels' => ['error'], // additional data of collected records 'logvars' => ['_ get',' _ post ', '_ FILES', '_ COOKIE', '_ SESSION', '_ server'], // specify the log storage file name 'logfile' => '@ app/runtime/logs/error/app. log', // whether to enable log (@ app/runtime/logs/error/20151223_app.log) 'enabledateprefix' => true, 'maxfilesize' => 1024*1, 'maxlogfiles' => 100,],/*** warning level Log: in some periods This method is used when something else occurs. * Usage: Yii: warning () */['class' => 'common \ components \ FileTarget ', // log level 'levels' => ['warning'], // additional data of collected records 'logvars' => ['_ get',' _ post ', '_ FILES', '_ COOKIE', '_ SESSION', '_ server'], // specify the log storage file name 'logfile' => '@ app/runtime/logs/warning/app. log', // whether to enable the log (@ app/runtime/logs/warning/20151223_app.log) 'enabledateprefix' => true, 'maxfilesize' => 1024*1, 'maxlogfiles' => 100,],/*** inf O-level Log: used to record some useful information at some locations. * Usage: Yii: info () */['class' => 'common \ components \ FileTarget ', // log level 'levels' => ['info'], // additional data of collected records 'logvars' => ['_ get',' _ post ', '_ FILES', '_ COOKIE', '_ SESSION', '_ server'], // specify the log storage file name 'logfile' => '@ app/runtime/logs/info/app. log', // whether to enable log (@ app/runtime/logs/info/20151223_app.log) 'enablesdateprefix' => true, 'maxfilesize' => 1024*1, 'maxlogfiles' => 100,],/*** trace-level Log: records information about Messages related to code running. It is mainly used in the development environment. * Usage: Yii: trace () */['class' => 'common \ components \ FileTarget ', // log level 'levels' => ['track'], // additional data of collected records 'logvars' => ['_ get',' _ post ', '_ FILES', '_ COOKIE', '_ SESSION', '_ server'], // specify the log storage file name 'logfile' => '@ app/runtime/logs/trace/app. log', // whether to enable log (@ app/runtime/logs/trace/20151223_app.log) 'enablesdateprefix' => true, 'maxfilesize' => 1024*1, 'maxlogfiles' => 100,],
Logic of yii logs
Yii uses a hierarchical log processing mechanism, that is, log collection and log final processing (such as displaying, saving to files, and saving to data) are separated.
The collection of log information is completed by the CLogger (logger), and the distribution and processing of log information is under the scheduling (called the log routing manager) of the CLogRouter, distribution to processing objects (for example, the CFileLogRoute and the class inherited from CLogRoute under the logging Directory, called the log processor). after reading the source code repeatedly, I was impressed by Yii's design philosophy, such layered processing makes it easy to flexibly expand.
The log information has different levels, such as ordinary info, profile, trace, warning, and error levels. you can set excessive conditions in log routing, for example, setting the levels attribute of CFileRoute, you can only process log information at the specified level.
For example, call in a program:
Yii::log($message,CLogger::LEVEL_ERROR,$category);
The corresponding process may be as follows:
- Generate a CLogger instance
- If both YII_DEBUG and YII_TRACE_LEVEL have been defined as valid values and the log level is not the profile, call tracing information is generated and appended to the log information.
- Call CLogger: log ($ msg, $ level, $ category) to collect logs. In fact, the logs are not written into the file and are saved in the memory.
Q: When is a log written to a file?
After repeated tracking, I found that in the init method of the CLogRouter class, the processor CLogRouter: processLogs () is bound to the OnEndRequest event of the Application object (). At the same time, bind the event processor CLogRouter: collectLogs method to the onFlush event of Yii ::$ _ logger. this method is used when there are too many log messages in Yii: log, refresh logs and write them to files in time. The code is as follows:
/** * Initializes this application component. * This method is required by the IApplicationComponent interface. */ public function init(){ parent::init(); foreach($this->_routes as $name=>$route) { $route=Yii::createComponent($route); $route->init(); $this->_routes[$name]=$route; } Yii::getLogger()->attachEventHandler('onFlush',array($this,'collectLogs')); Yii::app()->attachEventHandler('onEndRequest',array($this,'processLogs'));}
The CApplication: run () method defines:
if($this->hasEventHandler('onEndRequest')) { $this->onEndRequest(new CEvent($this)); }
Here we can understand that CLogger (Yii: $ _ logger) only collects logs (recorded in the content structure), and at the end of the program, the $ app object calls the CLogRouter's processLogs to process logs. Yii supports multiple log routes. for example, a log can be written to a file, displayed on a page, or even sent by email, or recorded in a database at the same time, this is implemented by the log: routes configuration in the configuration file. configure multiple elements for log: routes to implement multiple route distribution. The log information is filtered and recorded by the final log processor.
The tasks to be completed by the log processor mainly include the following: getting all the logs from the CLogger and filtering (mainly levels and categories two definitions of log: routes: levels/categories)
For more information about filtering, see the logic in CFileLogRoute: collectLogs:
$ Logs = $ logger-> getLogs ($ this-> levels, $ this-> categories); // perform filtering to obtain only the expected information
Log filtering is complete. Next, you need to final process the log (such as writing logs to files and recording logs to databases)
CFileLogRoute::processLogs($logs);
However, there is a small bug in this function, which only determines whether the log directory is writable, but not whether the log file itself is writable. CFileLogRoute implements a log rotation function (LogRoate) similar to Linux, and specifies the log file size. it is considerate and complete! I also want to learn from them and absorb their thoughts!
Configuration in protected/config/main. php:
'preload'=>array('log'),components => array( 'log'=>array( 'class'=>'CLogRouter', 'routes'=>array( array( 'class'=>'CFileLogRoute', 'levels'=>'error, warning,trace', ), ) ) )
Define log components to be preloaded (instantiated ). Use CLogRouter as the log routing manager, and set its log routing processor (routes attribute) and its configuration attributes. Preload and log attributes must be applied to the CWebApplication object (see configure call in CApplication ::__ construct. configure is inherited from the CModule ). When preloadComponents () is executed in the CWebApplication constructor, a log object (CLogRouter instance) is created ).
When creating and initializing a component, you actually call CModule: getComponent. in this call, you can use YiiBase: createComponent to create a component object and then call the init initialization of the component.
After reading the CLogRouter: init () process, there are two key points here: first, creating a log route processor (that is, determining the final log processing method: Writing files, sending emails, etc ), second, bind the onEndRequest event to the application object to process the CLogRouter: processLogs (). In CApplication: run (), there is indeed code used to run the onEndRequest event processing handle:
if($this->hasEventHandler('onEndRequest')) { $this->onEndRequest(new CEvent($this)); }
That is to say, the final processing of logs (such as writing files, system logs, and sending emails) occurs after the application program is completed. Yii uses the event mechanism to skillfully associate events with handling handles.
That is to say, when the application is running successfully, the system will execute CLogRouter: processLogs to process logs ,. CLogRouter is called the log routing manager. Each log routing processor obtains the corresponding logs from the CLooger object (using the filter mechanism) for final processing.
Specifically, the log system of Yii is divided into the following layers:
The log sender, that is, the program calls Yii: log ($ msg, $ level, $ category) to send the log to the CLogger object.
The CLogger object stores the log records in the memory. after the program runs, the processLogs method of the log component (log routing manager CLogRoute) is activated and executed, and the log router is called one by one, as the final processing of logs.
The detailed process is as follows:
- PreloadComponents is called in CApplication :__ construct (). as a result, the log component (CLogRoute) is instantiated and initialized by calling the init method.
- In the init method of the log component (CLogRoute), it initializes the log route and binds the processing process processLogs to the onEndRequest event of the CApplication object. Bind the process collectLogs to the onFlush event of the CLooger component.
- The other part of the application sends log information to the CLogger component by calling Yii: log (). The CLogger component saves the log information to the memory.
- After CApplication is executed (in the run method), the onEndRequest event is activated, the bound event processor processLogs is executed, and the log is written into the file. Yii's log routing mechanism brings unlimited flexibility to the expansion of the log system. And its multi-channel routing mechanism can process the same log information in multiple ways.
Here is an example: when an error-level database error occurs, send an email to the maintenance personnel in time and record the logs to the file. The planning concept is that sending emails and text messages are two different functions. Yii already includes the log email sending component (logging/CEmailLogRoute. php), but this component uses the mail function that comes with php. to use the mail function, you need to configure php. the smtp host in ini and uses a non-authenticated sending method. this method is completely unavailable currently. Instead, we need to use the smtp sending method with the verification function. Define the log processor class myEmailLogRoute in the protected/components/directory and inherit it from CEmailLogRoute. The main purpose is to rewrite the CEmailLogRoute: sendEmail () method, where, complete the SMTP processing details (this article focuses on how to process logs rather than sending emails ).
Next, we can define log route processing, edit protected/config/main. php, and add a new route configuration to the routes component of the log component:
'Log' => array ('class' => 'clogrouter', 'Routes '=> array ('class' => 'cfilelogroute ', 'levels' => 'Error, warning, Track',), array ('class' => 'mymaillogroute ', 'levels' => 'error ', # error levels for all exceptions are error, 'category' => 'exception. cdbexception', # A CDbException occurs when an error occurs in the database. 'Host' => 'Mail .163.com ', 'port' => 25, 'user' => 'Jeff _ yu', 'password' => 'You password ', 'timeout' => 30, 'elastic' => 'Jeff _ yu@gmail.com ', # The log recipient. 'Sentfrom' => 'Jeff _ yu@gmail.com ',),
After the above processing, we can achieve our goal. of course, you can further expand it according to your own needs.