设置Yii的错误日志,可按照设置错误级别输入到日志或数据库中。
对yii\log\FileTarget做了重写。
1、设置common/config/main.php
$db = require(__DIR__ . '/db.php');
return [
'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
'bootstrap' => ['log'],
'components' => [
'cache' => [
'class' => 'yii\caching\FileCache',
],
'db' => $db,
'log' => [
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning', 'info'],
],
[
// 'class' => 'yii\log\FileTarget',
'class' => 'app\common\components\FileTarget',
'levels' => ['error'],
'logFile' => '@runtime/logs/error.log',
],//日志入库
],
],
],
'timeZone' => 'Asia/Shanghai',
];
2、app\common\components\FileTarget
<?php
namespace app\common\components;
use yii\helpers\VarDumper;
use yii\log;
class FileTarget extends log\FileTarget
{
public function export()
{
parent::export(); // TODO: Change the autogenerated stub
//调用接口将数据入库 默认是收集错误日志
if (empty(\Yii::$app->params['errorLog']['switch'])) {//设置参数是否收集错误日志
$flag = false;
if (empty($_SERVER['DOCUMENT_ROOT'])) {
$projectName = '';
$entrance = 'console';
$flag = true;
} else {
$document_root = explode('/', $_SERVER['DOCUMENT_ROOT']);
$projectName = $document_root[count($document_root) - 3];//项目名称
$entrance = $document_root[count($document_root) - 2];//项目入口
}
$params = $_POST ?: $_GET;
$errList = [];
foreach ($this->messages as $message) {
list($text, $level, $category, $timestamp) = $message;
if ($level <> 4) {
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 ($flag) {
$dir1 = '/var/www/html/';
$start = strpos($text, $dir1);
if (!$start) {
$dir1 = '/disk/html/';
$start = strpos($text, $dir1);
$project = substr($text, $start + strlen($dir1), 50);
$project = explode('/', $project);
$projectName = $project[0];
} else {
$project = substr($text, $start + strlen($dir1), 50);
$project = explode('/', $project);
$projectName = $project[0];
}
}
$text = $text . "\n" . "params:" . json_encode($params);
$errType = 'error';
if (stripos($category, 'db')) {
$errType = 'db';
} else if (stripos($text, 'Redis')) {
$errType = 'redis';
}
$item = [];
$item[] = empty($projectName) ? '0' : $projectName;//项目
$item[] = empty($entrance) ? '0' : $entrance;//入口
$item[] = empty($_SERVER['SERVER_NAME']) ? '0' : $_SERVER['SERVER_NAME'];
$item[] = $level;
$item[] = $category;
$item[] = $timestamp;
$item[] = $this->getMessagePrefix($message);
$item[] = IPUtils::get_local_ip();
$item[] = empty($_SERVER['REQUEST_URI']) ? '0' : $_SERVER['REQUEST_URI'];
$item[] = $errType;
$item[] = $text;//错误信息
$errList[] = $item;
}
}
//请求接口入库
$this->collectErrorLog($errList);
}
}
/**
* @param $data
* @return mixed
* 错误日志入库
*/
private function collectErrorLog($data)
{
if (empty(\Yii::$app->params['errorLog']['logApiDomain'])) {
if (YII_ENV == 'local' || YII_ENV == 'dev') {
$url = 'http://dev.api.log.3ttech.cn/inner/collect-error-log?';
} else {
$url = 'http://api.log.3ttech.cn/inner/collect-error-log?';
}
} else {
$url = \Yii::$app->params['errorLog']['logApiDomain'] . '/inner/collect-error-log?';
}
$requestBody = [
'data' => $data,
];
$url .= http_build_query($requestBody);
$response = json_decode(AHelper::curl_get($url), true);
return $response;
}
}
3、数据表的结构如下:
表字段可按照yii2框架中的字段调整设置。
CREATE TABLE `t_user_logs` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`project` varchar(100) NOT NULL DEFAULT '' COMMENT '项目名称',
`entrance` varchar(20) NOT NULL DEFAULT '' COMMENT '入口',
`address` varchar(50) NOT NULL DEFAULT '' COMMENT '访问域名',
`level` varchar(200) NOT NULL DEFAULT '' COMMENT '错误级别',
`category` varchar(200) NOT NULL DEFAULT '' COMMENT '类别',
`log_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '日志时间',
`prefix` varchar(200) NOT NULL DEFAULT '' COMMENT '前缀',
`suffix` varchar(200) NOT NULL DEFAULT '' COMMENT '报错服务器ip',
`request_uri` varchar(100) NOT NULL DEFAULT '' COMMENT '请求路由',
`errType` varchar(20) NOT NULL DEFAULT '4' COMMENT '错误类型',
`message` text NOT NULL COMMENT '消息',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=100001 DEFAULT CHARSET=utf8;