国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

一步一步搭建前端監(jiān)控系統(tǒng):接口請(qǐng)求異常監(jiān)控篇

dreamtecher / 3600人閱讀

摘要:參考一步一步搭建前端監(jiān)控系統(tǒng)錯(cuò)誤監(jiān)控篇用插件記錄網(wǎng)絡(luò)請(qǐng)求異常關(guān)于專注于微信小程序微信小游戲支付寶小程序和線上應(yīng)用實(shí)時(shí)監(jiān)控。

摘要: 如何監(jiān)控HTTP請(qǐng)求錯(cuò)誤?

作者:一步一個(gè)腳印一個(gè)坑

原文:搭建前端監(jiān)控系統(tǒng)(四)接口請(qǐng)求異常監(jiān)控篇

Fundebug經(jīng)授權(quán)轉(zhuǎn)載,版權(quán)歸原作者所有。

背景:市面上的監(jiān)控系統(tǒng)有很多,大多收費(fèi),對(duì)于小型前端項(xiàng)目來說,必然是痛點(diǎn)。另一點(diǎn)主要原因是,功能雖然通用,卻未必能夠滿足我們自己的需求, 所以我們自給自足也許是個(gè)不錯(cuò)的辦法。

這是搭建前端監(jiān)控系統(tǒng)的第四章,主要是介紹如何統(tǒng)計(jì)靜態(tài)資源加載報(bào)錯(cuò),跟著我一步步做,你也能搭建出一個(gè)屬于自己的前端監(jiān)控系統(tǒng)。

上一章介紹了如何統(tǒng)計(jì)靜態(tài)資源加載報(bào)錯(cuò),今天要說的是接口請(qǐng)求報(bào)錯(cuò)。可能有人會(huì)認(rèn)為接口的報(bào)錯(cuò)應(yīng)該由后臺(tái)來關(guān)注,統(tǒng)計(jì),并修復(fù)。 確實(shí)如此,而且后臺(tái)服務(wù)有了很多成熟完善的統(tǒng)計(jì)工具,完全能夠應(yīng)對(duì)大部分的異常情況, 那么為什么還需要前端對(duì)接口請(qǐng)求進(jìn)行監(jiān)控呢。原因很簡單,因?yàn)榍岸耸莃ug的第一發(fā)現(xiàn)位置,在你幫后臺(tái)背鍋之前怎么快速把過甩出去呢,這時(shí)候,我們就需要有一個(gè)接口的監(jiān)控系統(tǒng),哈哈 :)

我們要監(jiān)控接口報(bào)錯(cuò)的情況,及時(shí)定位線上問題產(chǎn)生的原因

我們要分析接口的性能,以輔助我們對(duì)前端應(yīng)用的優(yōu)化。

好了, 進(jìn)入正題吧:

如何監(jiān)控前端接口請(qǐng)求呢?

一般前端請(qǐng)求都是用jquery的ajax請(qǐng)求,也有用fetch請(qǐng)求的,以及前端框架自己封裝的請(qǐng)求等等。總之他們封裝的方法各不相同,但是萬變不離其宗,他們都是對(duì)瀏覽器的這個(gè)對(duì)象 window.XMLHttpRequest 進(jìn)行了封裝,所以我們只要能夠監(jiān)聽到這個(gè)對(duì)象的一些事件,就能夠把請(qǐng)求的信息分離出來。

如何監(jiān)聽ajax請(qǐng)求

如果你用的jquery、zepto、或者自己封裝的ajax方法,就可以用如下的方法進(jìn)行監(jiān)聽。我們監(jiān)聽 XMLHttpRequest 對(duì)象的兩個(gè)事件 loadstart, loadend。但是監(jiān)聽的結(jié)果并不是像我們想象的那么容易理解,我們先看下ajaxLoadStart,ajaxLoadEnd的回調(diào)方法。

/**
 * 頁面接口請(qǐng)求監(jiān)控
 */
function recordHttpLog() {
    // 監(jiān)聽ajax的狀態(tài)
    function ajaxEventTrigger(event) {
        var ajaxEvent = new CustomEvent(event, {
            detail: this
        });
        window.dispatchEvent(ajaxEvent);
    }
    var oldXHR = window.XMLHttpRequest;
    function newXHR() {
        var realXHR = new oldXHR();
        realXHR.addEventListener(
            "loadstart",
            function() {
                ajaxEventTrigger.call(this, "ajaxLoadStart");
            },
            false
        );
        realXHR.addEventListener(
            "loadend",
            function() {
                ajaxEventTrigger.call(this, "ajaxLoadEnd");
            },
            false
        );
        // 此處的捕獲的異常會(huì)連日志接口也一起捕獲,如果日志上報(bào)接口異常了,就會(huì)導(dǎo)致死循環(huán)了。
        // realXHR.onerror = function () {
        //   siftAndMakeUpMessage("Uncaught FetchError: Failed to ajax", WEB_LOCATION, 0, 0, {});
        // }
        return realXHR;
    }
    var timeRecordArray = [];
    window.XMLHttpRequest = newXHR;
    window.addEventListener("ajaxLoadStart", function(e) {
        var tempObj = {
            timeStamp: new Date().getTime(),
            event: e
        };
        timeRecordArray.push(tempObj);
    });
    window.addEventListener("ajaxLoadEnd", function() {
        for (var i = 0; i < timeRecordArray.length; i++) {
            if (timeRecordArray[i].event.detail.status > 0) {
                var currentTime = new Date().getTime();
                var url = timeRecordArray[i].event.detail.responseURL;
                var status = timeRecordArray[i].event.detail.status;
                var statusText = timeRecordArray[i].event.detail.statusText;
                var loadTime = currentTime - timeRecordArray[i].timeStamp;
                if (!url || url.indexOf(HTTP_UPLOAD_LOG_API) != -1) return;
                var httpLogInfoStart = new HttpLogInfo(
                    HTTP_LOG,
                    url,
                    status,
                    statusText,
                    "發(fā)起請(qǐng)求",
                    timeRecordArray[i].timeStamp,
                    0
                );
                httpLogInfoStart.handleLogInfo(HTTP_LOG, httpLogInfoStart);
                var httpLogInfoEnd = new HttpLogInfo(
                    HTTP_LOG,
                    url,
                    status,
                    statusText,
                    "請(qǐng)求返回",
                    currentTime,
                    loadTime
                );
                httpLogInfoEnd.handleLogInfo(HTTP_LOG, httpLogInfoEnd);
                // 當(dāng)前請(qǐng)求成功后就在數(shù)組中移除掉
                timeRecordArray.splice(i, 1);
            }
        }
    });
}

一個(gè)頁面上會(huì)有很多個(gè)請(qǐng)求,當(dāng)一個(gè)頁面發(fā)出多個(gè)請(qǐng)求的時(shí)候,ajaxLoadStart事件被監(jiān)聽到,但是卻無法區(qū)分出來到底發(fā)送的是哪個(gè)請(qǐng)求,只返回了一個(gè)內(nèi)容超多的事件對(duì)象,而且事件對(duì)象的內(nèi)容幾乎完全一樣。當(dāng)ajaxLoadEnd事件被監(jiān)聽到的時(shí)候,也會(huì)返回一個(gè)內(nèi)容超多的時(shí)間對(duì)象,這個(gè)時(shí)候事件對(duì)象里包含了接口請(qǐng)求的所有信息。幸運(yùn)的是,兩個(gè)對(duì)象是同一個(gè)引用,也就意味著,ajaxLoadStart和ajaxLoadEnd事件被捕獲的時(shí)候,他們作用的是用一個(gè)對(duì)象。那我們就有辦法分析出來了。

當(dāng)ajaxLoadStart事件發(fā)生的時(shí)候,我們將回調(diào)方法中的事件對(duì)象全都放進(jìn)數(shù)組timeRecordArray里,當(dāng)ajaxLoadEnd發(fā)生的時(shí)候,我們就去遍歷這個(gè)數(shù)據(jù),遇到又返回結(jié)果的事件對(duì)象,說明接口請(qǐng)求已經(jīng)完成,記錄下來,并從數(shù)組中刪除該事件對(duì)象。這樣我們就能夠逐一分析出接口請(qǐng)求的內(nèi)容了。

如何監(jiān)聽fetch請(qǐng)求

通過第一種方法,已經(jīng)能夠監(jiān)聽到大部分的ajax請(qǐng)求了。然而,使用fetch請(qǐng)求的人越來越多,因?yàn)閒etch的鏈?zhǔn)秸{(diào)用可以讓我們擺脫ajax的嵌套地獄,被更多的人所青睞。奇怪的是,我用第一種方式,卻無法監(jiān)聽到fetch的請(qǐng)求事件,這是為什么呢?

return new Promise(function(resolve, reject) {
    var request = new Request(input, init);
    var xhr = new XMLHttpRequest();

    xhr.onload = function() {
        var options = {
            status: xhr.status,
            statusText: xhr.statusText,
            headers: parseHeaders(xhr.getAllResponseHeaders() || "")
        };
        options.url =
            "responseURL" in xhr
                ? xhr.responseURL
                : options.headers.get("X-Request-URL");
        var body = "response" in xhr ? xhr.response : xhr.responseText;
        resolve(new Response(body, options));
    };
    // .......
    xhr.send(
        typeof request._bodyInit === "undefined" ? null : request._bodyInit
    );
});

這個(gè)是fetch的一段源碼, 可以看到,它創(chuàng)建了一個(gè)Promise, 并新建了一個(gè)XMLHttpRequest對(duì)象 var xhr =newXMLHttpRequest()。由于fetch的代碼是內(nèi)置在瀏覽器中的,它必然先用監(jiān)控代碼執(zhí)行,所以,我們?cè)谔砑颖O(jiān)聽事件的時(shí)候,是無法監(jiān)聽fetch里邊的XMLHttpRequest對(duì)象的。怎么辦呢,我們需要重寫一下fetch的代碼。只要在監(jiān)控代碼執(zhí)行之后,我們重寫一下fetch,就可以正常監(jiān)聽使用fetch方式發(fā)送的請(qǐng)求了。就這么簡單 :)

看一下需要監(jiān)聽的字段:

// 設(shè)置日志對(duì)象類的通用屬性
function setCommonProperty() {
    this.happenTime = new Date().getTime(); // 日志發(fā)生時(shí)間
    this.webMonitorId = WEB_MONITOR_ID; // 用于區(qū)分應(yīng)用的唯一標(biāo)識(shí)(一個(gè)項(xiàng)目對(duì)應(yīng)一個(gè))
    this.simpleUrl = window.location.href.split("?")[0].replace("#", ""); // 頁面的url
    this.completeUrl = utils.b64EncodeUnicode(
        encodeURIComponent(window.location.href)
    ); // 頁面的完整url
    this.customerKey = utils.getCustomerKey(); // 用于區(qū)分用戶,所對(duì)應(yīng)唯一的標(biāo)識(shí),清理本地?cái)?shù)據(jù)后失效,
    // 用戶自定義信息, 由開發(fā)者主動(dòng)傳入, 便于對(duì)線上問題進(jìn)行準(zhǔn)確定位
    var wmUserInfo = localStorage.wmUserInfo
        ? JSON.parse(localStorage.wmUserInfo)
        : "";
    this.userId = utils.b64EncodeUnicode(wmUserInfo.userId || "");
    this.firstUserParam = utils.b64EncodeUnicode(
        wmUserInfo.firstUserParam || ""
    );
    this.secondUserParam = utils.b64EncodeUnicode(
        wmUserInfo.secondUserParam || ""
    );
}
// 接口請(qǐng)求日志,繼承于日志基類MonitorBaseInfo
function HttpLogInfo(
    uploadType,
    url,
    status,
    statusText,
    statusResult,
    currentTime,
    loadTime
) {
    setCommonProperty.apply(this);
    this.uploadType = uploadType; // 上傳類型
    this.httpUrl = utils.b64EncodeUnicode(encodeURIComponent(url)); // 請(qǐng)求地址
    this.status = status; // 接口狀態(tài)
    this.statusText = statusText; // 狀態(tài)描述
    this.statusResult = statusResult; // 區(qū)分發(fā)起和返回狀態(tài)
    this.happenTime = currentTime; // 客戶端發(fā)送時(shí)間
    this.loadTime = loadTime; // 接口請(qǐng)求耗時(shí)
}

所有工作準(zhǔn)備完畢,如果把收集到的日志從不同的維度展現(xiàn)出來,我就不細(xì)說了,直接上圖了。如此,便能夠?qū)η岸私涌趫?bào)錯(cuò)的情況有一個(gè)清晰的了解,也能夠快速的發(fā)現(xiàn)線上的問題。

參考

一步一步搭建前端監(jiān)控系統(tǒng):JS錯(cuò)誤監(jiān)控篇

用Fundebug插件記錄網(wǎng)絡(luò)請(qǐng)求異常

關(guān)于Fundebug

Fundebug專注于JavaScript、微信小程序、微信小游戲、支付寶小程序、React Native、Node.js和Java線上應(yīng)用實(shí)時(shí)BUG監(jiān)控。 自從2016年雙十一正式上線,F(xiàn)undebug累計(jì)處理了10億+錯(cuò)誤事件,付費(fèi)客戶有陽光保險(xiǎn)、核桃編程、荔枝FM、掌門1對(duì)1、微脈、青團(tuán)社等眾多品牌企業(yè)。歡迎大家免費(fèi)試用!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/105613.html

