现在,我正在yii2上开发一个项目,除了记录器中可用的级别之外,还出现了添加更多致命和关键任务的任务。
实际上,我重新定义了logger.php并开始重新定义Yii.php,但是它拉扯了供应商内部的许多依赖关系,并且错误开始出现:
致命错误:未捕获的错误:在/app/vendor/yiisoft/yii2/base/Module.php:183中找不到类'Yii'堆栈跟踪:#0 /app/components/Application.php(14):yii \ base \ Module :: setInstance(Object(app \ components \ Application))#1 /app/web/index.php(16):app \ components \ Application-> __ construct(Array)#2 {main}放在/ 183行上的app / vendor / yiisoft / yii2 / base / Module.php
记录器
class Logger extends \yii\log\Logger
{
/**
* Critical message level. An tracing message is one that reveals the code execution flow.
*/
const LEVEL_CRITICAL = 0x12;
/**
* Fatal message level. An tracing message is one that reveals the code execution flow.
*/
const LEVEL_FATAL = 0x16;
/**
* 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_CRITICAL => 'critical',
self::LEVEL_FATAL => 'fatal',
self::LEVEL_PROFILE_BEGIN => 'profile begin',
self::LEVEL_PROFILE_END => 'profile end',
self::LEVEL_PROFILE => 'profile',
];
return isset($levels[$level]) ? $levels[$level] : 'unknown';
}
}
yii.php
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require __DIR__ . '/vendor/autoload.php';
require __DIR__ . '/components/Yii.php';
$config = require __DIR__ . '/config/console.php';
$application = new yii\console\Application($config);
$exitCode = $application->run();
exit($exitCode);
Yii.php
<?php
namespace app\components;
use app\components\Logger;
use yii\di\Container;
class Yii extends \yii\BaseYii
{
private static $_logger;
/**
* @return Logger message logger
*/
public static function getLogger()
{
if (self::$_logger !== null) {
return self::$_logger;
}
return self::$_logger = static::createObject('app\components\Logger');
}
/**
* Sets the logger object.
* @param Logger $logger the logger object.
*/
public static function setLogger($logger)
{
self::$_logger = $logger;
}
public static function critical($message, $category = 'application')
{
static::getLogger()->log($message, Logger::LEVEL_CRITICAL, $category);
}
public static function fatal($message, $category = 'application')
{
static::getLogger()->log($message, Logger::LEVEL_FATAL, $category);
}
}
spl_autoload_register(['app\components\Yii', 'autoload'], true, true);
Yii::$classMap = require __DIR__ . '/../vendor/yiisoft/yii2/classes.php';
Yii::$container = new Container();
是否可以使其变得更简单,以免使用它重新定义每个组件的路径?
答案 0 :(得分:3)
使用您的实现覆盖\ yii \ log \ logger,以添加更多级别。您已经完成了此操作,因此我将跳过记录器代码。
namespace app\components;
class MyLogger extends \yii\log\Logger
{
...
}
覆盖日志目标,以便它可以处理您的额外级别
namespace app\components;
use \yii\log\Logger;
use \yii\helpers\VarDumper;
class MyFileTarget extends \yii\log\FileTarget
{
private $_levels = 0;
public function getLevels()
{
return $this->_levels;
}
public function setLevels($levels)
{
static $levelMap = [
'error' => Logger::LEVEL_ERROR,
'warning' => Logger::LEVEL_WARNING,
'info' => Logger::LEVEL_INFO,
'trace' => Logger::LEVEL_TRACE,
'critical' => MyLogger::LEVEL_CRITICAL,
'fatal' => MyLogger::LEVEL_FATAL,
'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;
}
}
public function formatMessage($message)
{
list($text, $level, $category, $timestamp) = $message;
$level = MyLogger::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));
}
}
在组件配置中设置日志分派器以使用记录器和目标
...
'components' => [
...
'log' => [
'logger' => \app\components\MyLogger::class,
'targets' => [
[
'class' => \app\components\MyFileTarget::class,
'levels' => ['fatal', 'critical'],
'categories' => ['app\*'],
'file' => '@runtime/logs/critical.log',
],
],
],
...
],
...
More info about log configuration
然后通过日志组件而不是别名Yii::error()
来调用记录器
Yii::$app->log->getLogger()->log('msg', MyLogger::LEVEL_CRITICAL, __METHOD__);
或者您可以为类似于这些别名的呼叫创建自己的助手。