Yii使用DbTarget实现日志功能的示例代码

2020-09-01 10:38:01

一:在配置文件的log组件中配置DbTarget

Yii使用DbTarget实现日志功能的示例代码

'log' => [ 'traceLevel' => YII_DEBUG ? 3 : 0, 'targets' => [  [   'class' => 'yiilogFileTarget',   'levels' => ['error', 'warning'],  ],  'test' => [   'class' => 'yiilogDbTarget',//DaTarget类   'logTable' => '{{%test_log}}',//日志表   'levels' => ['error', 'info', 'warning'],//日志等级  ], ],],

二:生成日志表

在项目目录下执行如下命令生成日志表

php yii migrate --migrationPath=@yii/log/migrations/

三:使用日志

在需要使用日志的地方使用

Yii::info()

四:自定义DbTarget日志

1:首先创建一个自定义的日志表

(1)在项目目录下执行

php yii migrate/create create_test_log

(2):在创建的migrate文件下编写创建数据库的迁移脚本

<?phpuse yiidbMigration;/** * Class m200720_091126_create_test_log */class m200720_091126_create_test_log extends Migration{ /**  * {@inheritdoc}  */ public function safeUp() {  $this->createTable('{{%test_log}}', [   'id' => $this->bigPrimaryKey(),   'level' => $this->integer()->notNull()->comment('日志等级'),   'category' => $this->string(100)->notNull()->comment('分类名称'),   'prefix' => $this->text(),   'route' => $this->string(100)->notNull()->comment('路由'),   'method' => $this->string(20)->notNull()->comment('请求方式'),   'app' => $this->string(20)->comment('请求应用'),   'module' => $this->string(20)->comment('请求模块'),   'request' => $this->text()->comment('请求参数'),   'status' => $this->string(10)->notNull()->comment('状态码'),   'message' => $this->text()->comment('日志内容'),   'request_at' => $this->double()->notNull()->comment('请求时间'),   'ip' => $this->string(63)->comment('请求IP'),  ], 'CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE=InnoDB COMMENT='请求日志表'');  //增加索引  $this->createIndex('idx_log_level', '{{%test_log}}', 'level');  $this->createIndex('idx_log_category', '{{%test_log}}', 'category');  $this->createIndex('idx_log_route', '{{%test_log}}', 'route');  $this->createIndex('idx_log_method', '{{%test_log}}', 'method');  $this->createIndex('idx_log_status', '{{%test_log}}', 'status'); } /**  * @inheritdoc  */ public function safeDown() {  $this->dropTable('{{%test_log}}'); }}

(3):执行如下命令生成DbTarget日志表

php yii migrate

2:编写一个DbTarget类来继承yiilogDbTarget类

<?phpnamespace appcomponents;use Yii;use yiihelpersVarDumper;use yiilogLogRuntimeException;use yiiwebHttpException;use yiiwebRequest;/** * DbTarget stores log messages in a database table. * * @see yiilogDbTarget * * @author wangjian * @since 1.0 */class DbTarget extends yiilogDbTarget{ /**  * @inheritdoc  */ public $categories = [  'application',  'yiiwebHttpException:*', ]; /**  * @inheritdoc  */ public $except = [  // 'yiiwebHttpException:404', ]; /**  * @inheritdoc  */ public $logVars = ['_GET', '_POST']; /**  * @var string 用户组件ID  */ public $userComponentId = 'user'; /**  * @inheritdoc  */ 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)) {   $oldExportInterval = $this->exportInterval;   $this->exportInterval = 0;   $this->export();   $this->exportInterval = $oldExportInterval;   $this->messages = [];  } } /**  * @inheritdoc  */ public function getMessagePrefix($message) {  if ($this->prefix !== null) {   return call_user_func($this->prefix, $message);  }  if (Yii::$app === null) {   return '';  }  $ip = $this->getIp();  $ip = empty($ip) ? '-' : $ip;  return "[$ip]"; } /**  * @inheritdoc  */ public function export() {  if ($this->db->getTransaction()) {   $this->db = clone $this->db;  }  $tableName = $this->db->quoteTableName($this->logTable);  $sql = "INSERT INTO $tableName ([[level]], [[category]], [[prefix]], [[route]], [[method]], [[app]], [[module]], [[request]], [[status]], [[message]], [[request_at]], [[ip]])    VALUES (:level, :category, :prefix, :route, :method, :app, :module, :request, :status, :message, :request_at, :ip)";  $command = $this->db->createCommand($sql);  $request = Yii::$app->getRequest();  list($route, $params) = $request->resolve();  $method = $request->getMethod();  $module = Yii::$app->controller->module->id;  $route = str_replace("{$module}/", '', $route);  foreach ($this->messages as $message) {   list($text, $level, $category, $timestamp) = $message;   $statusCode = 200;   if (!is_string($text)) {    if ($text instanceof Throwable || $text instanceof Exception) {     $statusCode = $text instanceof HttpException ? $text->statusCode : 500;     $text = $text->getMessage();    } else {     $text = VarDumper::export($text);    }   }   if ($command->bindValues([     ':level' => $level,     ':category' => $category,     ':prefix' => $this->getMessagePrefix($message),     ':route' => $route,     ':method' => $method,     ':app' => Yii::$app->id,     ':module' => $module,     ':request' => $this->getContextMessage(),     ':status' => $statusCode,     ':message' => $text,     ':request_at' => $timestamp,     ':ip' => $this->getIp(),    ])->execute() > 0) {    continue;   }   throw new LogRuntimeException('Unable to export log through database!');  } } /**  * 获取当前IP  */ protected function getIp() {  $request = Yii::$app->getRequest();  return $request instanceof Request ? $request->getUserIP() : ''; }}

3:在配置文件中将yiilogDbTarget类改成我们自定义的类

'log' => [ 'traceLevel' => YII_DEBUG ? 3 : 0, 'targets' => [  [   'class' => 'yiilogFileTarget',   'levels' => ['error', 'warning'],  ],  'test' => [   'class' => 'appcomponentsDbTarget',   'logTable' => '{{%test_log}}',   'levels' => ['error', 'info', 'warning'],  ], ],],

4:使用DbTarget日志

同样的使用Yii::info来记录日志

相关文章 大家在看