美文网首页
无星的前端之旅(七)—— PC端Web错误日志收集1

无星的前端之旅(七)—— PC端Web错误日志收集1

作者: 无星灬 | 来源:发表于2020-07-01 17:42 被阅读0次

    背景

    线上报错,啥也不知道,无法复现束手无策,客户开喷,研发背锅

    这种事情,u1s1,大家都遇到过吧

    解决方式就是有个日志收集上报的地方去查,查什么时候,什么时间,什么环境,出了什么错误,在某些程度能不那么被动

    选型

    是不是以为我是要说用哪家,实际上是准备自己写。。

    免费的不放心,付费的买不起
    但这里还是列出几家
    fundebug
    sentry

    怎么做?

    1.了解需要采集的指标
    2.收集的方式
    3.上报的方式
    4.上报的时机
    5.如何解析
    6.告警

    1.了解需要采集的数据指标

    这里可以参考一些付费的服务的采集指标,比如上面提到的fundebug,sentry,看看人家都收集啥。

    在了解以后,根据自身平台业务的需要,自行采集。

    比如我没有那些花里胡哨的需求,我只采集了如下信息:

    appId:我自己的业务数据,用来标识哪个App出了问题
    type:错误类型
    message:错误抛出的message
    stack:错误堆栈信息
    line:出错行
    column:出错列
    url:sourceMap后出错的js地址
    userAgent:用户的环境,什么浏览器,什么版本等等
    time:出错的世界
    

    实际上你还可以采集更多,但我的业务只需要这些了。

    2.收集

    2.1 收集上报策略核心

    这里我引用参考文章中《自研多端错误收集平台》,贝贝的一句话作为核心思路:“差异化采集,格式化上报!”
    在不同平台使用不同的采集方式。处理成统一的方式最后上报。
    在我落地的表现上就是,不同平台写不同包去处理,最后统一格式上传

    vue,xxx-error-vue
    react,xxx-error-react
    wechat,xxx-error-wechat
    

    2.2 错误的类型

    1.同步的脚本错误
    2.异步的脚本错误
    3.网络错误
    4.资源加载型错误
    

    我这里只捕获1,2,3

    2.3 收集的方式

    2.3.1 自动收集方式兜底

    自动采集的方式是一定要有的。

    这是个兜底策略,在没能手动上报的时候去抓住一些钩子抛出来的错误。

    对于运行在浏览器环境的JavaScript代码来说,浏览器会抛出几个钩子

    window.onerror = function (message, source, line, column, error) {
    //错误捕获1与   window.addEventListener('error') 二选一即可
    }
    window.addEventListener('error', event => {
    //错误捕获2,与   window.onerror 二选一即可     
    })
    window.addEventListener('unhandledrejection', event => {
    //错误捕获3,未实现Promise.reject()
    // 默认实现,以免控制台红色警告
        if (process.env.NODE_ENV === 'production') { event.preventDefault(); }
    })
    function networkHandle(): void {
    //错误捕获4,网络请求错误
        let originSend = XMLHttpRequest.prototype.send;
        XMLHttpRequest.prototype.send = function () {
            console.log('send', arguments);
            this.addEventListener('loadend', () => {
                console.log('loadend')
                if (this.status !== 200) {
                //网络请求挂了,捕获
                }
            })
            originSend.apply(this, arguments);
        };
    
    }
    

    对于额外的框架提供的错误,例如vue,它有着自己的Vue.config.errorHandler机制

    Vue.config.errorHandler = function (error: Error, vm: Object, info: any) {
    //错误捕获处理
    }
    

    2.3.2 手动上报方式

    这个方式也是一定要有的,它可以用来人为捕获一些业务/技术错误

    function notify(error: Error): void {
    //这里面就写点格式化处理和上报
    }
    

    2.4.2 如何进行错误格式化

    上面也说了,核心思想是

    差异化采集,格式化上报
    

    那么提到格式化,就不得不提到这个背景了。

    在不同浏览器不同框架上,抛出来的error不一样!

    比如:Vue.config.errorHandler中拿到的error是Vue处理后的信息,你无法很直观的拿到colum和line。

    这里就不得不提到一个库了TraceKit

    他的作用就是,格式化error,使得不同环境下的error输出相同格式的错误!

    使用方式

    import * as TraceKit from 'tracekit'
    function notify(error: Error): void {
        // 计算堆栈
        let stack = TraceKit.computeStackTrace(error)
        // stack = {name:'xx',mode:'xx',message:'xxx',stack:[{
        //  出错的js地址
        //  url:'xxx',
        //  line:0,
        //  column:0,
        //},{xx},{xx}]}
        //取第一个是因为一般第一个item中的url是真实报错的业务js
        let tmpStack = get(stack, ['stack', '0'])
        // 格式化stack
        let errorInfo: ErrorInfo = createErrorInfo(stack.name,stack.mode,stack.message,tmpStack)
        //格式化成string
        let result: String = formatErrorInfo(errorInfo)
        //这是上报,原因见下面
        let image = new Image()
        image.src = baseUrl + result
    }
    

    3.上报的方式

    这里我使用请求图片get请求的方式上报

    function notify(error){
    //formatErrorInfo是自定义的格式化方法,后文会写做了什么
    let result : String = formatErrorInfo(error)
    let image = new Image()
    image.src = baseUrl + result
    }
    

    为什么?

    1.图片请求没有跨域错误

    2.使用图片发送get请求,上报信息,由于浏览器对图片有缓存,同样的请求,图片只会发送一次,避免重复上报

    3.get请求简单

    4.上报的时机

    较好的方式:制定本地策略,合并请求,统一上传,节省流量也减少服务端压力。

    我就没那么多想法,出错就上报,直接一梭子往上怼就完事了,没到那个量级,也没那么多错误。后面也许会优化吧。

    5.如何解析

    挖个坑

    6.告警

    暂未做

    7.可视化

    我们有elk,直接把数据格式化打到elk上就可以了。

    但是目前没有没有想到好的方式去做sourceMap解析。

    曾经设想过写kibana插件去完成这个操作,但是我整了半天都没跑起来,有点难受。

    我的设想:
    1.kibana提供插件的形式去调取elk的存储查询功能,这是最完美的解决方式了。
    2.自己写页面,调取elk的查询接口。但阻塞点是elk的查询接口如何使用http调用?
    3.自己去存错误,不用elk,但这太蠢了。不太想这么做。

    8.写个demo?

    啥时候有空啥时候补一个。。。

    errorDemo

    参考文章

    前端早早聊-自研多端错误收集平台
    前端异常监控系统的落地

    相关文章

      网友评论

          本文标题:无星的前端之旅(七)—— PC端Web错误日志收集1

          本文链接:https://www.haomeiwen.com/subject/elehqktx.html