前端代碼的錯誤日誌收集了解一下

前言

開發web應用程序過程當中的一種常見的作法,就是集中保存錯誤日誌,以便查找重要錯誤的緣由.
就像數據庫和服務器都會按期寫入日誌同樣,在複雜的web應用程序中,咱們一樣推薦你把JavaScript錯誤也回寫到服務器,換句話再說,咱們也能夠將這些錯誤寫入到保存服務器端錯誤的地方,只不過標明他們來自前端.從而把前端的錯誤集中起來,能夠及大地方便前端開發者分析代碼.html

具體操做

主要思想

後端須要提供一個接收錯誤信息的接口,把接收到的錯誤信息存放在一個日誌文件中,好比 font-msg.log.
前端在比較可能會出現錯誤的地方用 try{}catch(err){} 語句來捕獲,而後經過一些能夠發送請求的方法,把收集到的報錯信息發送到這個後端提供的日誌接口.
這樣就獲得了前端的報錯日誌了,開發者能夠常常去查看,分析本身代碼中的不足,優化改善代碼.前端

代碼示例

前端代碼示例

前端代碼中,咱們使用了Image對象來發送請求,這樣作很是靈活,主要緣由以下:node

  • 全部瀏覽器都支持Image對象;
  • 能夠避免跨域限制,img的src屬性能夠實現跨域訪問.
  • 在記錄錯誤的過程當中出問題的機率比較低.
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>收集前端日誌實例頁面</title>
    <meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
</head>
<body>
    <div>日誌收集學習</div>
</body>
<script>
    // 發送錯誤日誌的函數
    function logError(sev, msg) {
        var img = new Image();
        img.src = "http://127.0.0.1:4000/postMessage?sev=" + encodeURIComponent(sev) + "&msg=" + encodeURIComponent(msg);
    }
    try {
        for(var i = 0, len= mods.length; i < len; i++) {
            mods[i].init();
        }
    } catch(ex) {
        // 捕捉錯誤信息
        logError("nonfatal", "Module init failed: " + ex.message);
    }
</script>
</html>

補充:
評論裏有朋友建議使用window.onerror事件,我在這裏引用一下JavaScript高級程序設計(第三版)的書中對這個事件的解釋:ios

任何沒有經過try-catch處理的錯誤都會觸發window對象的error事件,在任何web瀏覽器中,onerror事件處理程序都不會建立event對象,但它能夠接收三個參數: 錯誤信息,錯誤所在的URL和行號.多數狀況下,只有錯誤信息有用,由於URL只給出了文檔的位置,而行號所指的代碼既可能出自內部JavaScript代碼,也可能出自外部文件.
只要發生錯誤,不管是否是瀏覽器生成的,都會觸發error事件
window.onerror = function (message, url, line) {
    alert(message);
    return false;
}
經過返回false,這個函數實際就充當了整個文檔的try-catch語句,能夠捕獲全部無代碼處理的運行錯誤.可是瀏覽器在使用這個事件處理錯誤的方式有明顯不一樣,在IE中,即便發生onerror事件,代碼仍然會正常執行,全部變量和數據都將獲得保留,所以能在onerror事件處理程序中訪問它們,但在firefox中,常規代碼會中止執行,事件發生以前的全部變量和數據都將被銷燬,所以幾乎就沒法判斷錯誤了,且另外window.onerror事件不能捕獲promise的異常錯誤信息.
因此我在這裏使用的是try...catch...,可是我以爲具體的使用方法能夠根據本身的業務需求來肯定,我這裏只是作一個示例,實際的實現途徑還有不少,可是萬法同宗.

後端代碼示例

這裏我使用node寫了一個日誌採集的接口,並將採集到的信息寫入日誌文件.laravel

app.js(主入口文件):git

const Koa = require("koa");
const app = new Koa();

const router = require('./router');
const axios = require('axios')

app.use(router.routes());
app.use(router.allowedMethods());

app.on("error", function (err, ctx) {
    console.log(err)
})
app.listen(4000, function (ctx) {
    console.log("i am listening"); 
})

router/index.js(路由入口文件):github

const koaRouter = require("koa-router");
const router = new koaRouter();

const log4js = require("log4js");
var config = {
    "replaceConsole": true,
    "appenders": {
        "stdout": { 
            "type": "stdout"
        },
        "req": {
            "type": "dateFile",
            "filename": "logs/reqlog/",
            "pattern": "req-yyyy-MM-dd.log",
            "alwaysIncludePattern": true
        },
        "err": {
            "type": "dateFile",
            "filename": "logs/errlog/",
            "pattern": "err-yyyy-MM-dd.log",
            "alwaysIncludePattern": true
        },
        "oth": {
            "type": "dateFile",
            "filename": "logs/othlog/",
            "pattern": "oth-yyyy-MM-dd.log",
            "alwaysIncludePattern": true
        }
    },
    "categories": {
        "default": { 
            "appenders": ["stdout", "req"], 
            "level": "debug"
        },
        "err": { 
            "appenders": ["stdout", "err"], 
            "level": "error"
        },
        "oth": { 
            "appenders": ["stdout", "oth"], 
            "level": "info"
        }
    }
}
log4js.configure(config);
const reqLogger = log4js.getLogger();
const errLogger = log4js.getLogger('err');
const infoLogger = log4js.getLogger('oth');

router.get("/postMessage", async(ctx, next) => {
    console.log(ctx.query); 
    infoLogger.info(ctx.query.sev + "--" + ctx.query.msg);
    ctx.body = {
        msg: "i get it",
        code: 200
    };
    return next();
})
module.exports = router;

收集到的日誌信息截圖:web

clipboard.png

更詳細的代碼: https://github.com/muzishuiji...數據庫

推薦閱讀:axios

不知道大家是怎樣前端報錯信息的呢?若是大家有更好的採集方法,歡迎email(2510909248@qq.com)或者私信給我,愛分享的你最可愛^_^^_^

若是個人文章中有不足之處,歡迎批評指正~~

相關文章
相關標籤/搜索