首页 > 其他分享 >记录--百分百空手接大锅

记录--百分百空手接大锅

时间:2023-07-21 17:47:17浏览次数:30  
标签:pay const monitor 空手 -- 百分百 ajax error message

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

背景

愉快的双休周末刚过完,早上来忽然被运营通知线上业务挂了,用户无法下单。卧槽,赶紧进入debug模式,一查原来是服务端返回的数据有问题,赶紧问了服务端,大佬回复说是业务部门配置套餐错误。好在主责不在我们,不过赶紧写了复盘文档,主动找自己的责任,扛起这口大锅,都怪我们前端,没有做好前端监控,导致线上问题持续两天才发现。原本以为运营会把推辞一下说不,锅是她们的,可惜人家不太懂人情世故,这锅就扣在了技术部头上。虽然但是,我还是静下心来把前端异常监控搞了出来,下次一定不要主动接锅,希望看到本文的朋友们也不要随便心软接锅^_^

监控

因为之前基于sentry做了埋点处理,基础已经打好,支持全自动埋点、手动埋点和数据上报。相关的原理可以参考之前的一篇文章如何从0-1构建数据平台(2)- 前端埋点。本次监控的数据上报也基于sentry.js。那么如何设计整个流程呢。具体步骤如下:

  1. 监控数据分类

  2. 监控数据定义

  3. 监控数据收集

  4. 监控数据上报

  5. 监控数据输出

  6. 监控数据预警

数据分类

我们主要是前端的数据错误,一般的异常大类分为逻辑异常和代码异常。基于我们的项目,由于涉及营收,我们就将逻辑错误专注于支付异常,其他的代码导致的错误分为一大类。然后再将两大异常进行细分,如下:

  1. 支付异常

    1.1 支付成功

    1.2 支付失败

  2. 代码异常

    2.1 bindexception

 2.1.1  js_error

 2.1.2  img_error

 2.1.3  audio_error

 2.1.4  script_error

 2.1.5 video_error
  1. unhandleRejection

    3.1 promise_unhandledrejection_error

    3.2 ajax_error

  2. vueException

  3. peformanceInfo

数据定义

基于sentry的上报数据,一般都包括事件与属性。在此我们定义支付异常事件为“page_h5_pay_monitor”,定义代码异常事件为“page_monitor”。然后支付异常的属性大概为:

    pay_time,

    pay_orderid,

    pay_result,

    pay_amount,

    pay_type,

    pay_use_coupon,

    pay_use_coupon_id,

    pay_use_coupon_name,

    pay_use_discount_amount,

    pay_fail_reason,

    pay_platment
代码异常不同的错误类型可能属性会有所区别:
    // js_error

    monitor_type,

    monitor_message,

    monitor_lineno,

    monitor_colno,

    monitor_error,

    monitor_stack,

    monitor_url

    // src_error

    monitor_type,

    monitor_target_src,

    monitor_url

    // promise_error

    monitor_type,

    monitor_message,

    monitor_stack,

    monitor_url

    // ajax_error

    monitor_type,

    monitor_ajax_method,

    monitor_ajax_data,

    monitor_ajax_params,

    monitor_ajax_url,

    monitor_ajax_headers,

    monitor_url,

    monitor_message,

    monitor_ajax_code

    // vue_error

    monitor_type,

    monitor_message,

    monitor_stack,

    monitor_hook,

    monitor_url

    // peformanceInfo 为数据添加 loading_time 属性,该属性通过entryTypes获取

    try {

        const observer = new PerformanceObserver((list) => {

            for (const entry of list.getEntries()) {

                if (entry.entryType === 'paint') {

                    sa.store.set('loading_time', entry.startTime)

                }
            }

        })

        observer.observe({ entryTypes: ['paint'] })

    } catch (err) {

        console.log(err)

    }

数据收集

数据收集通过事件绑定进行收集,具体绑定如下:

import {

    BindErrorReporter,

    VueErrorReporter,

    UnhandledRejectionReporter

} from './report'

const Vue = require('vue')


// binderror绑定

const MonitorBinderror = () => {

    window.addEventListener(

    'error',

    function(error) {

        BindErrorReporter(error)

    },true )

}

// unhandleRejection绑定 这里由于使用了axios,因此ajax_error也属于promise_error

