1. 程式人生 > 程式設計 >Yii使用DbTarget實現日誌功能的示例程式碼

Yii使用DbTarget實現日誌功能的示例程式碼

一:在配置檔案的log元件中配置DbTarget

Yii使用DbTarget實現日誌功能的示例程式碼

'log' => [
 'traceLevel' => YII_DEBUG ? 3 : 0,'targets' => [
  [
   'class' => 'yii\log\FileTarget','levels' => ['error','warning'],],'test' => [
   'class' => 'yii\log\DbTarget',//DaTarget類
   'logTable' => '{{%test_log}}',//日誌表
   'levels' => ['error','info',//日誌等級
  ],

二:生成日誌表

在專案目錄下執行如下命令生成日誌表

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

三:使用日誌

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

Yii::info()

四:自定義DbTarget日誌

1:首先建立一個自定義的日誌表

(1)在專案目錄下執行

php yii migrate/create create_test_log

(2):在建立的migrate檔案下編寫建立資料庫的遷移指令碼

<?php
use yii\db\Migration;
/**
 * 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','category');
  $this->createIndex('idx_log_route','route');
  $this->createIndex('idx_log_method','method');
  $this->createIndex('idx_log_status','status');
 }
 /**
  * @inheritdoc
  */
 public function safeDown()
 {
  $this->dropTable('{{%test_log}}');
 }
}

(3):執行如下命令生成DbTarget日誌表

php yii migrate

2:編寫一個DbTarget類來繼承yiilogDbTarget類

<?php
namespace app\components;
use Yii;
use yii\helpers\VarDumper;
use yii\log\LogRuntimeException;
use yii\web\HttpException;
use yii\web\Request;
/**
 * DbTarget stores log messages in a database table.
 *
 * @see yii\log\DbTarget
 *
 * @author wangjian
 * @since 1.0
 */
class DbTarget extends \yii\log\DbTarget
{
 /**
  * @inheritdoc
  */
 public $categories = [
  'application','yii\web\HttpException:*',];
 /**
  * @inheritdoc
  */
 public $except = [
  // 'yii\web\HttpException: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,'test' => [
   'class' => 'app\components\DbTarget','logTable' => '{{%test_log}}',

4:使用DbTarget日誌

同樣的使用Yii::info來記錄日誌

到此這篇關於Yii使用DbTarget實現日誌功能的示例程式碼的文章就介紹到這了,更多相關Yii DbTarget 日誌內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!