This article mainly introduces the PHP yii framework of the log, the analysis of the log is the basis of daily site maintenance, Yii provides a more powerful log function, the need for friends can refer to the next
Yii page-level log Open
In main.php, the log segment is added,
The following shows the page log array (' class ' = ' Cweblogroute ', ' levels ' = ' trace ',//level for trace ' categories ' = ' system.db.* '// Show only information about the database, including database connections, database execution statements),
Complete as follows:
' Log ' =>array ( ' class ' = ' Clogrouter ', ' routes ' =>array (' class ' = ') ' Cfilelogroute ', ' levels ' = ' Error, warning ', ' ), //page log below displays the array ( ' class ' = ' = ') Cweblogroute ', ' levels ' + ' trace ', //level for trace ' categories ' = ' system.db.* '//Only displays information about the database, Including database connection, database execution statement ), //Uncomment the following to show log messages on Web pages /* Array ( ' Class ' = ' Cweblogroute ', ), */ ) ,
Extending the Yii2 Log component
<?php/** * Author:forecho <caizhenghai@gmail.com> * CREATETIME:2015/12/22 18:13 * Description: */namespace Common\components;use yii;use yii\helpers\filehelper;class Filetarget extends \yii\log\filetarget{/** * @var bool Using the log prefix (@app/runtime/logs/error/20151223_app.log) */Public $enableDatePrefix = false; /** * @var bool Enable 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 (' Ymd '). '_' . $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; } }}
This is used in the configuration file:
' Components ' and [' log ' = ' = ' traceLevel ' + yii_debug? 3:0, ' targets ' = ' = '/** * ERROR level log: Call this method to log relevant information when a fatal problem that needs to be resolved immediately occurs. * How to use: Yii::error () */[' class ' = ' common\components\filetarget ',//log level ' levels ' =& Gt [' ERROR '],//collection of additional data recorded ' logvars ' = [' _get ', ' _post ', ' _files ', ' _cookie ', ' _session ', ' _server '], Specifies the file name saved by the log ' logFile ' = ' @app/runtime/logs/error/app.log ',//whether the log is turned on (@app/runtime/logs/error/201512 23_app.log) ' enabledateprefix ' = True, ' maxfilesize ' = 1, ' maxlogfiles ' and ' = 100, ],/** * Warning Level log: Use this method when something outside of the expectation occurs. * How to use: yii::warning () */[' class ' = ' common\components\filetarget ',//log level ' levels ' = = [' Warning '],//The additional data collected for the record ' logvars ' = [' _get ', ' _post ', ' _files ', ' _cookie ', ' _session ', ' _server ' ],//Specify the file name of the log save ' logFile ' => ' @app/runtime/logs/warning/app.log ',//whether to open the log (@app/runtime/logs/warning/20151223_app.log) ' Enabledateprefi X ' = True, ' maxfilesize ' = * 1, ' maxlogfiles ' = +,],/** * Info level log: In some The location records some of the more useful information when used. * How to use: Yii::info () */[' class ' = ' common\components\filetarget ',//log level ' levels ' =&G T [' Info '],//collection of additional data recorded ' logvars ' = [' _get ', ' _post ', ' _files ', ' _cookie ', ' _session ', ' _server '], Specifies the file name saved by the log ' logFile ' = ' @app/runtime/logs/info/app.log ',//whether the log is turned on (@app/runtime/logs/info/20151223_ App.log) ' enabledateprefix ' = True, ' maxfilesize ' = 1024x768 * 1, ' maxlogfiles ' and ' = 100,] ,/** * Trace level log: Records related messages about the run of a piece of code. Primarily for the development environment. * How to use: Yii::trace () */[' class ' = ' common\components\filetarget ',//log level ' levels ' =& Gt [' Trace '],//collection of recorded extra data ' Logvars ' = = [' _get ', ' _post ', ' _files ', ' _cookie ', ' _session ', ' _server '],//Specify the log save filename ' logFile ' = ' @app/run Time/logs/trace/app.log ',//whether to turn on log (@app/runtime/logs/trace/20151223_app.log) ' enabledateprefix ' = True , ' maxfilesize ' = 1, ' maxlogfiles ' = 100,],],,
The logic of Yii logs
Yii uses a hierarchy of log processing mechanisms, that is, the collection of logs and the final processing of logs (such as display, save to file, save to the number of data) is separate.
The collection of log information is done by the Clogger (logger), and the distribution of the log information is processed in the Clogrouter schedule (called the Log Routing manager). distributed to the processing objects (such as Cfilelogroute and logging inherit from the Clogroute class, called the log processor), after repeated reading of its source code, I am more than the design of Yii to be impressed, so layered processing, making it easy to expand flexibly.
The log information has a level, such as ordinary info, profile, trace, warning, error level, you can set the filter condition in the log route, such as setting Cfileroute's Levels property, can only process the specified level of log information.
As called in the program:
Yii::log ($message, Clogger::level_error, $category);
The corresponding process may be as follows:
Generating Clogger instances
If Yii_debug, Yii_trace_level is already defined as a valid value, and the log level is not profile, the call backtracking information is generated and appended to the log information.
Call Clogger:: Log ($msg, $level, $category) to collect the log, in fact, the log is not written to the file, just staged in memory.
Question: When was the log written to the file?
After repeated tracing, I found that the Onendrequest event binding processor for the Application object in the Init method of the Clogrouter class Clogrouter::p rocesslogs (). The Yii::$_logger Onflush event is also bound to the event handler Clogrouter::collectlogs method, which is used to write the log flush to the file in a timely manner when there are too many logs messages in Yii::log (). The code is as follows:
/** * Initializes this application component. * This method was 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 '));}
In the Capplication::run () method, you define the following:
if ($this->haseventhandler (' onendrequest ')) {$this->onendrequest (new CEvent ($this));}
Here we can understand that Clogger (Yii::$_logger) simply collects the log (recorded in the content structure) and then, at the end of the program, calls Clogrouter's processlogs for processing by the $app object. Yii support log Multi-path, such as: the same log can be written to the file, but also can be displayed on the page, even in e-mail, and even recorded in the database, which is implemented by the configuration file log:routes configuration, for log:routes configuration of multiple elements, Implement multiple routing distributions. Log information is filtered and records are processed by the final log processor.
The tasks to be accomplished by the log processor include the following: Get all logs from Clogger and filter (mostly levels, categories two definitions log:routes:levels/categories)
First filter the logic in the Reference Cfilelogroute::collectlogs ():
$logs = $logger->getlogs ($this->levels, $this->categories); Execution filtering, only to the desired information
Log filtering is completed the final processing of the log (e.g. writing to a file, logging to a database, etc.)
Cfilelogroute::p rocesslogs ($logs);
But in this function, there is a small bug, only to determine whether the log directory can be written, not to determine whether the log file itself can be written. Cfilelogroute implements a Linux-like log rotation function (logroate), and specifies the size of the log file, thoughtful, very perfect! I also want to learn from it and absorb its 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 ', ), ) ) )
The definition of the log component requires pre-loading (instantiation). The configuration uses Clogrouter as the log Routing manager and sets its log route processor (routes property) and its configuration properties. The definition of the preload, log property is applied to the Cwebapplication object (see Configure call in Capplication::__construct, configure inherit from Cmodule). Instead of executing preloadcomponents () in the Cwebapplication constructor, a log object (that is, an instance of Clogrouter) is created.
When a component is created and initialized, it is actually called cmodule::getcomponent, which uses yiibase::createcomponent to create the Component object and then initializes the component's init.
Then read the Clogrouter::init () process, where there are two key points, one is to create a log route processor (that is, the final processing of the decision log: Write files, send mail, etc.), and the other is to bind the Application object onendrequest event processing Clogrouter ::p rocesslogs (). and in Capplication::run () there is indeed a correlation code to run the Onendrequest event handle:
if ($this->haseventhandler (' onendrequest ')) { $this->onendrequest (New CEvent ($this));}
That is, the final processing of the log (such as writing to a file, system log, sending mail) Occurs after the application has finished running. Yii uses the event mechanism to skillfully implement the association of events with handle handles.
That is, when the application finishes running, the Clogrouter is executed::p rocesslogs, the log is processed. Clogrouter is called the log Routing manager. Each log routing processor obtains a corresponding log from the Clooger object (using the filtering mechanism) for final processing.
In particular, Yii's log system is divided into the following levels:
Log sender, called Yii::log ($msg, $level, $category) in the program, sends the log to the Clogger object
The Clogger object is responsible for staging the log records in memory after the program runs, the log component (log Routing manager Clogroute) Processlogs method is activated, which calls the log router one by one for the final processing of the log.
A more detailed overview of the process is as follows:
Capplication::__construct () calls Preloadcomponents, which causes the log component (Clogroute) to be instantiated and initialized with the Init method called.
The Init method of the Log component (Clogroute) is to initialize the log route and give the CApplication object Onendrequest event binding process Processlogs. The Onflush event binding process Collectlogs to the Clooger component.
Other parts of the application send log information to the Clogger component by calling Yii::log (), and the Clogger component temporarily saves the log information in memory.
CApplication execution completes (in the Run method), the Onendrequest event is activated, the bound event handler Processlogs is executed, and the log is written to the file. The logging routing mechanism of Yii brings infinite flexibility to the log system extension. and its multi-path by the processing mechanism, the same log information can be processed in many ways.
Here is a case where error-level database errors occur, sending e-mails to the relevant maintainers in a timely manner, and logging them to the file at the same time. Planning ideas, sending mail and SMS messages are two different features, Yii has been brought with the log mail sending component (logging/ cemaillogroute.php), but this component uses PHP's own mail functions, using the Mail function to configure the SMTP host in the php.ini, and the use of non-authenticated send method, which is completely unusable in the current situation. Instead, we need to use the SMTP Send with authentication feature. In the protected/components/directory to define the log processor class Myemaillogroute, and let it inherit from Cemaillogroute, the main purpose is to override the Cemaillogroute::sendemail () method, Among them, the processing details of SMTP should be perfected (the focus of this article is on how to handle the log, rather than on sending the message).
Next, we can define log route processing, edit protected/config/main.php, add a new routing configuration to the routes component of the log component:
' Log ' =>array (' class ' = ' clogrouter ', ' Routes ' =>array (' class ' = ' Cfilelogroute ', ' levels ' and ' = ') Error, Warning,trace ',), Array (' class ' = ' Myemaillogroute ', ' levels ' = ' error ', #所有异常的错误级别均为error, ' categories ' = ' exception. CDBException ', #数据库产生错误时, will produce cdbexception anomalies. ' Host ' = ' mail.163.com ', ' Port ', ' + ', ' user ' = ' jeff_yu ', ' password ' + ' you password ', ' timeout ' = ' em Ails ' = ' jeff_yu@gmail.com ', #日志接收人. ' Sentfrom ' = ' jeff_yu@gmail.com ',),
After the above processing, can make it achieve our goal, of course, you can according to your own needs to further expand.
The above is the whole content of this article, I hope that everyone's learning has helped, more relevant content please pay attention to topic.alibabacloud.com!