init
This commit is contained in:
99
vendor/yiisoft/yii2/log/DbTarget.php
vendored
Normal file
99
vendor/yiisoft/yii2/log/DbTarget.php
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\log;
|
||||
|
||||
use Yii;
|
||||
use yii\base\InvalidConfigException;
|
||||
use yii\db\Connection;
|
||||
use yii\db\Exception;
|
||||
use yii\di\Instance;
|
||||
use yii\helpers\VarDumper;
|
||||
|
||||
/**
|
||||
* DbTarget stores log messages in a database table.
|
||||
*
|
||||
* The database connection is specified by [[db]]. Database schema could be initialized by applying migration:
|
||||
*
|
||||
* ```
|
||||
* yii migrate --migrationPath=@yii/log/migrations/
|
||||
* ```
|
||||
*
|
||||
* If you don't want to use migration and need SQL instead, files for all databases are in migrations directory.
|
||||
*
|
||||
* You may change the name of the table used to store the data by setting [[logTable]].
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class DbTarget extends Target
|
||||
{
|
||||
/**
|
||||
* @var Connection|array|string the DB connection object or the application component ID of the DB connection.
|
||||
* After the DbTarget object is created, if you want to change this property, you should only assign it
|
||||
* with a DB connection object.
|
||||
* Starting from version 2.0.2, this can also be a configuration array for creating the object.
|
||||
*/
|
||||
public $db = 'db';
|
||||
/**
|
||||
* @var string name of the DB table to store cache content. Defaults to "log".
|
||||
*/
|
||||
public $logTable = '{{%log}}';
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the DbTarget component.
|
||||
* This method will initialize the [[db]] property to make sure it refers to a valid DB connection.
|
||||
* @throws InvalidConfigException if [[db]] is invalid.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
$this->db = Instance::ensure($this->db, Connection::className());
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores log messages to DB.
|
||||
* Starting from version 2.0.14, this method throws LogRuntimeException in case the log can not be exported.
|
||||
* @throws Exception
|
||||
* @throws LogRuntimeException
|
||||
*/
|
||||
public function export()
|
||||
{
|
||||
if ($this->db->getTransaction()) {
|
||||
// create new database connection, if there is an open transaction
|
||||
// to ensure insert statement is not affected by a rollback
|
||||
$this->db = clone $this->db;
|
||||
}
|
||||
|
||||
$tableName = $this->db->quoteTableName($this->logTable);
|
||||
$sql = "INSERT INTO $tableName ([[level]], [[category]], [[log_time]], [[prefix]], [[message]])
|
||||
VALUES (:level, :category, :log_time, :prefix, :message)";
|
||||
$command = $this->db->createCommand($sql);
|
||||
foreach ($this->messages as $message) {
|
||||
list($text, $level, $category, $timestamp) = $message;
|
||||
if (!is_string($text)) {
|
||||
// exceptions may not be serializable if in the call stack somewhere is a Closure
|
||||
if ($text instanceof \Throwable || $text instanceof \Exception) {
|
||||
$text = (string) $text;
|
||||
} else {
|
||||
$text = VarDumper::export($text);
|
||||
}
|
||||
}
|
||||
if ($command->bindValues([
|
||||
':level' => $level,
|
||||
':category' => $category,
|
||||
':log_time' => $timestamp,
|
||||
':prefix' => $this->getMessagePrefix($message),
|
||||
':message' => $text,
|
||||
])->execute() > 0) {
|
||||
continue;
|
||||
}
|
||||
throw new LogRuntimeException('Unable to export log through database!');
|
||||
}
|
||||
}
|
||||
}
|
||||
207
vendor/yiisoft/yii2/log/Dispatcher.php
vendored
Normal file
207
vendor/yiisoft/yii2/log/Dispatcher.php
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\log;
|
||||
|
||||
use Yii;
|
||||
use yii\base\Component;
|
||||
use yii\base\ErrorHandler;
|
||||
|
||||
/**
|
||||
* Dispatcher manages a set of [[Target|log targets]].
|
||||
*
|
||||
* Dispatcher implements the [[dispatch()]]-method that forwards the log messages from a [[Logger]] to
|
||||
* the registered log [[targets]].
|
||||
*
|
||||
* An instance of Dispatcher is registered as a core application component and can be accessed using `Yii::$app->log`.
|
||||
*
|
||||
* You may configure the targets in application configuration, like the following:
|
||||
*
|
||||
* ```php
|
||||
* [
|
||||
* 'components' => [
|
||||
* 'log' => [
|
||||
* 'targets' => [
|
||||
* 'file' => [
|
||||
* 'class' => 'yii\log\FileTarget',
|
||||
* 'levels' => ['trace', 'info'],
|
||||
* 'categories' => ['yii\*'],
|
||||
* ],
|
||||
* 'email' => [
|
||||
* 'class' => 'yii\log\EmailTarget',
|
||||
* 'levels' => ['error', 'warning'],
|
||||
* 'message' => [
|
||||
* 'to' => 'admin@example.com',
|
||||
* ],
|
||||
* ],
|
||||
* ],
|
||||
* ],
|
||||
* ],
|
||||
* ]
|
||||
* ```
|
||||
*
|
||||
* Each log target can have a name and can be referenced via the [[targets]] property as follows:
|
||||
*
|
||||
* ```php
|
||||
* Yii::$app->log->targets['file']->enabled = false;
|
||||
* ```
|
||||
*
|
||||
* @property int $flushInterval How many messages should be logged before they are sent to targets. This
|
||||
* method returns the value of [[Logger::flushInterval]].
|
||||
* @property Logger $logger The logger. If not set, [[\Yii::getLogger()]] will be used. Note that the type of
|
||||
* this property differs in getter and setter. See [[getLogger()]] and [[setLogger()]] for details.
|
||||
* @property int $traceLevel How many application call stacks should be logged together with each message.
|
||||
* This method returns the value of [[Logger::traceLevel]]. Defaults to 0.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Dispatcher extends Component
|
||||
{
|
||||
/**
|
||||
* @var array|Target[] the log targets. Each array element represents a single [[Target|log target]] instance
|
||||
* or the configuration for creating the log target instance.
|
||||
*/
|
||||
public $targets = [];
|
||||
|
||||
/**
|
||||
* @var Logger the logger.
|
||||
*/
|
||||
private $_logger;
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct($config = [])
|
||||
{
|
||||
// ensure logger gets set before any other config option
|
||||
if (isset($config['logger'])) {
|
||||
$this->setLogger($config['logger']);
|
||||
unset($config['logger']);
|
||||
}
|
||||
// connect logger and dispatcher
|
||||
$this->getLogger();
|
||||
|
||||
parent::__construct($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
foreach ($this->targets as $name => $target) {
|
||||
if (!$target instanceof Target) {
|
||||
$this->targets[$name] = Yii::createObject($target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the connected logger.
|
||||
* If not set, [[\Yii::getLogger()]] will be used.
|
||||
* @property Logger the logger. If not set, [[\Yii::getLogger()]] will be used.
|
||||
* @return Logger the logger.
|
||||
*/
|
||||
public function getLogger()
|
||||
{
|
||||
if ($this->_logger === null) {
|
||||
$this->setLogger(Yii::getLogger());
|
||||
}
|
||||
|
||||
return $this->_logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the connected logger.
|
||||
* @param Logger|string|array $value the logger to be used. This can either be a logger instance
|
||||
* or a configuration that will be used to create one using [[Yii::createObject()]].
|
||||
*/
|
||||
public function setLogger($value)
|
||||
{
|
||||
if (is_string($value) || is_array($value)) {
|
||||
$value = Yii::createObject($value);
|
||||
}
|
||||
$this->_logger = $value;
|
||||
$this->_logger->dispatcher = $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int how many application call stacks should be logged together with each message.
|
||||
* This method returns the value of [[Logger::traceLevel]]. Defaults to 0.
|
||||
*/
|
||||
public function getTraceLevel()
|
||||
{
|
||||
return $this->getLogger()->traceLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $value how many application call stacks should be logged together with each message.
|
||||
* This method will set the value of [[Logger::traceLevel]]. If the value is greater than 0,
|
||||
* at most that number of call stacks will be logged. Note that only application call stacks are counted.
|
||||
* Defaults to 0.
|
||||
*/
|
||||
public function setTraceLevel($value)
|
||||
{
|
||||
$this->getLogger()->traceLevel = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int how many messages should be logged before they are sent to targets.
|
||||
* This method returns the value of [[Logger::flushInterval]].
|
||||
*/
|
||||
public function getFlushInterval()
|
||||
{
|
||||
return $this->getLogger()->flushInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $value how many messages should be logged before they are sent to targets.
|
||||
* This method will set the value of [[Logger::flushInterval]].
|
||||
* Defaults to 1000, meaning the [[Logger::flush()]] method will be invoked once every 1000 messages logged.
|
||||
* Set this property to be 0 if you don't want to flush messages until the application terminates.
|
||||
* This property mainly affects how much memory will be taken by the logged messages.
|
||||
* A smaller value means less memory, but will increase the execution time due to the overhead of [[Logger::flush()]].
|
||||
*/
|
||||
public function setFlushInterval($value)
|
||||
{
|
||||
$this->getLogger()->flushInterval = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches the logged messages to [[targets]].
|
||||
* @param array $messages the logged messages
|
||||
* @param bool $final whether this method is called at the end of the current application
|
||||
*/
|
||||
public function dispatch($messages, $final)
|
||||
{
|
||||
$targetErrors = [];
|
||||
foreach ($this->targets as $target) {
|
||||
if ($target->enabled) {
|
||||
try {
|
||||
$target->collect($messages, $final);
|
||||
} catch (\Exception $e) {
|
||||
$target->enabled = false;
|
||||
$targetErrors[] = [
|
||||
'Unable to send log via ' . get_class($target) . ': ' . ErrorHandler::convertExceptionToVerboseString($e),
|
||||
Logger::LEVEL_WARNING,
|
||||
__METHOD__,
|
||||
microtime(true),
|
||||
[],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($targetErrors)) {
|
||||
$this->dispatch($targetErrors, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
106
vendor/yiisoft/yii2/log/EmailTarget.php
vendored
Normal file
106
vendor/yiisoft/yii2/log/EmailTarget.php
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\log;
|
||||
|
||||
use Yii;
|
||||
use yii\base\InvalidConfigException;
|
||||
use yii\di\Instance;
|
||||
use yii\mail\MailerInterface;
|
||||
|
||||
/**
|
||||
* EmailTarget sends selected log messages to the specified email addresses.
|
||||
*
|
||||
* You may configure the email to be sent by setting the [[message]] property, through which
|
||||
* you can set the target email addresses, subject, etc.:
|
||||
*
|
||||
* ```php
|
||||
* 'components' => [
|
||||
* 'log' => [
|
||||
* 'targets' => [
|
||||
* [
|
||||
* 'class' => 'yii\log\EmailTarget',
|
||||
* 'mailer' => 'mailer',
|
||||
* 'levels' => ['error', 'warning'],
|
||||
* 'message' => [
|
||||
* 'from' => ['log@example.com'],
|
||||
* 'to' => ['developer1@example.com', 'developer2@example.com'],
|
||||
* 'subject' => 'Log message',
|
||||
* ],
|
||||
* ],
|
||||
* ],
|
||||
* ],
|
||||
* ],
|
||||
* ```
|
||||
*
|
||||
* In the above `mailer` is ID of the component that sends email and should be already configured.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class EmailTarget extends Target
|
||||
{
|
||||
/**
|
||||
* @var array the configuration array for creating a [[\yii\mail\MessageInterface|message]] object.
|
||||
* Note that the "to" option must be set, which specifies the destination email address(es).
|
||||
*/
|
||||
public $message = [];
|
||||
/**
|
||||
* @var MailerInterface|array|string the mailer object or the application component ID of the mailer object.
|
||||
* After the EmailTarget object is created, if you want to change this property, you should only assign it
|
||||
* with a mailer object.
|
||||
* Starting from version 2.0.2, this can also be a configuration array for creating the object.
|
||||
*/
|
||||
public $mailer = 'mailer';
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
if (empty($this->message['to'])) {
|
||||
throw new InvalidConfigException('The "to" option must be set for EmailTarget::message.');
|
||||
}
|
||||
$this->mailer = Instance::ensure($this->mailer, 'yii\mail\MailerInterface');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends log messages to specified email addresses.
|
||||
* Starting from version 2.0.14, this method throws LogRuntimeException in case the log can not be exported.
|
||||
* @throws LogRuntimeException
|
||||
*/
|
||||
public function export()
|
||||
{
|
||||
// moved initialization of subject here because of the following issue
|
||||
// https://github.com/yiisoft/yii2/issues/1446
|
||||
if (empty($this->message['subject'])) {
|
||||
$this->message['subject'] = 'Application Log';
|
||||
}
|
||||
$messages = array_map([$this, 'formatMessage'], $this->messages);
|
||||
$body = wordwrap(implode("\n", $messages), 70);
|
||||
$message = $this->composeMessage($body);
|
||||
if (!$message->send($this->mailer)) {
|
||||
throw new LogRuntimeException('Unable to export log through email!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Composes a mail message with the given body content.
|
||||
* @param string $body the body content
|
||||
* @return \yii\mail\MessageInterface $message
|
||||
*/
|
||||
protected function composeMessage($body)
|
||||
{
|
||||
$message = $this->mailer->compose();
|
||||
Yii::configure($message, $this->message);
|
||||
$message->setTextBody($body);
|
||||
|
||||
return $message;
|
||||
}
|
||||
}
|
||||
206
vendor/yiisoft/yii2/log/FileTarget.php
vendored
Normal file
206
vendor/yiisoft/yii2/log/FileTarget.php
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\log;
|
||||
|
||||
use Yii;
|
||||
use yii\base\InvalidConfigException;
|
||||
use yii\helpers\FileHelper;
|
||||
|
||||
/**
|
||||
* FileTarget records log messages in a file.
|
||||
*
|
||||
* The log file is specified via [[logFile]]. If the size of the log file exceeds
|
||||
* [[maxFileSize]] (in kilo-bytes), a rotation will be performed, which renames
|
||||
* the current log file by suffixing the file name with '.1'. All existing log
|
||||
* files are moved backwards by one place, i.e., '.2' to '.3', '.1' to '.2', and so on.
|
||||
* The property [[maxLogFiles]] specifies how many history files to keep.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class FileTarget extends Target
|
||||
{
|
||||
/**
|
||||
* @var string log file path or [path alias](guide:concept-aliases). If not set, it will use the "@runtime/logs/app.log" file.
|
||||
* The directory containing the log files will be automatically created if not existing.
|
||||
*/
|
||||
public $logFile;
|
||||
/**
|
||||
* @var bool whether log files should be rotated when they reach a certain [[maxFileSize|maximum size]].
|
||||
* Log rotation is enabled by default. This property allows you to disable it, when you have configured
|
||||
* an external tools for log rotation on your server.
|
||||
* @since 2.0.3
|
||||
*/
|
||||
public $enableRotation = true;
|
||||
/**
|
||||
* @var int maximum log file size, in kilo-bytes. Defaults to 10240, meaning 10MB.
|
||||
*/
|
||||
public $maxFileSize = 10240; // in KB
|
||||
/**
|
||||
* @var int number of log files used for rotation. Defaults to 5.
|
||||
*/
|
||||
public $maxLogFiles = 5;
|
||||
/**
|
||||
* @var int the permission to be set for newly created log files.
|
||||
* This value will be used by PHP chmod() function. No umask will be applied.
|
||||
* If not set, the permission will be determined by the current environment.
|
||||
*/
|
||||
public $fileMode;
|
||||
/**
|
||||
* @var int the permission to be set for newly created directories.
|
||||
* This value will be used by PHP chmod() function. No umask will be applied.
|
||||
* Defaults to 0775, meaning the directory is read-writable by owner and group,
|
||||
* but read-only for other users.
|
||||
*/
|
||||
public $dirMode = 0775;
|
||||
/**
|
||||
* @var bool Whether to rotate log files by copy and truncate in contrast to rotation by
|
||||
* renaming files. Defaults to `true` to be more compatible with log tailers and is windows
|
||||
* systems which do not play well with rename on open files. Rotation by renaming however is
|
||||
* a bit faster.
|
||||
*
|
||||
* The problem with windows systems where the [rename()](http://www.php.net/manual/en/function.rename.php)
|
||||
* function does not work with files that are opened by some process is described in a
|
||||
* [comment by Martin Pelletier](http://www.php.net/manual/en/function.rename.php#102274) in
|
||||
* the PHP documentation. By setting rotateByCopy to `true` you can work
|
||||
* around this problem.
|
||||
*/
|
||||
public $rotateByCopy = true;
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the route.
|
||||
* This method is invoked after the route is created by the route manager.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
if ($this->logFile === null) {
|
||||
$this->logFile = Yii::$app->getRuntimePath() . '/logs/app.log';
|
||||
} else {
|
||||
$this->logFile = Yii::getAlias($this->logFile);
|
||||
}
|
||||
if ($this->maxLogFiles < 1) {
|
||||
$this->maxLogFiles = 1;
|
||||
}
|
||||
if ($this->maxFileSize < 1) {
|
||||
$this->maxFileSize = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes log messages to a file.
|
||||
* Starting from version 2.0.14, this method throws LogRuntimeException in case the log can not be exported.
|
||||
* @throws InvalidConfigException if unable to open the log file for writing
|
||||
* @throws LogRuntimeException if unable to write complete log to file
|
||||
*/
|
||||
public function export()
|
||||
{
|
||||
$logPath = dirname($this->logFile);
|
||||
FileHelper::createDirectory($logPath, $this->dirMode, true);
|
||||
|
||||
$text = implode("\n", array_map([$this, 'formatMessage'], $this->messages)) . "\n";
|
||||
if (($fp = @fopen($this->logFile, 'a')) === false) {
|
||||
throw new InvalidConfigException("Unable to append to log file: {$this->logFile}");
|
||||
}
|
||||
@flock($fp, LOCK_EX);
|
||||
if ($this->enableRotation) {
|
||||
// clear stat cache to ensure getting the real current file size and not a cached one
|
||||
// this may result in rotating twice when cached file size is used on subsequent calls
|
||||
clearstatcache();
|
||||
}
|
||||
if ($this->enableRotation && @filesize($this->logFile) > $this->maxFileSize * 1024) {
|
||||
$this->rotateFiles();
|
||||
@flock($fp, LOCK_UN);
|
||||
@fclose($fp);
|
||||
$writeResult = @file_put_contents($this->logFile, $text, FILE_APPEND | LOCK_EX);
|
||||
if ($writeResult === false) {
|
||||
$error = error_get_last();
|
||||
throw new LogRuntimeException("Unable to export log through file!: {$error['message']}");
|
||||
}
|
||||
$textSize = strlen($text);
|
||||
if ($writeResult < $textSize) {
|
||||
throw new LogRuntimeException("Unable to export whole log through file! Wrote $writeResult out of $textSize bytes.");
|
||||
}
|
||||
} else {
|
||||
$writeResult = @fwrite($fp, $text);
|
||||
if ($writeResult === false) {
|
||||
$error = error_get_last();
|
||||
throw new LogRuntimeException("Unable to export log through file!: {$error['message']}");
|
||||
}
|
||||
$textSize = strlen($text);
|
||||
if ($writeResult < $textSize) {
|
||||
throw new LogRuntimeException("Unable to export whole log through file! Wrote $writeResult out of $textSize bytes.");
|
||||
}
|
||||
@flock($fp, LOCK_UN);
|
||||
@fclose($fp);
|
||||
}
|
||||
if ($this->fileMode !== null) {
|
||||
@chmod($this->logFile, $this->fileMode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates log files.
|
||||
*/
|
||||
protected function rotateFiles()
|
||||
{
|
||||
$file = $this->logFile;
|
||||
for ($i = $this->maxLogFiles; $i >= 0; --$i) {
|
||||
// $i == 0 is the original log file
|
||||
$rotateFile = $file . ($i === 0 ? '' : '.' . $i);
|
||||
if (is_file($rotateFile)) {
|
||||
// suppress errors because it's possible multiple processes enter into this section
|
||||
if ($i === $this->maxLogFiles) {
|
||||
@unlink($rotateFile);
|
||||
continue;
|
||||
}
|
||||
$newFile = $this->logFile . '.' . ($i + 1);
|
||||
$this->rotateByCopy ? $this->rotateByCopy($rotateFile, $newFile) : $this->rotateByRename($rotateFile, $newFile);
|
||||
if ($i === 0) {
|
||||
$this->clearLogFile($rotateFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* Clear log file without closing any other process open handles
|
||||
* @param string $rotateFile
|
||||
*/
|
||||
private function clearLogFile($rotateFile)
|
||||
{
|
||||
if ($filePointer = @fopen($rotateFile, 'a')) {
|
||||
@ftruncate($filePointer, 0);
|
||||
@fclose($filePointer);
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* Copy rotated file into new file
|
||||
* @param string $rotateFile
|
||||
* @param string $newFile
|
||||
*/
|
||||
private function rotateByCopy($rotateFile, $newFile)
|
||||
{
|
||||
@copy($rotateFile, $newFile);
|
||||
if ($this->fileMode !== null) {
|
||||
@chmod($newFile, $this->fileMode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames rotated file into new file
|
||||
* @param string $rotateFile
|
||||
* @param string $newFile
|
||||
*/
|
||||
private function rotateByRename($rotateFile, $newFile)
|
||||
{
|
||||
@rename($rotateFile, $newFile);
|
||||
}
|
||||
}
|
||||
25
vendor/yiisoft/yii2/log/LogRuntimeException.php
vendored
Normal file
25
vendor/yiisoft/yii2/log/LogRuntimeException.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\log;
|
||||
|
||||
/**
|
||||
* LogRuntimeException represents an exception caused by problems with log delivery.
|
||||
*
|
||||
* @author Bizley <pawel@positive.codes>
|
||||
* @since 2.0.14
|
||||
*/
|
||||
class LogRuntimeException extends \yii\base\Exception
|
||||
{
|
||||
/**
|
||||
* @return string the user-friendly name of this exception
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Log Runtime';
|
||||
}
|
||||
}
|
||||
326
vendor/yiisoft/yii2/log/Logger.php
vendored
Normal file
326
vendor/yiisoft/yii2/log/Logger.php
vendored
Normal file
@@ -0,0 +1,326 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\log;
|
||||
|
||||
use Yii;
|
||||
use yii\base\Component;
|
||||
|
||||
/**
|
||||
* Logger records logged messages in memory and sends them to different targets if [[dispatcher]] is set.
|
||||
*
|
||||
* A Logger instance can be accessed via `Yii::getLogger()`. You can call the method [[log()]] to record a single log message.
|
||||
* For convenience, a set of shortcut methods are provided for logging messages of various severity levels
|
||||
* via the [[Yii]] class:
|
||||
*
|
||||
* - [[Yii::trace()]]
|
||||
* - [[Yii::error()]]
|
||||
* - [[Yii::warning()]]
|
||||
* - [[Yii::info()]]
|
||||
* - [[Yii::beginProfile()]]
|
||||
* - [[Yii::endProfile()]]
|
||||
*
|
||||
* For more details and usage information on Logger, see the [guide article on logging](guide:runtime-logging).
|
||||
*
|
||||
* When the application ends or [[flushInterval]] is reached, Logger will call [[flush()]]
|
||||
* to send logged messages to different log targets, such as [[FileTarget|file]], [[EmailTarget|email]],
|
||||
* or [[DbTarget|database]], with the help of the [[dispatcher]].
|
||||
*
|
||||
* @property array $dbProfiling The first element indicates the number of SQL statements executed, and the
|
||||
* second element the total time spent in SQL execution. This property is read-only.
|
||||
* @property float $elapsedTime The total elapsed time in seconds for current request. This property is
|
||||
* read-only.
|
||||
* @property array $profiling The profiling results. Each element is an array consisting of these elements:
|
||||
* `info`, `category`, `timestamp`, `trace`, `level`, `duration`, `memory`, `memoryDiff`. The `memory` and
|
||||
* `memoryDiff` values are available since version 2.0.11. This property is read-only.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Logger extends Component
|
||||
{
|
||||
/**
|
||||
* Error message level. An error message is one that indicates the abnormal termination of the
|
||||
* application and may require developer's handling.
|
||||
*/
|
||||
const LEVEL_ERROR = 0x01;
|
||||
/**
|
||||
* Warning message level. A warning message is one that indicates some abnormal happens but
|
||||
* the application is able to continue to run. Developers should pay attention to this message.
|
||||
*/
|
||||
const LEVEL_WARNING = 0x02;
|
||||
/**
|
||||
* Informational message level. An informational message is one that includes certain information
|
||||
* for developers to review.
|
||||
*/
|
||||
const LEVEL_INFO = 0x04;
|
||||
/**
|
||||
* Tracing message level. An tracing message is one that reveals the code execution flow.
|
||||
*/
|
||||
const LEVEL_TRACE = 0x08;
|
||||
/**
|
||||
* Profiling message level. This indicates the message is for profiling purpose.
|
||||
*/
|
||||
const LEVEL_PROFILE = 0x40;
|
||||
/**
|
||||
* Profiling message level. This indicates the message is for profiling purpose. It marks the
|
||||
* beginning of a profiling block.
|
||||
*/
|
||||
const LEVEL_PROFILE_BEGIN = 0x50;
|
||||
/**
|
||||
* Profiling message level. This indicates the message is for profiling purpose. It marks the
|
||||
* end of a profiling block.
|
||||
*/
|
||||
const LEVEL_PROFILE_END = 0x60;
|
||||
|
||||
/**
|
||||
* @var array logged messages. This property is managed by [[log()]] and [[flush()]].
|
||||
* Each log message is of the following structure:
|
||||
*
|
||||
* ```
|
||||
* [
|
||||
* [0] => message (mixed, can be a string or some complex data, such as an exception object)
|
||||
* [1] => level (integer)
|
||||
* [2] => category (string)
|
||||
* [3] => timestamp (float, obtained by microtime(true))
|
||||
* [4] => traces (array, debug backtrace, contains the application code call stacks)
|
||||
* [5] => memory usage in bytes (int, obtained by memory_get_usage()), available since version 2.0.11.
|
||||
* ]
|
||||
* ```
|
||||
*/
|
||||
public $messages = [];
|
||||
/**
|
||||
* @var int how many messages should be logged before they are flushed from memory and sent to targets.
|
||||
* Defaults to 1000, meaning the [[flush]] method will be invoked once every 1000 messages logged.
|
||||
* Set this property to be 0 if you don't want to flush messages until the application terminates.
|
||||
* This property mainly affects how much memory will be taken by the logged messages.
|
||||
* A smaller value means less memory, but will increase the execution time due to the overhead of [[flush()]].
|
||||
*/
|
||||
public $flushInterval = 1000;
|
||||
/**
|
||||
* @var int how much call stack information (file name and line number) should be logged for each message.
|
||||
* If it is greater than 0, at most that number of call stacks will be logged. Note that only application
|
||||
* call stacks are counted.
|
||||
*/
|
||||
public $traceLevel = 0;
|
||||
/**
|
||||
* @var Dispatcher the message dispatcher
|
||||
*/
|
||||
public $dispatcher;
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the logger by registering [[flush()]] as a shutdown function.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
register_shutdown_function(function () {
|
||||
// make regular flush before other shutdown functions, which allows session data collection and so on
|
||||
$this->flush();
|
||||
// make sure log entries written by shutdown functions are also flushed
|
||||
// ensure "flush()" is called last when there are multiple shutdown functions
|
||||
register_shutdown_function([$this, 'flush'], true);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a message with the given type and category.
|
||||
* If [[traceLevel]] is greater than 0, additional call stack information about
|
||||
* the application code will be logged as well.
|
||||
* @param string|array $message the message to be logged. This can be a simple string or a more
|
||||
* complex data structure that will be handled by a [[Target|log target]].
|
||||
* @param int $level the level of the message. This must be one of the following:
|
||||
* `Logger::LEVEL_ERROR`, `Logger::LEVEL_WARNING`, `Logger::LEVEL_INFO`, `Logger::LEVEL_TRACE`,
|
||||
* `Logger::LEVEL_PROFILE_BEGIN`, `Logger::LEVEL_PROFILE_END`.
|
||||
* @param string $category the category of the message.
|
||||
*/
|
||||
public function log($message, $level, $category = 'application')
|
||||
{
|
||||
$time = microtime(true);
|
||||
$traces = [];
|
||||
if ($this->traceLevel > 0) {
|
||||
$count = 0;
|
||||
$ts = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||
array_pop($ts); // remove the last trace since it would be the entry script, not very useful
|
||||
foreach ($ts as $trace) {
|
||||
if (isset($trace['file'], $trace['line']) && strpos($trace['file'], YII2_PATH) !== 0) {
|
||||
unset($trace['object'], $trace['args']);
|
||||
$traces[] = $trace;
|
||||
if (++$count >= $this->traceLevel) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->messages[] = [$message, $level, $category, $time, $traces, memory_get_usage()];
|
||||
if ($this->flushInterval > 0 && count($this->messages) >= $this->flushInterval) {
|
||||
$this->flush();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes log messages from memory to targets.
|
||||
* @param bool $final whether this is a final call during a request.
|
||||
*/
|
||||
public function flush($final = false)
|
||||
{
|
||||
$messages = $this->messages;
|
||||
// https://github.com/yiisoft/yii2/issues/5619
|
||||
// new messages could be logged while the existing ones are being handled by targets
|
||||
$this->messages = [];
|
||||
if ($this->dispatcher instanceof Dispatcher) {
|
||||
$this->dispatcher->dispatch($messages, $final);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total elapsed time since the start of the current request.
|
||||
* This method calculates the difference between now and the timestamp
|
||||
* defined by constant `YII_BEGIN_TIME` which is evaluated at the beginning
|
||||
* of [[\yii\BaseYii]] class file.
|
||||
* @return float the total elapsed time in seconds for current request.
|
||||
*/
|
||||
public function getElapsedTime()
|
||||
{
|
||||
return microtime(true) - YII_BEGIN_TIME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the profiling results.
|
||||
*
|
||||
* By default, all profiling results will be returned. You may provide
|
||||
* `$categories` and `$excludeCategories` as parameters to retrieve the
|
||||
* results that you are interested in.
|
||||
*
|
||||
* @param array $categories list of categories that you are interested in.
|
||||
* You can use an asterisk at the end of a category to do a prefix match.
|
||||
* For example, 'yii\db\*' will match categories starting with 'yii\db\',
|
||||
* such as 'yii\db\Connection'.
|
||||
* @param array $excludeCategories list of categories that you want to exclude
|
||||
* @return array the profiling results. Each element is an array consisting of these elements:
|
||||
* `info`, `category`, `timestamp`, `trace`, `level`, `duration`, `memory`, `memoryDiff`.
|
||||
* The `memory` and `memoryDiff` values are available since version 2.0.11.
|
||||
*/
|
||||
public function getProfiling($categories = [], $excludeCategories = [])
|
||||
{
|
||||
$timings = $this->calculateTimings($this->messages);
|
||||
if (empty($categories) && empty($excludeCategories)) {
|
||||
return $timings;
|
||||
}
|
||||
|
||||
foreach ($timings as $i => $timing) {
|
||||
$matched = empty($categories);
|
||||
foreach ($categories as $category) {
|
||||
$prefix = rtrim($category, '*');
|
||||
if (($timing['category'] === $category || $prefix !== $category) && strpos($timing['category'], $prefix) === 0) {
|
||||
$matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($matched) {
|
||||
foreach ($excludeCategories as $category) {
|
||||
$prefix = rtrim($category, '*');
|
||||
foreach ($timings as $i => $timing) {
|
||||
if (($timing['category'] === $category || $prefix !== $category) && strpos($timing['category'], $prefix) === 0) {
|
||||
$matched = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$matched) {
|
||||
unset($timings[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
return array_values($timings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the statistical results of DB queries.
|
||||
* The results returned include the number of SQL statements executed and
|
||||
* the total time spent.
|
||||
* @return array the first element indicates the number of SQL statements executed,
|
||||
* and the second element the total time spent in SQL execution.
|
||||
*/
|
||||
public function getDbProfiling()
|
||||
{
|
||||
$timings = $this->getProfiling(['yii\db\Command::query', 'yii\db\Command::execute']);
|
||||
$count = count($timings);
|
||||
$time = 0;
|
||||
foreach ($timings as $timing) {
|
||||
$time += $timing['duration'];
|
||||
}
|
||||
|
||||
return [$count, $time];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the elapsed time for the given log messages.
|
||||
* @param array $messages the log messages obtained from profiling
|
||||
* @return array timings. Each element is an array consisting of these elements:
|
||||
* `info`, `category`, `timestamp`, `trace`, `level`, `duration`, `memory`, `memoryDiff`.
|
||||
* The `memory` and `memoryDiff` values are available since version 2.0.11.
|
||||
*/
|
||||
public function calculateTimings($messages)
|
||||
{
|
||||
$timings = [];
|
||||
$stack = [];
|
||||
|
||||
foreach ($messages as $i => $log) {
|
||||
list($token, $level, $category, $timestamp, $traces) = $log;
|
||||
$memory = isset($log[5]) ? $log[5] : 0;
|
||||
$log[6] = $i;
|
||||
$hash = md5(json_encode($token));
|
||||
if ($level == self::LEVEL_PROFILE_BEGIN) {
|
||||
$stack[$hash] = $log;
|
||||
} elseif ($level == self::LEVEL_PROFILE_END) {
|
||||
if (isset($stack[$hash])) {
|
||||
$timings[$stack[$hash][6]] = [
|
||||
'info' => $stack[$hash][0],
|
||||
'category' => $stack[$hash][2],
|
||||
'timestamp' => $stack[$hash][3],
|
||||
'trace' => $stack[$hash][4],
|
||||
'level' => count($stack) - 1,
|
||||
'duration' => $timestamp - $stack[$hash][3],
|
||||
'memory' => $memory,
|
||||
'memoryDiff' => $memory - (isset($stack[$hash][5]) ? $stack[$hash][5] : 0),
|
||||
];
|
||||
unset($stack[$hash]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ksort($timings);
|
||||
|
||||
return array_values($timings);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the text display of the specified level.
|
||||
* @param int $level the message level, e.g. [[LEVEL_ERROR]], [[LEVEL_WARNING]].
|
||||
* @return string the text display of the level
|
||||
*/
|
||||
public static function getLevelName($level)
|
||||
{
|
||||
static $levels = [
|
||||
self::LEVEL_ERROR => 'error',
|
||||
self::LEVEL_WARNING => 'warning',
|
||||
self::LEVEL_INFO => 'info',
|
||||
self::LEVEL_TRACE => 'trace',
|
||||
self::LEVEL_PROFILE_BEGIN => 'profile begin',
|
||||
self::LEVEL_PROFILE_END => 'profile end',
|
||||
self::LEVEL_PROFILE => 'profile',
|
||||
];
|
||||
|
||||
return isset($levels[$level]) ? $levels[$level] : 'unknown';
|
||||
}
|
||||
}
|
||||
97
vendor/yiisoft/yii2/log/SyslogTarget.php
vendored
Normal file
97
vendor/yiisoft/yii2/log/SyslogTarget.php
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\log;
|
||||
|
||||
use Yii;
|
||||
use yii\helpers\VarDumper;
|
||||
|
||||
/**
|
||||
* SyslogTarget writes log to syslog.
|
||||
*
|
||||
* @author miramir <gmiramir@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class SyslogTarget extends Target
|
||||
{
|
||||
/**
|
||||
* @var string syslog identity
|
||||
*/
|
||||
public $identity;
|
||||
/**
|
||||
* @var int syslog facility.
|
||||
*/
|
||||
public $facility = LOG_USER;
|
||||
/**
|
||||
* @var int openlog options. This is a bitfield passed as the `$option` parameter to [openlog()](http://php.net/openlog).
|
||||
* Defaults to `null` which means to use the default options `LOG_ODELAY | LOG_PID`.
|
||||
* @see http://php.net/openlog for available options.
|
||||
* @since 2.0.11
|
||||
*/
|
||||
public $options;
|
||||
|
||||
/**
|
||||
* @var array syslog levels
|
||||
*/
|
||||
private $_syslogLevels = [
|
||||
Logger::LEVEL_TRACE => LOG_DEBUG,
|
||||
Logger::LEVEL_PROFILE_BEGIN => LOG_DEBUG,
|
||||
Logger::LEVEL_PROFILE_END => LOG_DEBUG,
|
||||
Logger::LEVEL_PROFILE => LOG_DEBUG,
|
||||
Logger::LEVEL_INFO => LOG_INFO,
|
||||
Logger::LEVEL_WARNING => LOG_WARNING,
|
||||
Logger::LEVEL_ERROR => LOG_ERR,
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
if ($this->options === null) {
|
||||
$this->options = LOG_ODELAY | LOG_PID;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes log messages to syslog.
|
||||
* Starting from version 2.0.14, this method throws LogRuntimeException in case the log can not be exported.
|
||||
* @throws LogRuntimeException
|
||||
*/
|
||||
public function export()
|
||||
{
|
||||
openlog($this->identity, $this->options, $this->facility);
|
||||
foreach ($this->messages as $message) {
|
||||
if (syslog($this->_syslogLevels[$message[1]], $this->formatMessage($message)) === false) {
|
||||
throw new LogRuntimeException('Unable to export log through system log!');
|
||||
}
|
||||
}
|
||||
closelog();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatMessage($message)
|
||||
{
|
||||
list($text, $level, $category, $timestamp) = $message;
|
||||
$level = Logger::getLevelName($level);
|
||||
if (!is_string($text)) {
|
||||
// exceptions may not be serializable if in the call stack somewhere is a Closure
|
||||
if ($text instanceof \Throwable || $text instanceof \Exception) {
|
||||
$text = (string) $text;
|
||||
} else {
|
||||
$text = VarDumper::export($text);
|
||||
}
|
||||
}
|
||||
|
||||
$prefix = $this->getMessagePrefix($message);
|
||||
return "{$prefix}[$level][$category] $text";
|
||||
}
|
||||
}
|
||||
371
vendor/yiisoft/yii2/log/Target.php
vendored
Normal file
371
vendor/yiisoft/yii2/log/Target.php
vendored
Normal file
@@ -0,0 +1,371 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\log;
|
||||
|
||||
use Yii;
|
||||
use yii\base\Component;
|
||||
use yii\base\InvalidConfigException;
|
||||
use yii\helpers\ArrayHelper;
|
||||
use yii\helpers\StringHelper;
|
||||
use yii\helpers\VarDumper;
|
||||
use yii\web\Request;
|
||||
|
||||
/**
|
||||
* Target is the base class for all log target classes.
|
||||
*
|
||||
* A log target object will filter the messages logged by [[Logger]] according
|
||||
* to its [[levels]] and [[categories]] properties. It may also export the filtered
|
||||
* messages to specific destination defined by the target, such as emails, files.
|
||||
*
|
||||
* Level filter and category filter are combinatorial, i.e., only messages
|
||||
* satisfying both filter conditions will be handled. Additionally, you
|
||||
* may specify [[except]] to exclude messages of certain categories.
|
||||
*
|
||||
* @property bool $enabled Indicates whether this log target is enabled. Defaults to true. Note that the type
|
||||
* of this property differs in getter and setter. See [[getEnabled()]] and [[setEnabled()]] for details.
|
||||
* @property int $levels The message levels that this target is interested in. This is a bitmap of level
|
||||
* values. Defaults to 0, meaning all available levels. Note that the type of this property differs in getter
|
||||
* and setter. See [[getLevels()]] and [[setLevels()]] for details.
|
||||
*
|
||||
* For more details and usage information on Target, see the [guide article on logging & targets](guide:runtime-logging).
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
abstract class Target extends Component
|
||||
{
|
||||
/**
|
||||
* @var array list of message categories that this target is interested in. Defaults to empty, meaning all categories.
|
||||
* You can use an asterisk at the end of a category so that the category may be used to
|
||||
* match those categories sharing the same common prefix. For example, 'yii\db\*' will match
|
||||
* categories starting with 'yii\db\', such as 'yii\db\Connection'.
|
||||
*/
|
||||
public $categories = [];
|
||||
/**
|
||||
* @var array list of message categories that this target is NOT interested in. Defaults to empty, meaning no uninteresting messages.
|
||||
* If this property is not empty, then any category listed here will be excluded from [[categories]].
|
||||
* You can use an asterisk at the end of a category so that the category can be used to
|
||||
* match those categories sharing the same common prefix. For example, 'yii\db\*' will match
|
||||
* categories starting with 'yii\db\', such as 'yii\db\Connection'.
|
||||
* @see categories
|
||||
*/
|
||||
public $except = [];
|
||||
/**
|
||||
* @var array list of the PHP predefined variables that should be logged in a message.
|
||||
* Note that a variable must be accessible via `$GLOBALS`. Otherwise it won't be logged.
|
||||
*
|
||||
* Defaults to `['_GET', '_POST', '_FILES', '_COOKIE', '_SESSION', '_SERVER']`.
|
||||
*
|
||||
* Since version 2.0.9 additional syntax can be used:
|
||||
* Each element could be specified as one of the following:
|
||||
*
|
||||
* - `var` - `var` will be logged.
|
||||
* - `var.key` - only `var[key]` key will be logged.
|
||||
* - `!var.key` - `var[key]` key will be excluded.
|
||||
*
|
||||
* Note that if you need $_SESSION to logged regardless if session was used you have to open it right at
|
||||
* the start of your request.
|
||||
*
|
||||
* @see \yii\helpers\ArrayHelper::filter()
|
||||
*/
|
||||
public $logVars = ['_GET', '_POST', '_FILES', '_COOKIE', '_SESSION', '_SERVER'];
|
||||
/**
|
||||
* @var callable a PHP callable that returns a string to be prefixed to every exported message.
|
||||
*
|
||||
* If not set, [[getMessagePrefix()]] will be used, which prefixes the message with context information
|
||||
* such as user IP, user ID and session ID.
|
||||
*
|
||||
* The signature of the callable should be `function ($message)`.
|
||||
*/
|
||||
public $prefix;
|
||||
/**
|
||||
* @var int how many messages should be accumulated before they are exported.
|
||||
* Defaults to 1000. Note that messages will always be exported when the application terminates.
|
||||
* Set this property to be 0 if you don't want to export messages until the application terminates.
|
||||
*/
|
||||
public $exportInterval = 1000;
|
||||
/**
|
||||
* @var array the messages that are retrieved from the logger so far by this log target.
|
||||
* Please refer to [[Logger::messages]] for the details about the message structure.
|
||||
*/
|
||||
public $messages = [];
|
||||
/**
|
||||
* @var bool whether to log time with microseconds.
|
||||
* Defaults to false.
|
||||
* @since 2.0.13
|
||||
*/
|
||||
public $microtime = false;
|
||||
|
||||
private $_levels = 0;
|
||||
private $_enabled = true;
|
||||
|
||||
|
||||
/**
|
||||
* Exports log [[messages]] to a specific destination.
|
||||
* Child classes must implement this method.
|
||||
*/
|
||||
abstract public function export();
|
||||
|
||||
/**
|
||||
* Processes the given log messages.
|
||||
* This method will filter the given messages with [[levels]] and [[categories]].
|
||||
* And if requested, it will also export the filtering result to specific medium (e.g. email).
|
||||
* @param array $messages log messages to be processed. See [[Logger::messages]] for the structure
|
||||
* of each message.
|
||||
* @param bool $final whether this method is called at the end of the current application
|
||||
*/
|
||||
public function collect($messages, $final)
|
||||
{
|
||||
$this->messages = array_merge($this->messages, static::filterMessages($messages, $this->getLevels(), $this->categories, $this->except));
|
||||
$count = count($this->messages);
|
||||
if ($count > 0 && ($final || $this->exportInterval > 0 && $count >= $this->exportInterval)) {
|
||||
if (($context = $this->getContextMessage()) !== '') {
|
||||
$this->messages[] = [$context, Logger::LEVEL_INFO, 'application', YII_BEGIN_TIME];
|
||||
}
|
||||
// set exportInterval to 0 to avoid triggering export again while exporting
|
||||
$oldExportInterval = $this->exportInterval;
|
||||
$this->exportInterval = 0;
|
||||
$this->export();
|
||||
$this->exportInterval = $oldExportInterval;
|
||||
|
||||
$this->messages = [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the context information to be logged.
|
||||
* The default implementation will dump user information, system variables, etc.
|
||||
* @return string the context information. If an empty string, it means no context information.
|
||||
*/
|
||||
protected function getContextMessage()
|
||||
{
|
||||
$context = ArrayHelper::filter($GLOBALS, $this->logVars);
|
||||
$result = [];
|
||||
foreach ($context as $key => $value) {
|
||||
$result[] = "\${$key} = " . VarDumper::dumpAsString($value);
|
||||
}
|
||||
|
||||
return implode("\n\n", $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int the message levels that this target is interested in. This is a bitmap of
|
||||
* level values. Defaults to 0, meaning all available levels.
|
||||
*/
|
||||
public function getLevels()
|
||||
{
|
||||
return $this->_levels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the message levels that this target is interested in.
|
||||
*
|
||||
* The parameter can be either an array of interested level names or an integer representing
|
||||
* the bitmap of the interested level values. Valid level names include: 'error',
|
||||
* 'warning', 'info', 'trace' and 'profile'; valid level values include:
|
||||
* [[Logger::LEVEL_ERROR]], [[Logger::LEVEL_WARNING]], [[Logger::LEVEL_INFO]],
|
||||
* [[Logger::LEVEL_TRACE]] and [[Logger::LEVEL_PROFILE]].
|
||||
*
|
||||
* For example,
|
||||
*
|
||||
* ```php
|
||||
* ['error', 'warning']
|
||||
* // which is equivalent to:
|
||||
* Logger::LEVEL_ERROR | Logger::LEVEL_WARNING
|
||||
* ```
|
||||
*
|
||||
* @param array|int $levels message levels that this target is interested in.
|
||||
* @throws InvalidConfigException if $levels value is not correct.
|
||||
*/
|
||||
public function setLevels($levels)
|
||||
{
|
||||
static $levelMap = [
|
||||
'error' => Logger::LEVEL_ERROR,
|
||||
'warning' => Logger::LEVEL_WARNING,
|
||||
'info' => Logger::LEVEL_INFO,
|
||||
'trace' => Logger::LEVEL_TRACE,
|
||||
'profile' => Logger::LEVEL_PROFILE,
|
||||
];
|
||||
if (is_array($levels)) {
|
||||
$this->_levels = 0;
|
||||
foreach ($levels as $level) {
|
||||
if (isset($levelMap[$level])) {
|
||||
$this->_levels |= $levelMap[$level];
|
||||
} else {
|
||||
throw new InvalidConfigException("Unrecognized level: $level");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$bitmapValues = array_reduce($levelMap, function ($carry, $item) {
|
||||
return $carry | $item;
|
||||
});
|
||||
if (!($bitmapValues & $levels) && $levels !== 0) {
|
||||
throw new InvalidConfigException("Incorrect $levels value");
|
||||
}
|
||||
$this->_levels = $levels;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the given messages according to their categories and levels.
|
||||
* @param array $messages messages to be filtered.
|
||||
* The message structure follows that in [[Logger::messages]].
|
||||
* @param int $levels the message levels to filter by. This is a bitmap of
|
||||
* level values. Value 0 means allowing all levels.
|
||||
* @param array $categories the message categories to filter by. If empty, it means all categories are allowed.
|
||||
* @param array $except the message categories to exclude. If empty, it means all categories are allowed.
|
||||
* @return array the filtered messages.
|
||||
*/
|
||||
public static function filterMessages($messages, $levels = 0, $categories = [], $except = [])
|
||||
{
|
||||
foreach ($messages as $i => $message) {
|
||||
if ($levels && !($levels & $message[1])) {
|
||||
unset($messages[$i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$matched = empty($categories);
|
||||
foreach ($categories as $category) {
|
||||
if ($message[2] === $category || !empty($category) && substr_compare($category, '*', -1, 1) === 0 && strpos($message[2], rtrim($category, '*')) === 0) {
|
||||
$matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($matched) {
|
||||
foreach ($except as $category) {
|
||||
$prefix = rtrim($category, '*');
|
||||
if (($message[2] === $category || $prefix !== $category) && strpos($message[2], $prefix) === 0) {
|
||||
$matched = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$matched) {
|
||||
unset($messages[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a log message for display as a string.
|
||||
* @param array $message the log message to be formatted.
|
||||
* The message structure follows that in [[Logger::messages]].
|
||||
* @return string the formatted message
|
||||
*/
|
||||
public function formatMessage($message)
|
||||
{
|
||||
list($text, $level, $category, $timestamp) = $message;
|
||||
$level = Logger::getLevelName($level);
|
||||
if (!is_string($text)) {
|
||||
// exceptions may not be serializable if in the call stack somewhere is a Closure
|
||||
if ($text instanceof \Throwable || $text instanceof \Exception) {
|
||||
$text = (string) $text;
|
||||
} else {
|
||||
$text = VarDumper::export($text);
|
||||
}
|
||||
}
|
||||
$traces = [];
|
||||
if (isset($message[4])) {
|
||||
foreach ($message[4] as $trace) {
|
||||
$traces[] = "in {$trace['file']}:{$trace['line']}";
|
||||
}
|
||||
}
|
||||
|
||||
$prefix = $this->getMessagePrefix($message);
|
||||
return $this->getTime($timestamp) . " {$prefix}[$level][$category] $text"
|
||||
. (empty($traces) ? '' : "\n " . implode("\n ", $traces));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string to be prefixed to the given message.
|
||||
* If [[prefix]] is configured it will return the result of the callback.
|
||||
* The default implementation will return user IP, user ID and session ID as a prefix.
|
||||
* @param array $message the message being exported.
|
||||
* The message structure follows that in [[Logger::messages]].
|
||||
* @return string the prefix string
|
||||
*/
|
||||
public function getMessagePrefix($message)
|
||||
{
|
||||
if ($this->prefix !== null) {
|
||||
return call_user_func($this->prefix, $message);
|
||||
}
|
||||
|
||||
if (Yii::$app === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$request = Yii::$app->getRequest();
|
||||
$ip = $request instanceof Request ? $request->getUserIP() : '-';
|
||||
|
||||
/* @var $user \yii\web\User */
|
||||
$user = Yii::$app->has('user', true) ? Yii::$app->get('user') : null;
|
||||
if ($user && ($identity = $user->getIdentity(false))) {
|
||||
$userID = $identity->getId();
|
||||
} else {
|
||||
$userID = '-';
|
||||
}
|
||||
|
||||
/* @var $session \yii\web\Session */
|
||||
$session = Yii::$app->has('session', true) ? Yii::$app->get('session') : null;
|
||||
$sessionID = $session && $session->getIsActive() ? $session->getId() : '-';
|
||||
|
||||
return "[$ip][$userID][$sessionID]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a value indicating whether this log target is enabled.
|
||||
* @param bool|callable $value a boolean value or a callable to obtain the value from.
|
||||
* The callable value is available since version 2.0.13.
|
||||
*
|
||||
* A callable may be used to determine whether the log target should be enabled in a dynamic way.
|
||||
* For example, to only enable a log if the current user is logged in you can configure the target
|
||||
* as follows:
|
||||
*
|
||||
* ```php
|
||||
* 'enabled' => function() {
|
||||
* return !Yii::$app->user->isGuest;
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
public function setEnabled($value)
|
||||
{
|
||||
$this->_enabled = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the log target is enabled.
|
||||
* @property bool Indicates whether this log target is enabled. Defaults to true.
|
||||
* @return bool A value indicating whether this log target is enabled.
|
||||
*/
|
||||
public function getEnabled()
|
||||
{
|
||||
if (is_callable($this->_enabled)) {
|
||||
return call_user_func($this->_enabled, $this);
|
||||
}
|
||||
|
||||
return $this->_enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns formatted ('Y-m-d H:i:s') timestamp for message.
|
||||
* If [[microtime]] is configured to true it will return format 'Y-m-d H:i:s.u'.
|
||||
* @param float $timestamp
|
||||
* @return string
|
||||
* @since 2.0.13
|
||||
*/
|
||||
protected function getTime($timestamp)
|
||||
{
|
||||
$parts = explode('.', StringHelper::floatToString($timestamp));
|
||||
|
||||
return date('Y-m-d H:i:s', $parts[0]) . ($this->microtime && isset($parts[1]) ? ('.' . $parts[1]) : '');
|
||||
}
|
||||
}
|
||||
94
vendor/yiisoft/yii2/log/migrations/m141106_185632_log_init.php
vendored
Normal file
94
vendor/yiisoft/yii2/log/migrations/m141106_185632_log_init.php
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
use yii\base\InvalidConfigException;
|
||||
use yii\db\Migration;
|
||||
use yii\log\DbTarget;
|
||||
|
||||
/**
|
||||
* Initializes log table.
|
||||
*
|
||||
* The indexes declared 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 additional indexes (e.g. index on `log_time`).
|
||||
*
|
||||
* @author Alexander Makarov <sam@rmcreative.ru>
|
||||
* @since 2.0.1
|
||||
*/
|
||||
class m141106_185632_log_init extends Migration
|
||||
{
|
||||
/**
|
||||
* @var DbTarget[] Targets to create log table for
|
||||
*/
|
||||
private $dbTargets = [];
|
||||
|
||||
/**
|
||||
* @throws InvalidConfigException
|
||||
* @return DbTarget[]
|
||||
*/
|
||||
protected function getDbTargets()
|
||||
{
|
||||
if ($this->dbTargets === []) {
|
||||
$log = Yii::$app->getLog();
|
||||
|
||||
$usedTargets = [];
|
||||
foreach ($log->targets as $target) {
|
||||
if ($target instanceof DbTarget) {
|
||||
$currentTarget = [
|
||||
$target->db,
|
||||
$target->logTable,
|
||||
];
|
||||
if (!in_array($currentTarget, $usedTargets, true)) {
|
||||
// do not create same table twice
|
||||
$usedTargets[] = $currentTarget;
|
||||
$this->dbTargets[] = $target;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->dbTargets === []) {
|
||||
throw new InvalidConfigException('You should configure "log" component to use one or more database targets before executing this migration.');
|
||||
}
|
||||
}
|
||||
|
||||
return $this->dbTargets;
|
||||
}
|
||||
|
||||
public function up()
|
||||
{
|
||||
foreach ($this->getDbTargets() as $target) {
|
||||
$this->db = $target->db;
|
||||
|
||||
$tableOptions = null;
|
||||
if ($this->db->driverName === 'mysql') {
|
||||
// http://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci
|
||||
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB';
|
||||
}
|
||||
|
||||
$this->createTable($target->logTable, [
|
||||
'id' => $this->bigPrimaryKey(),
|
||||
'level' => $this->integer(),
|
||||
'category' => $this->string(),
|
||||
'log_time' => $this->double(),
|
||||
'prefix' => $this->text(),
|
||||
'message' => $this->text(),
|
||||
], $tableOptions);
|
||||
|
||||
$this->createIndex('idx_log_level', $target->logTable, 'level');
|
||||
$this->createIndex('idx_log_category', $target->logTable, 'category');
|
||||
}
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
foreach ($this->getDbTargets() as $target) {
|
||||
$this->db = $target->db;
|
||||
|
||||
$this->dropTable($target->logTable);
|
||||
}
|
||||
}
|
||||
}
|
||||
29
vendor/yiisoft/yii2/log/migrations/schema-mssql.sql
vendored
Normal file
29
vendor/yiisoft/yii2/log/migrations/schema-mssql.sql
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Database schema required by \yii\log\DbTarget.
|
||||
*
|
||||
* The indexes declared 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 additional indexes (e.g. index on `log_time`).
|
||||
*
|
||||
* @author Alexander Makarov <sam@rmcreative.ru>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
* @since 2.0.1
|
||||
*/
|
||||
|
||||
if object_id('[log]', 'U') is not null
|
||||
drop table [log];
|
||||
|
||||
create table [log]
|
||||
(
|
||||
[id] bigint IDENTITY PRIMARY KEY,
|
||||
[level] integer,
|
||||
[category] varchar(255),
|
||||
[log_time] float,
|
||||
[prefix] text,
|
||||
[message] text
|
||||
);
|
||||
|
||||
create index [idx_log_level] on [log] ([level]);
|
||||
create index [idx_log_category] on [log] ([category]);
|
||||
27
vendor/yiisoft/yii2/log/migrations/schema-mysql.sql
vendored
Normal file
27
vendor/yiisoft/yii2/log/migrations/schema-mysql.sql
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Database schema required by \yii\log\DbTarget.
|
||||
*
|
||||
* The indexes declared 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 additional indexes (e.g. index on `log_time`).
|
||||
*
|
||||
* @author Alexander Makarov <sam@rmcreative.ru>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
* @since 2.0.1
|
||||
*/
|
||||
|
||||
drop table if exists `log`;
|
||||
|
||||
create table `log`
|
||||
(
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
`level` integer,
|
||||
`category` varchar(255),
|
||||
`log_time` double,
|
||||
`prefix` text,
|
||||
`message` text,
|
||||
key `idx_log_level` (`level`),
|
||||
key `idx_log_category` (`category`)
|
||||
) engine InnoDB;
|
||||
27
vendor/yiisoft/yii2/log/migrations/schema-oci.sql
vendored
Normal file
27
vendor/yiisoft/yii2/log/migrations/schema-oci.sql
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Database schema required by \yii\log\DbTarget.
|
||||
*
|
||||
* The indexes declared 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 additional indexes (e.g. index on `log_time`).
|
||||
*
|
||||
* @author Alexander Makarov <sam@rmcreative.ru>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
* @since 2.0.1
|
||||
*/
|
||||
|
||||
drop table if exists "log";
|
||||
|
||||
create table "log"
|
||||
(
|
||||
"id" number(20) NOT NULL PRIMARY KEY,
|
||||
"level" integer,
|
||||
"category" varchar(255),
|
||||
"log_time" number,
|
||||
"prefix" text,
|
||||
"message" text,
|
||||
key "idx_log_level" ("level"),
|
||||
key "idx_log_category" ("category")
|
||||
);
|
||||
28
vendor/yiisoft/yii2/log/migrations/schema-pgsql.sql
vendored
Normal file
28
vendor/yiisoft/yii2/log/migrations/schema-pgsql.sql
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Database schema required by \yii\log\DbTarget.
|
||||
*
|
||||
* The indexes declared 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 additional indexes (e.g. index on `log_time`).
|
||||
*
|
||||
* @author Alexander Makarov <sam@rmcreative.ru>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
* @since 2.0.1
|
||||
*/
|
||||
|
||||
drop table if exists "log";
|
||||
|
||||
create table "log"
|
||||
(
|
||||
"id" bigserial NOT NULL PRIMARY KEY,
|
||||
"level" integer,
|
||||
"category" varchar(255),
|
||||
"log_time" double precision,
|
||||
"prefix" text,
|
||||
"message" text
|
||||
);
|
||||
|
||||
create index "idx_log_level" on "log" ("level");
|
||||
create index "idx_log_category" on "log" ("category");
|
||||
28
vendor/yiisoft/yii2/log/migrations/schema-sqlite.sql
vendored
Normal file
28
vendor/yiisoft/yii2/log/migrations/schema-sqlite.sql
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Database schema required by \yii\log\DbTarget.
|
||||
*
|
||||
* The indexes declared 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 additional indexes (e.g. index on `log_time`).
|
||||
*
|
||||
* @author Alexander Makarov <sam@rmcreative.ru>
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
* @since 2.0.1
|
||||
*/
|
||||
|
||||
drop table if exists "log";
|
||||
|
||||
create table "log"
|
||||
(
|
||||
"id" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
"level" integer,
|
||||
"category" varchar(255),
|
||||
"log_time" double,
|
||||
"prefix" text,
|
||||
"message" text
|
||||
);
|
||||
|
||||
create index "idx_log_level" on "log" ("level");
|
||||
create index "idx_log_category" on "log" ("category");
|
||||
Reference in New Issue
Block a user