Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenaka Moorthi <benaka.moorthi@gmail.com>2013-09-23 12:05:13 +0400
committerBenaka Moorthi <benaka.moorthi@gmail.com>2013-09-23 12:05:13 +0400
commit809ca913e379113e4c64e9fa82a0d8f17fe8fca6 (patch)
tree0d6eb5c1d02430df4a260371135e392068994261 /core/Log.php
parent6dce0122d24c3b2f7b07c26a69c850f86075e025 (diff)
Initial refactoring.
Diffstat (limited to 'core/Log.php')
-rw-r--r--core/Log.php386
1 files changed, 245 insertions, 141 deletions
diff --git a/core/Log.php b/core/Log.php
index a2720098dd..feeaf92ef4 100644
--- a/core/Log.php
+++ b/core/Log.php
@@ -10,196 +10,300 @@
*/
namespace Piwik;
-use Piwik\Log\APICall;
-use Piwik\Log\Error;
-use Piwik\Log\Exception;
-use Piwik\Log\Message;
+use Piwik\Common;
+use Piwik\Db;
+
+/* TODO:
+; all calls to the API (method name, parameters, execution time, caller IP, etc.)
+; disabled by default as it can cause serious overhead and should only be used wisely
+;logger_api_call[] = file
+*/
/**
- *
- * @package Piwik
- * @subpackage Log
- * @see Zend_Log, libs/Zend/Log.php
- * @link http://framework.zend.com/manual/en/zend.log.html
+ * TODO
*/
-abstract class Log extends \Zend_Log
+class Log
{
- protected $logToDatabaseTableName = null;
- protected $logToDatabaseColumnMapping = null;
- protected $logToFileFilename = null;
- protected $fileFormatter = null;
- protected $screenFormatter = null;
- protected $currentRequestKey;
+ // log levels
+ const NONE = 0;
+ const ERROR = 1;
+ const WARN = 2;
+ const INFO = 3;
+ const DEBUG = 4;
+ const VERBOSE = 5;
+
+ // config option names
+ const LOG_LEVEL_CONFIG_OPTION = 'log_level';
+ const LOG_WRITERS_CONFIG_OPTION = 'log_writers';
+ const LOGGER_FILE_PATH_CONFIG_OPTION = 'logger_file_path';
+ const LOGGER_DATABASE_TABLE_CONFIG_OPTION = 'logger_db_table';
+
+ /**
+ * TODO
+ */
+ private static $instance = null;
+
+ /**
+ * TODO
+ */
+ public static function getInstance()
+ {
+ if (self::$instance === null) {
+ self::$instance = new Log();
+ }
+ return self::$instance;
+ }
+
+ /**
+ * TODO
+ */
+ private $currentLogLevel = self::WARN;
+
+ /**
+ * TODO
+ */
+ private $writers = array();
+
+ /**
+ * TODO
+ */
+ private $logMessageFormat = "[%pluginName%:%datetime%] %message%";
+
+ /**
+ * TODO
+ */
+ private $logToDatabaseTable = "logger_message";
+
+ /**
+ * TODO
+ */
+ private $logToFileFilename;
/**
- * @param string $logToFileFilename filename of logfile
- * @param \Zend_Log_Formatter_Interface $fileFormatter
- * @param \Zend_Log_Formatter_Interface $screenFormatter
- * @param string $logToDatabaseTableName
- * @param array $logToDatabaseColumnMapping
+ * TODO
*/
- function __construct($logToFileFilename,
- $fileFormatter,
- $screenFormatter,
- $logToDatabaseTableName,
- $logToDatabaseColumnMapping)
+ public function __construct()
{
- parent::__construct();
+ $logConfig = Config::getInstance()->log;
+ $this->setCurrentLogLevelFromConfig($logConfig);
+ $this->setLogWritersFromConfig($logConfig);
+ $this->setLogFilePathFromConfig($logConfig);
+ $this->setLogDatabaseTableFromConfig($logConfig);
+ $this->disableLoggingBasedOnConfig($logConfig);
+ }
- $this->currentRequestKey = substr(Common::generateUniqId(), 0, 8);
+ private function setLogWritersFromConfig($logConfig)
+ {
+ // set the log writers
+ $logWriters = $logConfig[self::LOG_WRITERS_CONFIG_OPTION];
- $log_dir = Config::getInstance()->log['logger_file_path'];
- if ($log_dir[0] != '/' && $log_dir[0] != DIRECTORY_SEPARATOR) {
- $log_dir = PIWIK_USER_PATH . '/' . $log_dir;
+ $logWriters = array_map('trim', $logWriters);
+ foreach ($logWriters as $writerName) {
+ $writer = $this->createWriterByName($writerName);
+ if (!empty($writer)) {
+ $this->writers[] = $writer;
+ }
}
- $this->logToFileFilename = $log_dir . '/' . $logToFileFilename;
+ }
+
+ private function setCurrentLogLevelFromConfig($logConfig)
+ {
+ if (!empty($logConfig[self::LOG_LEVEL_CONFIG_OPTION])) {
+ $logLevel = $this->getLogLevelFromStringName(self::LOG_LEVEL_CONFIG_OPTION);
- $this->fileFormatter = $fileFormatter;
- $this->screenFormatter = $screenFormatter;
- $this->logToDatabaseTableName = Common::prefixTable($logToDatabaseTableName);
- $this->logToDatabaseColumnMapping = $logToDatabaseColumnMapping;
+ if ($logLevel >= self::NONE // sanity check
+ && $logLevel <= self::VERBOSE
+ ) {
+ $this->currentLogLevel = $logLevel;
+ }
+ }
}
- function addWriteToFile()
+ private function setLogDatabaseTableFromConfig($logConfig)
{
- Filesystem::mkdir(dirname($this->logToFileFilename));
- $writerFile = new \Zend_Log_Writer_Stream($this->logToFileFilename);
- $writerFile->setFormatter($this->fileFormatter);
- $this->addWriter($writerFile);
+ if (!empty($logConfig[self::LOGGER_DATABASE_TABLE_CONFIG_OPTION])) {
+ $this->logToDatabaseTable = $logConfig[self::LOGGER_DATABASE_TABLE_CONFIG_OPTION];
+ }
}
- function addWriteToNull()
+ private function setLogFilePathFromConfig($logConfig)
{
- $this->addWriter(new \Zend_Log_Writer_Null);
+ $logDir = $logConfig[self::LOGGER_FILE_PATH_CONFIG_OPTION];
+ if ($logDir[0] != '/' && $logDir[0] != DIRECTORY_SEPARATOR) {
+ $logDir = PIWIK_USER_PATH . '/' . $logDir;
+ }
+ $this->logToFileFilename = $logDir . '/piwik.log';
}
- function addWriteToDatabase()
+ private function createWriterByName($writerName)
{
- $writerDb = new \Zend_Log_Writer_Db(
- \Zend_Registry::get('db'),
- $this->logToDatabaseTableName,
- $this->logToDatabaseColumnMapping);
+ $self = $this;
+
+ $writer = false;
+ if ($writerName == 'file') {
+ $writer = function ($pluginName, $datetime, $message) use ($self) {
+ $self->logToFile($this->formatMessage($pluginName, $datetime, $message));
+ };
+ } else if ($writerName == 'screen') {
+ $writer = function ($pluginName, $datetime, $message) use ($self) {
+ $self->logToScreen($this->formatMessage($pluginName, $datetime, $message));
+ };
+ } else if ($writerName == 'db') {
+ $writer = function ($pluginName, $datetime, $message) use ($self) {
+ $self->logToDatabase($pluginName, $datetime, $message);
+ };
+ }
+ return $writer;
+ }
- $this->addWriter($writerDb);
+ private function logToFile($message)
+ {
+ file_put_contents($this->logToFileFilename, $message . "\n", FILE_APPEND);
}
- function addWriteToScreen()
+ private function logToScreen($message)
{
- $writerScreen = new \Zend_Log_Writer_Stream('php://output');
- $writerScreen->setFormatter($this->screenFormatter);
- $this->addWriter($writerScreen);
+ echo $message . "\n";
}
- public function getWritersCount()
+ private function logToDatabase($pluginName, $datetime, $message)
{
- return count($this->_writers);
+ $sql = "INSERT INTO " . Common::prefixTable($this->logToDatabaseTable)
+ . " (plugin, time, message)"
+ . " VALUES (?, ?, ?)";
+ Db::query($sql, array($pluginName, $datetime, $message));
}
/**
- * Log an event
- * @param string $event
- * @param int $priority
- * @param null $extras
- * @throws \Zend_Log_Exception
- * @return void
+ * TODO
*/
- public function log($event, $priority, $extras = null)
+ public function log($level, $pluginName, $message, $sprintfParams = array())
{
- // sanity checks
- if (empty($this->_writers)) {
- throw new \Zend_Log_Exception('No writers were added');
+ if ($this->shouldLoggerLog($level)) {
+ $datetime = date("Y-m-d H:i:s");
+ $message = sprintf($message, $sprintfParams);
+
+ $this->writeMessage($pluginName, $message, $datetime);
}
+ }
- $event['timestamp'] = date('Y-m-d H:i:s');
- $event['requestKey'] = $this->currentRequestKey;
- // pack into event required by filters and writers
- $event = array_merge($event, $this->_extras);
+ /**
+ * TODO
+ */
+ private function formatMessage($pluginName, $message, $datetime)
+ {
+ return str_replace(
+ array("%pluginName%", "%message%", "%datetime%"),
+ array($pluginName, $message, $datetime),
+ $this->logMessageFormat
+ );
+ }
- // one message must stay on one line
- if (isset($event['message'])) {
- $event['message'] = str_replace(array(PHP_EOL, "\n"), " ", $event['message']);
+ /**
+ * TODO
+ */
+ private function writeMessage($pluginName, $datetime, $message)
+ {
+ foreach ($this->writers as $writer) {
+ $writer($pluginName, $datetime, $message);
}
+ }
- // Truncate the backtrace which can be too long to display in the browser
- if (!empty($event['backtrace'])) {
- $maxSizeOutputBytes = 1024 * 1024; // no more than 1M output please
- $truncateBacktraceLineAfter = 1000;
- $maxLines = ceil($maxSizeOutputBytes / $truncateBacktraceLineAfter);
- $bt = explode("\n", $event['backtrace']);
- foreach ($bt as $count => &$line) {
- if (strlen($line) > $truncateBacktraceLineAfter) {
- $line = substr($line, 0, $truncateBacktraceLineAfter) . '...';
- }
- if ($count > $maxLines) {
- $line .= "\nTruncated error message.";
- break;
- }
- }
- $event['backtrace'] = implode("\n", $bt);
- }
- // abort if rejected by the global filters
- foreach ($this->_filters as $filter) {
- if (!$filter->accept($event)) {
- return;
- }
- }
+ /**
+ * TODO
+ */
+ public static function log($level, $pluginName, $message, $sprintfParams = array())
+ {
+ self::getInstance()->log($level, $pluginName, $message, $sprintfParams);
+ }
- // send to each writer
- foreach ($this->_writers as $writer) {
- $writer->write($event);
- }
+ /**
+ * TODO
+ */
+ public static function e($pluginName, $message, $sprintfParams = array())
+ {
+ self::log(self::ERROR, $pluginName, $message, $sprintfParams);
}
+ /**
+ * TODO
+ */
+ public static function w($pluginName, $message, $sprintfParams = array())
+ {
+ self::log(self::WARN, $pluginName, $message, $sprintfParams);
+ }
/**
- * Create log object
- * @throws Exception
+ * TODO
*/
- static public function make()
+ public static function i($pluginName, $message, $sprintfParams = array())
{
- $configAPI = Config::getInstance()->log;
+ self::log(self::INFO, $pluginName, $message, $sprintfParams);
+ }
- /** @var Log[] $aLoggers */
- $aLoggers = array(
- 'logger_api_call' => new APICall,
- 'logger_exception' => new Exception,
- 'logger_error' => new Error,
- 'logger_message' => new Message,
- );
+ /**
+ * TODO
+ */
+ public static function d($pluginName, $message, $sprintfParams = array())
+ {
+ self::log(self::DEBUG, $pluginName, $message, $sprintfParams);
+ }
- foreach ($configAPI as $loggerType => $aRecordTo) {
- if (isset($aLoggers[$loggerType])) {
- $logger = $aLoggers[$loggerType];
-
- foreach ($aRecordTo as $recordTo) {
- switch ($recordTo) {
- case 'screen':
- $logger->addWriteToScreen();
- break;
-
- case 'database':
- $logger->addWriteToDatabase();
- break;
-
- case 'file':
- $logger->addWriteToFile();
- break;
-
- default:
- throw new \Exception("'$recordTo' is not a valid Log type. Valid logger types are: screen, database, file.");
- break;
- }
- }
- }
+ /**
+ * TODO
+ */
+ public static function v($pluginName, $message, $sprintfParams = array())
+ {
+ self::log(self::VERBOSE, $pluginName, $message, $sprintfParams);
+ }
+
+ /**
+ * Returns if logging should work
+ * @return bool
+ */
+ private function shouldLoggerLog($level)
+ {
+ return $level <= $this->currentLogLevel;
+ }
+
+ private function disableLoggingBasedOnConfig($logConfig)
+ {
+ $disableLogging = false;
+
+ if (!empty($logConfig['log_only_when_cli'])
+ && !Common::isPhpCliMode()
+ ) {
+ $disableLogging = true;
}
- foreach ($aLoggers as $loggerType => $logger) {
- if ($logger->getWritersCount() == 0) {
- $logger->addWriteToNull();
- }
- \Zend_Registry::set($loggerType, $logger);
+ if (!empty($logConfig['log_only_when_debug_parameter'])
+ && !isset($_REQUEST['debug'])
+ ) {
+ $disableLogging = true;
}
- }
-}
+ if ($disableLogging) {
+ $this->currentLogLevel = self::NONE;
+ }
+ }
+ private function getLogLevelFromStringName($name)
+ {
+ switch ($name) {
+ case 'NONE':
+ return self::NONE;
+ case 'ERROR':
+ return self::ERROR;
+ case 'WARN':
+ return self::WARN;
+ case 'INFO':
+ return self::INFO;
+ case 'DEBUG':
+ return self::DEBUG;
+ case 'VERBOSE':
+ return self::VERBOSE;
+ default:
+ return -1;
+ }
+ }
+} \ No newline at end of file