1. 程式人生 > >從零實現前端日誌上報

從零實現前端日誌上報

前期準備

  • XAMPP —— PHP環境+資料庫視覺化操作

進入主題

建表結構

首先需要確定需要上傳哪些資訊

  • 通過 window.onerror 可以獲取 msg, url, line, col, error等錯誤資訊,JS 的錯誤行號、url錯誤地址,
  • 通過 window.navigator.userAgent 獲取 裝置瀏覽器的資訊集合

執行SQL語句

CREATE TABLE `j_log` (
  `id` int(10) NOT NULL AUTO_INCREMENT COMMENT 'id號',
  `os_version` char(10) DEFAULT NULL
COMMENT '系統版本號', `msg` varchar(255) DEFAULT NULL COMMENT '錯誤資訊', `error_url` varchar(255) DEFAULT NULL COMMENT '錯誤所在的url', `line` int(10) DEFAULT NULL COMMENT '錯誤所在的行', `col` int(10) DEFAULT NULL COMMENT '錯誤所在的列', `error` varchar(255) DEFAULT NULL COMMENT '具體的error物件', `url` varchar(255) DEFAULT
NULL, `browser` varchar(255) DEFAULT NULL COMMENT '瀏覽器型別', `product_name` char(255) CHARACTER SET utf8 DEFAULT '' COMMENT '產品名稱', `error_time` char(20) DEFAULT NULL COMMENT '時間戳', `os` char(10) DEFAULT NULL COMMENT '系統型別', `extend` varchar(255) DEFAULT NULL COMMENT '業務擴充套件欄位、儲存JSON字串', `ua`
varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=55 DEFAULT CHARSET=utf8;
採用何種方式進行日誌上報

基於日誌上報前端除去將資料發給後端外不需要進行額外的資料處理,我採用img標籤的形式進行。

let path = 'http://localhost:8080/dashboard/log.php'
let os_version = 'V_0.0.1';
let msg = '這是一條測試的msg';
let error_url = 'index.php';

function click_me (path, os_version, msg, error_url) {
    (new Image).src = `${path}?os_version=${os_version}&msg=${msg}&error_url=${error_url}`;
}
PHP程式碼編寫

簡單使用mysqli封裝的資料庫操作類

資料庫操作類
<?php 
	/**
	 * MySQL操作資料庫
	 */
	class Mysql{
		public $mydb; // 接收資料庫例項
		public function __construct($host, $username, $password, $db)
		{
			$this->mydb = new mysqli($host, $username, $password, $db); // 伺服器,使用者名稱,密碼,資料庫名
	
			if ($this->mydb->connect_errno) {	# 非0即為資料庫連線失敗
				die('Connect Error (' . $this->mydb->connect_errno . ') '
		            . $this->mydb->connect_error);
			} else {
				// echo "成功連結到資料庫:". $db . "<br>";
			};
		}

		public function runSql ($sql) { // 執行SQL語句
			$this->mydb->query("set names utf8"); // 設定編碼規則

			$result = $this->mydb->query($sql);
			echo $sql;

			if ($result) {
				if ($result->num_rows) {
					# 第一種方法
					# $row = $result->fetch_row();
					# print_r($row);
					/*
					while ($row = $result->fetch_row()) {
						print_r($row);
					}
					*/
					# 第二種方法
					/*
					while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
						print_r($row);	
					}
					*/
					# 第三種方法
					$row = $result->fetch_all(MYSQLI_ASSOC);
					# 將陣列轉為json資料
					return json_encode($row);
				}
			}else{
				echo "語句執行失敗! <br>";
				echo $this->mydb->error . "<br>";
			    echo $this->mydb->errno . "<br>";
			}
		}

		public function insert ($table, $field) { // 增加資料
			$sql = "INSERT INTO " . $table . " VALUES " . $field;
			$this->runSql($sql);
		}

		public function update ($table, $field, $condition) { // 更新資料
			$sql = "UPDATE " . $table . " SET " . $field . " WHERE " . $condition;
			$this->runSql($sql);
		}

		public function delete ($table, $condition) {	// 刪除資料
			$sql = "DELETE FROM " . $table . " WHERE " . $condition;
			$this->runSql($sql);
		}

		public function selece ($table, $condition = false) { // 查資料
			$sql = $condition ?
				"SELECT * FROM " . $table . " WHERE " . $condition :
				"SELECT * FROM " . $table;
			$res = $this->runSql($sql);

			if ($res) return $res;
		}
		
		public function closeSql () {	// 斷開資料庫連結
			$this->mydb->close();
		}
	}
?>
log.php業務邏輯程式碼
// 引入PHP程式碼
<?php include "./fetch/database.php" ?> 

<?php 
    // 用到的變數,需要先定義在外部
    $os_version=NULL;
    $msg=NULL;
    $error_url=NULL;

    if ($_GET['os_version'] AND $_GET['msg'] AND $_GET['error_url']) {
        $os_version = $_GET['os_version'];
        $msg = $_GET['msg'];
        $error_url = $_GET['error_url'];

        $mysqli = new Mysql('localhost', 'root', '', 'my_firstDB');

        // '$os_version' 兩側的''很關鍵 ,如不加SQL語句中不能拿到正確的字元,會被當做變數解析為null
        $mysqli->insert("j_log(os_version, msg, error_url)", "('$os_version', '$msg', '$error_url')");

        $mysqli->closeSql();
    } else {
        echo '請補全';
        return;
    }
?>

此時呼叫click_me方法即可實現日誌上報