Commit 760fdf98 by Qiang Xue

w

parent 54e36b75
<?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 &copy; 2008-2011 Yii Software LLC * @copyright Copyright &copy; 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();
} }
} }
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
* @license http://www.yiiframework.com/license/ * @license http://www.yiiframework.com/license/
*/ */
namespace yii\logging;
/** /**
* FileTarget records log messages in files. * FileTarget records log messages in files.
* *
......
- logging - logging
* WebTarget
* ProfileTarget
* Toolbar ?
- base - base
* error/exception handling * error/exception handling
* module * module
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment