Qiang Xue
13 years ago
3 changed files with 70 additions and 120 deletions
@ -1,156 +1,101 @@ |
|||||||
<?php |
<?php |
||||||
/** |
/** |
||||||
* CDbLogRoute class file. |
* DbTarget class file. |
||||||
* |
* |
||||||
* @author Qiang Xue <qiang.xue@gmail.com> |
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
* @link http://www.yiiframework.com/ |
* @link http://www.yiiframework.com/ |
||||||
* @copyright Copyright © 2008-2011 Yii Software LLC |
* @copyright Copyright © 2008-2012 Yii Software LLC |
||||||
* @license http://www.yiiframework.com/license/ |
* @license http://www.yiiframework.com/license/ |
||||||
*/ |
*/ |
||||||
|
|
||||||
|
namespace yii\logging; |
||||||
|
|
||||||
/** |
/** |
||||||
* CDbLogRoute stores log messages in a database table. |
* DbTarget stores log messages in a database table. |
||||||
* |
* |
||||||
* To specify the database table for storing log messages, set {@link logTableName} as |
* By default, DbTarget will use the database specified by [[connectionID]] and save |
||||||
* the name of the table and specify {@link connectionID} to be the ID of a {@link CDbConnection} |
* messages into a table named by [[tableName]]. Please refer to [[tableName]] for the required |
||||||
* application component. If they are not set, a SQLite3 database named 'log-YiiVersion.db' will be created |
* table structure. Note that this table must be created beforehand. Otherwise an exception |
||||||
* and used under the application runtime directory. |
* will be thrown when DbTarget is saving messages into DB. |
||||||
* |
* |
||||||
* @author Qiang Xue <qiang.xue@gmail.com> |
* @author Qiang Xue <qiang.xue@gmail.com> |
||||||
* @version $Id: CDbLogRoute.php 3069 2011-03-14 00:28:38Z qiang.xue $ |
* @since 2.0 |
||||||
* @package system.logging |
|
||||||
* @since 1.0 |
|
||||||
*/ |
*/ |
||||||
class CDbLogRoute extends CLogRoute |
class DbTarget extends Target |
||||||
{ |
{ |
||||||
/** |
/** |
||||||
* @var string the ID of CDbConnection application component. If not set, a SQLite database |
* @var string the ID of [[\yii\db\dao\Connection]] application component. |
||||||
* will be automatically created and used. The SQLite database file is |
* Defaults to 'db'. Please make sure that your database contains a table |
||||||
* <code>protected/runtime/log-YiiVersion.db</code>. |
* whose name is as specified in [[tableName]] and has the required table structure. |
||||||
|
* @see tableName |
||||||
*/ |
*/ |
||||||
public $connectionID; |
public $connectionID = 'db'; |
||||||
/** |
/** |
||||||
* @var string the name of the DB table that stores log content. Defaults to 'YiiLog'. |
* @var string the name of the DB table that stores log messages. Defaults to '{{log}}'. |
||||||
* If {@link autoCreateLogTable} is false and you want to create the DB table manually by yourself, |
* If you are using table prefix 'tbl_' (configured via [[\yii\db\dao\Connection::tablePrefix]]), |
||||||
* you need to make sure the DB table is of the following structure: |
* it means the DB table would be named as 'tbl_log'. |
||||||
* <pre> |
* |
||||||
* ( |
* The DB table must have the following structure: |
||||||
* id INTEGER NOT NULL PRIMARY KEY, |
* |
||||||
* level VARCHAR(128), |
* ~~~ |
||||||
* category VARCHAR(128), |
* CREATE TABLE tbl_log ( |
||||||
* logtime INTEGER, |
* id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, |
||||||
* message TEXT |
* level VARCHAR(32), |
||||||
* ) |
* category VARCHAR(255), |
||||||
* </pre> |
* log_time INTEGER, |
||||||
* Note, the 'id' column must be created as an auto-incremental column. |
* message TEXT, |
||||||
* In MySQL, this means it should be <code>id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY</code>; |
* INDEX idx_log_level (level), |
||||||
* In PostgreSQL, it is <code>id SERIAL PRIMARY KEY</code>. |
* INDEX idx_log_category (category) |
||||||
* @see autoCreateLogTable |
* ) |
||||||
|
* ~~~ |
||||||
|
* |
||||||
|
* Note that the 'id' column must be created as an auto-incremental column. |
||||||
|
* The above SQL shows the syntax of MySQL. If you are using other DBMS, you need |
||||||
|
* to adjust it accordingly. For example, in PosgreSQL, it should be `id SERIAL PRIMARY KEY`. |
||||||
|
* |
||||||
|
* The indexes declared above are not required. They are mainly used to improve the performance |
||||||
|
* of some queries about message levels and categories. Depending on your actual needs, you may |
||||||
|
* want to create other indexes. |
||||||
*/ |
*/ |
||||||
public $logTableName = 'YiiLog'; |
public $tableName = '{{log}}'; |
||||||
/** |
|
||||||
* @var boolean whether the log DB table should be automatically created if not exists. Defaults to true. |
|
||||||
* @see logTableName |
|
||||||
*/ |
|
||||||
public $autoCreateLogTable = true; |
|
||||||
/** |
|
||||||
* @var CDbConnection the DB connection instance |
|
||||||
*/ |
|
||||||
private $_db; |
|
||||||
|
|
||||||
/** |
private $_db; |
||||||
* Initializes the route. |
|
||||||
* This method is invoked after the route is created by the route manager. |
|
||||||
*/ |
|
||||||
public function init() |
|
||||||
{ |
|
||||||
parent::init(); |
|
||||||
|
|
||||||
if ($this->autoCreateLogTable) |
|
||||||
{ |
|
||||||
$db = $this->getDbConnection(); |
|
||||||
$sql = "DELETE FROM {$this->logTableName} WHERE 0=1"; |
|
||||||
try |
|
||||||
{ |
|
||||||
$db->createCommand($sql)->execute(); |
|
||||||
} |
|
||||||
catch(Exception $e) |
|
||||||
{ |
|
||||||
$this->createLogTable($db, $this->logTableName); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Creates the DB table for storing log messages. |
|
||||||
* @param CDbConnection $db the database connection |
|
||||||
* @param string $tableName the name of the table to be created |
|
||||||
*/ |
|
||||||
protected function createLogTable($db, $tableName) |
|
||||||
{ |
|
||||||
$driver = $db->getDriverName(); |
|
||||||
if ($driver === 'mysql') |
|
||||||
$logID = 'id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY'; |
|
||||||
elseif ($driver === 'pgsql') |
|
||||||
$logID = 'id SERIAL PRIMARY KEY'; |
|
||||||
else |
|
||||||
$logID = 'id INTEGER NOT NULL PRIMARY KEY'; |
|
||||||
|
|
||||||
$sql = " |
|
||||||
CREATE TABLE $tableName |
|
||||||
( |
|
||||||
$logID, |
|
||||||
level VARCHAR(128), |
|
||||||
category VARCHAR(128), |
|
||||||
logtime INTEGER, |
|
||||||
message TEXT |
|
||||||
)"; |
|
||||||
$db->createCommand($sql)->execute(); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
/** |
||||||
* @return CDbConnection the DB connection instance |
* Returns the DB connection used for saving log messages. |
||||||
* @throws CException if {@link connectionID} does not point to a valid application component. |
* @return \yii\db\dao\Connection the DB connection instance |
||||||
|
* @throws \yii\base\Exception if [[connectionID]] does not refer to a valid application component ID. |
||||||
*/ |
*/ |
||||||
protected function getDbConnection() |
public function getDbConnection() |
||||||
{ |
{ |
||||||
if ($this->_db !== null) |
if ($this->_db !== null) { |
||||||
return $this->_db; |
return $this->_db; |
||||||
elseif (($id = $this->connectionID) !== null) |
|
||||||
{ |
|
||||||
if (($this->_db = Yii::app()->getComponent($id)) instanceof CDbConnection) |
|
||||||
return $this->_db; |
|
||||||
else |
|
||||||
throw new CException(Yii::t('yii', 'CDbLogRoute.connectionID "{id}" does not point to a valid CDbConnection application component.', |
|
||||||
array('{id}' => $id))); |
|
||||||
} |
} |
||||||
else |
$this->_db = \Yii::app()->getComponent($this->connectionID); |
||||||
{ |
if (!$this->_db instanceof \yii\db\dao\Connection) { |
||||||
$dbFile = Yii::app()->getRuntimePath() . DIRECTORY_SEPARATOR . 'log-' . Yii::getVersion() . '.db'; |
throw new \yii\base\Exception('DbTarget.connectionID must refer to a valid application component ID'); |
||||||
return $this->_db = new CDbConnection('sqlite:' . $dbFile); |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
/** |
/** |
||||||
* Stores log messages into database. |
* Stores log [[messages]] to DB. |
||||||
* @param array $logs list of log messages |
* @param boolean $final whether this method is called at the end of the current application |
||||||
*/ |
*/ |
||||||
protected function processLogs($logs) |
public function exportMessages($final) |
||||||
{ |
{ |
||||||
$sql = " |
$sql = "INSERT INTO {$this->tableName} |
||||||
INSERT INTO {$this->logTableName} |
(level, category, log_time, message) VALUES |
||||||
(level, category, logtime, message) VALUES |
(:level, :category, :log_time, :message)"; |
||||||
(:level, :category, :logtime, :message) |
|
||||||
"; |
|
||||||
$command = $this->getDbConnection()->createCommand($sql); |
$command = $this->getDbConnection()->createCommand($sql); |
||||||
foreach ($logs as $log) |
foreach ($this->messages as $message) { |
||||||
{ |
$command->bindValues(array( |
||||||
$command->bindValue(':level', $log[1]); |
':level' => $message[1], |
||||||
$command->bindValue(':category', $log[2]); |
':category' => $message[2], |
||||||
$command->bindValue(':logtime', (int)$log[3]); |
':log_time' => $message[3], |
||||||
$command->bindValue(':message', $log[0]); |
':message' => $message[0], |
||||||
$command->execute(); |
))->execute(); |
||||||
} |
} |
||||||
|
|
||||||
|
$this->messages = array(); |
||||||
} |
} |
||||||
} |
} |
||||||
|
Loading…
Reference in new issue