const MonitorUnhandledRejection = () => {

    window.addEventListener('unhandledrejection', function(error) {

        if (error && error.reason) {

            const { message, code, stack, isAxios, config } = error.reason

            if (isAxios && config) {

                // console.log(config)

                const { data, params, headers, url, method } = config

                UnhandledRejectionReporter({

                isAjax: true,

                data: JSON.stringify(data),

                params: JSON.stringify(params),

                headers: JSON.stringify(headers),

                url,

                method,

                message: message || error.message,

                code

                })

            } else {

                UnhandledRejectionReporter({

                isAjax: false,

                message,

                stack

                })

            }

        }

    })

}

// vueException绑定

const MonitorVueError = () => {

    Vue.config.errorHandler = function(error, vm, info) {

        const { message, stack } = error

        VueErrorReporter({

            message,

            stack,

            vuehook: info

        })

    }

}

// 输出绑定方法

export const MonitorException = () => {

    try {

        MonitorBinderror()

        MonitorUnhandledRejection()

        MonitorVueError()

    } catch (error) {

        console.log('monitor exception init error', error)

    }

}

数据上报

数据上报都是基于sentry进行上报,具体如下:

/*

* 异常监控库 基于sentry jssdk

* 监控类别:

* 1、window one rror 监控未定义属性使用 js资源加载失败问题

* 2、window addListener error 监控未定义属性使用 图片资源加载失败问题

* 3、unhandledrejection 监听promise对象未catch的错误

* 4、vue.errorHandler 监听vue脚本错误

* 5、自定义错误 包括接口错误 或其他diy错误

* 上报事件: page_monitor

*/

// 错误类别常量

const ERROR_TYPE = {

    JS_ERROR: 'js_error',

    IMG_ERROR: 'img_error',

    AUDIO_ERROR: 'audio_error',

    SCRIPT_ERROR: 'script_error',

    VIDEO_ERROR: 'video_error',

    VUE_ERROR: 'vue_error',

    PROMISE_ERROR: 'promise_unhandledrejection_error',

    AJAX_ERROR: 'ajax_error'

}

const MONITOR_NAME = 'page_monitor'

const PAY_MONITOR_NAME = 'page_h5_pay_monitor'

const MEMBER_PAY_MONITOR_NAME = 'page_member_pay_monitor'

export const BindErrorReporter = function(error) {

    if (error) {

        if (error.error) {

            const { colno, lineno } = error

            const { message, stack } = error.error

            // 过滤

            // 客户端会有调用calljs的场景 可能有一些未知的calljs

            if (message && message.toLowerCase().indexOf('calljs') !== -1) {

                return

            }

            sa.track(MONITOR_NAME, {

            //属性

            })

        } else if (error.target) {

            const type = error.target.nodeName.toLowerCase()

            const monitorType = type + '_error'

            const src = error.target.src

            sa.track(MONITOR_NAME, {

            //属性

            })

        }

    }

}

export const UnhandledRejectionReporter = function({

    isAjax = false,

    method,

    data,

    params,

    url,

    headers,

    message,

    stack,

    code

}) {

        if (!isAjax) {

            // 过滤一些特殊的场景

            // 1、自动播放触发问题

            if (message && message.toLowerCase().indexOf('user gesture') !== -1) {

                return

            }

            sa.track(MONITOR_NAME, {

                //属性

            })

        } else {

            sa.track(MONITOR_NAME, {

                //属性

            })

        }

    }

    export const VueErrorReporter = function({ message, stack, vuehook }) {

    sa.track(MONITOR_NAME, {

        //属性

    })

}

export const H5PayErrorReport = ({

    isSuccess = true,

    amount = 0,

    type = -1,

    couponId = -1,

    couponName = '',

    discountAmount = 0,

    reason = '',

    orderid = 0,

}) => {

    // 事件名:page_member_pay_monitor

    sa.track(PAY_MONITOR_NAME, {

        //属性

    })

}

以上,通过sentry的sa.track进行上报,具体不作展开

输出与预警

数据被上报到大数据平台,被存储到hdfs中,然后我们直接做定时任务读取hdfs进行一定的过滤通过钉钉webhook输出到钉钉群,另外如果有需要做数据备份可以通过hdfs到数据仓库再到kylin进行存储。

总结

数据监控对于大的,特别是涉及营收的平台是必要的,我们在设计项目的时候一定要考虑到,最好能说服服务端,让他们服务端也提供相应的代码监控。ngnix层或者云端最好也来一层。严重的异常可以直接给你打电话,目前云平台都有相应支持。这样有异常及时发现,锅嘛,接到手里就可以精准扔出去了。

本文转载于:

https://juejin.cn/post/7244363578429030459

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 

标签:pay,const,monitor,空手,--,百分百,ajax,error,message
From: https://www.cnblogs.com/smileZAZ/p/17572049.html

相关文章

  • springboot~redisson中使用lua脚本的问题
    起因事情是这样的,我在通过redission进行限流时,用到了在lua脚本里进行数值计算,而我在本地测试过程中,发现所有tonumber()方法时,返回值都是nil,这个原因最后找到了,是没有配置序列化的方式,出现错误提示如下:org.redisson.client.RedisException:ERRErrorrunningscript(calltof_......
  • linux系统编程学习笔记
    IO当系统调用io与标准io都能完成相同功能时,优先使用标准io因为不同操作系统提供的系统调用不同,但标准io是之上的封装,不会随着系统的不同改变另外标准io可以合并系统调用,加速如标准io如fopen,在linux下依赖open,在windows下依赖openfile标准IO与系统IO区别一个吞吐量大(即先缓存......
  • Kong API Gateway 配置文件详解
    一、前言Kong配置文件是Kong服务的核心文件,它配置了Kong以怎样的方式运行,并且依赖于这个配置生成Nginx的配置文件,本文通过解读Kong配置文件,以了解Kong的运行和配置。在成功安装Kong以后,会有一个名为kong.conf.default默认的配置文件示例,如果是通过包管理器安装的,通常位于/etc/k......
  • CentOS 7密码忘记修改不成功失败
    重置密码(过程和https://blog.csdn.net/drnrrwfs/article/details/126801657文章一样)也提示成功,但是登录就是提示密码不对。解决方法:你可能重置错用户了。系统安装时候就新建了其他用户,而不是默认的root用户。以下是过程分析:1.重置先看看用户1000的ID名是啥,这里是......
  • Arthas浅用
    安装curl-Ohttps://arthas.aliyun.com/arthas-boot.jar使用java-jararthas-boot.jar--target-ip192.168.150.38##可以在浏览器上访问http://192.168.150.38:3658/##常用命令##看板dashboard##dump文件heapdump--live/tmp/dump.hprof##火焰图profilers......
  • MINIO配置TLS访问
    服务端证书生成opensslgenrsa-outca.key2048opensslreq-x509-new-nodes-keyca.key-subj"/CN=*.*.*.*"-days365-outca.crtopensslgenrsa-outserver.key2048opensslreq-new-nodes-keyserver.key-subj"/CN=*.*.*.*"-outserver.cs......
  • linux删除文件、文件夹
    linux删除文件夹  1、除文件夹实例:rm-rf/var/log/httpd/access 将会删除/var/log/httpd/access目录以及其下所有文件、文件夹 2、删除文件使用实例:rm-f/var/log/httpd/access.log 将会强制删除/var/log/httpd/access.log这个文件......
  • MySQL之order by优化
    MySQL之orderby优化.Usingfilesort:通过表的索引或全表扫描,读取满足条件的数据行,然后在排序缓冲区sortbuffer中完成排序操作,所有不是通过索引直接返回排序结果的排序都叫FileSot排序。Usingindex:通过有序索引顺序扫描直接返回有序数据,这种情况即为usingindex,不需要......
  • Linux中内核线程可以被抢占吗?
    1背景 说起抢占,需要关注服务器上Linux内核中的CONFIG_PREEMPT_xxx采用的何种模式,下面是几个比较常见系统的配置方式例如REHL以及centos7使用的是CONFIG_PREEMPT_VOLUNTARY又例如SLES以及龙蜥OS使用的是CONFIG_PREEMPT_NONE 咱们这里要分析的就是在CONFIG_PREEMPT_VOLUN......
  • 大熊猫直播还没有看?TSINGEE轻松打造动物园直播方案,在线看,时时看~
    最近旅居韩国的大熊猫爱宝喜添双胞胎,新闻迅速登上了热搜。不仅爱宝、乐宝、福宝,国内萌萌的花花、阳光开朗大男孩西直门三太子萌兰等也长期霸占各大平台的热搜词条。在成都大熊猫繁育研究基地,络绎不绝的游客们为了一睹“顶流女明星”花花的芳容,不惜排队半天。根据公开资料显示,顶流......