当前位置:首页 > 服务端 > 前端异常上报

前端异常上报

目录

引子

前端异常解析:Source Map 中讨论了 Source Map 的使用,接着看看异常上报的方式。

影响因素

异常上报,可能产生影响的因素有:

  1. 上报的频率。当出现死循环,不断触发异常上报时,这个就跟 DDOS 攻击差不多了。
  2. 上报的数据量。不同的请求方式,能携带的数据量有限制。如果想要录制用户的操作,那么产生的数据量,不同情况下会不一样。
  3. 跨域。日志服务器有些是单独的。
  4. 不同 web 服务器对于请求的 body 大小限制不同,见 Can HTTP POST be limitless?
  5. 上报请求的响应方式。响应同样会消耗资源。

以上是一些比较容易想到的因素,在实际的情况中,根据不同监控的需要,可能会出现其它的影响因素。

上报方式

图片 src

优点:

  • 不受跨域限制。
  • 可以不用响应。

不足:

XHR/Fetch

优点:

  • POST 的方式可以传送更多的数据,理论上没有限制请求 body 的大小,但不同的服务器,接受的请求的 body 大小可能有限制。

不足:

  • 受跨域限制。
  • 可能与其它优先级更高的网络请求竞争资源。

Beacon

Beacon(信标)接口用于安排异步和非阻塞数据传输,从而能最大限度地减少与其它关键型操作的资源争用,同时还能将请求发送到目的地。特点有:

  • 信标请求使用的 POST 方式而且不需要响应。
  • 信标请求会避免与关键操作和优先级高的网络请求竞争资源。
  • 用户代理可以有效的合并信标请求,以优化移动设备上的能量使用。
  • 信标请求保证在页面卸载之前初始化,并且允许运行完成,而不需要阻塞请求或阻塞其它用户交互事件处理。
window.navigator.sendBeacon(url,data)
  • url : 传送数据的 URL 。
  • data : 传送的数据,这个参数可选,支持 ArrayBufferView、Blob、DOMString、FormData ,更详细类型见 BodyInit unions

兼容性见 Can I use Beacon

不足:

  • 这个方法不会提供任何关于数据传送是否成功的信息。
  • 受跨域限制。

频率

针对不同的异常和目的,上报的频率可以人为的进行控制。比较概括的可以分为三类:即时上报、批量上报、用户主动上报。

即时上报

即时上报就是触发了异常马上上报,这类异常一般会严重影响到用户的使用。

当比较多的异常连续触发或出现了无限循环触发异常时,上报的请求也需要一定的管理。下面是 @sentry/utils version 5.8.0 中管理的一种方式:

import { SentryError } from './error';
import { SyncPromise } from './syncpromise';
/** A simple queue that holds promises. */
export class PromiseBuffer {
    constructor(_limit) {
        this._limit = _limit;
        /** Internal set of queued Promises */
        this._buffer = [];
    }
    /**
     * Says if the buffer is ready to take more requests
     */
    isReady() {
        return this._limit === undefined || this.length() < this._limit;
    }
    /**
     * Add a promise to the queue.
     *
     * @param task Can be any PromiseLike<T>
     * @returns The original promise.
     */
    add(task) {
        if (!this.isReady()) {
            return SyncPromise.reject(new SentryError('Not adding Promise due to buffer limit reached.'));
        }
        if (this._buffer.indexOf(task) === -1) {
            this._buffer.push(task);
        }
        task
            .then(() => this.remove(task))
            .then(null, () => this.remove(task).then(null, () => {
            // We have to add this catch here otherwise we have an unhandledPromiseRejection
            // because it's a new Promise chain.
        }));
        return task;
    }
    /**
     * Remove a promise to the queue.
     *
     * @param task Can be any PromiseLike<T>
     * @returns Removed promise.
     */
    remove(task) {
        const removedTask = this._buffer.splice(this._buffer.indexOf(task), 1)[0];
        return removedTask;
    }
    /**
     * This function returns the number of unresolved promises in the queue.
     */
    length() {
        return this._buffer.length;
    }
    /**
     * This will drain the whole queue, returns true if queue is empty or drained.
     * If timeout is provided and the queue takes longer to drain, the promise still resolves but with false.
     *
     * @param timeout Number in ms to wait until it resolves with false.
     */
    drain(timeout) {
        return new SyncPromise(resolve => {
            const capturedSetTimeout = setTimeout(() => {
                if (timeout && timeout > 0) {
                    resolve(false);
                }
            }, timeout);
            SyncPromise.all(this._buffer)
                .then(() => {
                clearTimeout(capturedSetTimeout);
                resolve(true);
            })
                .then(null, () => {
                resolve(true);
            });
        });
    }
}

主要思路:

  • 初始化的时候,会提供一个数组 _buffer 和阈值 _limit
  • 所有的请求会进行类似 Promise 机制包裹,通过方法 add 放到数组中。请求是异步的,根据事件循环机制,可以连续增加新的请求。
  • 当添加的请求数量超过 _limit 时,就不会继续添加了,这样就可以达到一定控制的效果。

批量上报

将收集到的信息先存储到本地,当数据量或间隔时间达到一定的阈值,将本地存储的信息一次性打包上传。追踪用户的操作路径这类信息比较适合这种方式。

用户主动上报

提供一个异常上报入口,由用户自己反馈所遇到的问题。

如果考虑隐私方面的政策,在进入系统的时候,需要告知会进行一些信息采集。

参考资料

作者:XXHolic
来源链接:https://www.cnblogs.com/thyshare/p/14166323.html

版权声明:
1、Java侠(https://www.javaxia.com)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。





本文链接:https://www.javaxia.com/server/125144.html

分享给朋友:

“前端异常上报” 的相关文章

[C#][控件]文本类控件2022年05月17日 20:45:24
CentOS yum 源的配置与使用2022年05月19日 19:54:27
配置 yum 源的两种方法2022年05月19日 19:54:29
投票统计,遍历数据2022年05月21日 11:41:42
软件工程专业如何就业!2022年05月23日 22:31:42
信息系统项目干系人管理2022年05月24日 20:43:17
Activity的生命周期2022年05月25日 21:59:10