相關(guān)文章

  • 步一搭建前端監(jiān)控系統(tǒng):如何記錄用戶行為?

    摘要:摘要通過記錄用戶行為,快速復(fù)現(xiàn)場(chǎng)景。這是搭建前端監(jiān)控系統(tǒng)的第二章,主要是介紹如何統(tǒng)計(jì)報(bào)錯(cuò),跟著我一步步做,你也能搭建出一個(gè)屬于自己的前端監(jiān)控系統(tǒng)。 摘要: 通過記錄用戶行為,快速復(fù)現(xiàn)BUG場(chǎng)景。 作者:一步一個(gè)腳印一個(gè)坑 原文:搭建前端監(jiān)控系統(tǒng)(備選)用戶行為統(tǒng)計(jì)和監(jiān)控篇(如何快速定位線上問題) Fundebug經(jīng)授權(quán)轉(zhuǎn)載,版權(quán)歸原作者所有。 一步一步搭建前端監(jiān)控系統(tǒng)系列博客: ...

    tolerious 評(píng)論0 收藏0
  • 步一搭建前端監(jiān)控系統(tǒng):如何定位前端線上問題?

    摘要:一直以來,前端的線上問題很難定位,因?yàn)樗l(fā)生于用戶的一系列操作之后。當(dāng)然,這些問題并非不能克服,讓我們來一起看看如何去定位線上的問題吧。地址參考一步一步搭建前端監(jiān)控系統(tǒng)錯(cuò)誤監(jiān)控篇一步一步搭建前端監(jiān)控系統(tǒng)接口請(qǐng)求異常監(jiān)控篇 摘要: 記錄用戶行為,排查線上BUG。 作者:一步一個(gè)腳印一個(gè)坑 原文:如何定位前端線上問題(如何排查前端生產(chǎn)問題) Fundebug經(jīng)授權(quán)轉(zhuǎn)載,版權(quán)歸原作者所...

    aaron 評(píng)論0 收藏0
  • 步一搭建前端監(jiān)控系統(tǒng):JS錯(cuò)誤監(jiān)控

    摘要:摘要徒手寫錯(cuò)誤監(jiān)控。為什么用定時(shí)器呢,因?yàn)樵趩雾搼?yīng)用中,路由的切換和地址欄的變化是無法被監(jiān)控的,我確實(shí)沒有想到特別好的辦法來監(jiān)控,所以用了這種方式,如果有人有更好的辦法,請(qǐng)給我留言,謝謝。 摘要: 徒手寫JS錯(cuò)誤監(jiān)控。 作者:一步一個(gè)腳印一個(gè)坑 原文:搭建前端監(jiān)控系統(tǒng)(二)JS錯(cuò)誤監(jiān)控篇 Fundebug經(jīng)授權(quán)轉(zhuǎn)載,版權(quán)歸原作者所有。 背景:市面上的監(jiān)控系統(tǒng)有很多,大多收費(fèi),對(duì)于...

    EdwardUp 評(píng)論0 收藏0
  • Sentry異常監(jiān)控方案部署-前端攻略

    摘要:故而,我們需要在項(xiàng)目出現(xiàn)異常時(shí)主動(dòng)對(duì)其進(jìn)行收集上報(bào),分析原因和影響后制定下一步解決方案。所以,我們需要一款成熟的異常監(jiān)控系統(tǒng)來協(xié)助我們。最近在公司項(xiàng)目中部署了,用于項(xiàng)目中異常監(jiān)控,涵蓋了前端后端。 原文首發(fā)于我的個(gè)人博客: https://lonhon.top/ 凡事只要有可能出錯(cuò),那就一定會(huì)出錯(cuò) 對(duì)于任何一個(gè)項(xiàng)目而言,本地測(cè)試肯定做不到100%覆蓋,而且,我們也不能保證用戶能按照我們...

    Lorry_Lu 評(píng)論0 收藏0
  • 步一搭建前端監(jiān)控系統(tǒng):如何將網(wǎng)頁截圖上報(bào)?

    摘要:目前已經(jīng)在運(yùn)行的線上前端監(jiān)控系統(tǒng)代碼和講解都放在這篇文章里監(jiān)控系統(tǒng)介紹及代碼用戶對(duì)前端程序員來說,就是一個(gè)黑匣子。 摘要: 通過錄屏或者截圖,快速復(fù)現(xiàn)BUG場(chǎng)景。 作者:一步一個(gè)腳印一個(gè)坑 原文:搭建前端監(jiān)控系統(tǒng)(備選)Js截圖上報(bào)篇 Fundebug經(jīng)授權(quán)轉(zhuǎn)載,版權(quán)歸原作者所有。 PS:本文關(guān)于Fundebug錄屏功能的內(nèi)容有些不準(zhǔn)確的地方,比如錄屏并非通過截圖實(shí)現(xiàn)的,錄屏插件...

    Martin91 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<