Coder Social home page Coder Social logo

badjs-report's Introduction

badjs-report -- 前端日志上报与JS异常监控

Build Status Gitter

Author

caihuiji yorts52

Install

$ npm install badjs-report
$ bower install https://github.com/BetterJS/badjs-report.git
$ lego install badjs-report --save

Getting Started

badjs-report 必须在所有类库之前加载并初始化。 但是要在 jquery、seajs、requrejs等类库后调用spyAll()。

初始化
BJ_REPORT.init({
  id: 1                                 // 不指定 id 将不上报
});
配置说明
BJ_REPORT.init({
  id: 1,                                // 上报 id, 不指定 id 将不上报
  uin: 123,                             // 指定用户 id, (默认已经读取 qq uin)
  delay: 1000,                          // 延迟多少毫秒,合并缓冲区中的上报(默认)
  url: "//badjs2.qq.com/badjs",         // 指定上报地址
  ignore: [/Script error/i],            // 忽略某个错误
  random: 1,                            // 抽样上报,1~0 之间数值,1为100%上报(默认 1)
  repeat: 5,                            // 重复上报次数(对于同一个错误超过多少次不上报)
                                        // 避免出现单个用户同一错误上报过多的情况
  onReport: function(id, errObj){},     // 当上报的时候回调。 id: 上报的 id, errObj: 错误的对象
  submit: null,                         // 覆盖原来的上报方式,可以自行修改为 post 上报等
  ext: {},                              // 扩展属性,后端做扩展处理属性。例如:存在 msid 就会分发到 monitor,
  offlineLog : false,                   // 是否启离线日志 [默认 false]
  offlineLogExp : 5,                    // 离线有效时间,默认最近5天
});

BJ_Report 是重写了 window.onerror 进行上报的,无需编写任何捕获错误的代码

手动上报
BJ_REPORT.report("error msg");

BJ_REPORT.report({
  msg: "xx load error",                 // 错误信息
  target: "xxx.js",                     // 错误的来源js
  rowNum: 100,                          // 错误的行数
  colNum: 100,                          // 错误的列数
});

try{
    // something throw error ...
}catch(error){
    BJ_REPORT.report(e);
}
延迟上报
BJ_REPORT.push("error msg");

BJ_REPORT.push({
  msg: "xx load error",                 // 错误信息
  target: "xxx.js",                     // 错误的来源js
  rowNum: 100,                          // 错误的行数
  colNum: 100,                          // 错误的列数
});

BJ_REPORT.report();
 上报离线日志  
BJ_REPORT.reportOfflineLog();

什么是离线日志? #25

用法
//初始化
BJ_REPORT.init({id: 1})

//主动上报错误日志
BJ_REPORT.report("error msg 2");

//info上报,用于记录操作日志
BJ_REPORT.info("info");

//可以结合实时上报,跟踪问题; 不存入存储
BJ_REPORT.debug("debug");

//记录离线日志  
BJ_REPORT.offlineLog("offlineLog");

高级用法

script error 的错误,怎么解决? #3

由于 BJ_Report 只是重写了onerror 方法而已,而且浏览器的跨域问题不能获得外链 javascript 的错误,所以使用tryJs 进行包裹。

包裹jquery

BJ_REPORT.tryJs().spyJquery();

包裹 jquery 的 event.add , event.remove , event.ajax 这几个异步方法。

包裹 define , require

BJ_REPORT.tryJs().spyModules();

包裹 模块化框架 的 define , require 方法

包裹 js 默认的方法

BJ_REPORT.tryJs().spySystem();

包裹 js 的 setTimeout , setInterval 方法

包裹 自定义的方法

var customFunction = function (){};
customFunction  = BJ_REPORT.tryJs().spyCustom(customFunction );

// 只会包裹 customOne  , customTwo
var customObject = { customOne : function (){} , customTwo : function (){} , customVar : 1}
BJ_REPORT.tryJs().spyCustom(customObject );

包裹 自定义的方法或则对象

运行所有默认的包裹

//自动运行 SpyJquery , SpyModule , SpySystem
BJ_REPORT.tryJs().spyAll();

update log

v1.3.3
  1. BUGFIX
v1.3.1
  1. 支持离线日志
  2. 支持自动上报离线日志
v1.2.3
  1. BUGFIX
v1.2.1
  1. 增加去除重复参数
  2. 修复了 webpack 引入问题
  3. BUGFIX
v1.1.8
  1. 项目重命名后更新项目路径(注: 之前名字为report)
v1.1.7
  1. 合并上报的问题
  2. 增加sea.use try-catch 处理
v1.1.6
  1. add BJ_ERROR hash
v1.1.5
  1. bugfix
v1.1.4
  1. 增加info 和 debug 接口
  2. report 增加对 error 对象处理
  3. 处理 [Object event] 问题
v1.1.3
  1. bugfix
v1.1.2
  1. 增加抽样参数 random
v1.1.1
  1. seajs 兼容的BUG修复
  2. 增加 ext 属性,用户可以自己定义里面的值上报
v1.1.0
  1. 增加对seajs 模块化的包裹
  2. 增加对IE下面的错误的上报
v1.0.5
  1. 修复异步环境下抛给浏览器的BUG也会上报,
  2. 修复ignore 数组判断的迭代的问题
v1.0.4
  1. 修复 spy 插件增加在 异步环境中,抛出异常捕获后,再抛给浏览器
  2. 修复 增加在异步环境中,抛出异常,捕获后,将错误信息输出
  3. 增加onReport 回调
v1.0.3
  1. 修复说明文档
v1.0.2
  1. 修复 uin 的正则
v1.0.1
  1. 增加 spy 插件
v1.0.0
  1. 功能上线

badjs-report's People

Contributors

caihuiji avatar chyingp avatar guocover avatar loskael avatar tailgo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

badjs-report's Issues

请求的返回应该怎么写?

如果返回一个json格式,会提示格式错误,不返回的话又报404,虽然不影响功能,但是是否避免这些报错信息?

QuotaExceededError: Dom exception 22

这个是localstorage 容量的超过了浏览器的限制。
不同浏览器的有不同的限制,主流的浏览器是5M,但是 ios 下的 safari 是 2M。

ios error msg bug fixed.

Error object on ios has no msg property, by fixing the error msg report on ios, finding an error on iphones becomes easier.

bj-report-tryjs-1.3.1: [BJ-REPORT] TypeError: foo.apply is not a function

版本:最新的 1.3.1

浏览器:Linux Chrome

调用:

head 里:

BJ_REPORT.init({ id: 4, url: "******/badjs", ignore: [/Script error/i], repeat: 20 });

body 里:

BJ_REPORT.tryJs().spyAll();

页面里用了 jquery 和 seajs ,spyAll 是在最后调用的。页面只要 resize 就会抛出如下异常:

[BJ-REPORT] TypeError: foo.apply is not a function
    at http://******/lib/badjs-report/1.3.1/bj-report-tryjs.js:604:28

查看源代码后发现是这一段:

var cat = function(foo, args) {
        return function() {
            try {
                return foo.apply(this, args || arguments);
            } catch (error) {

                _onthrow(error);

                //some browser throw error (chrome) , can not find error where it throw,  so print it on console;
                if (error.stack && console && console.error) {
                    console.error("[BJ-REPORT]", error.stack);
                }

                // hang up browser and throw , but it should trigger onerror , so rewrite onerror then recover it
                if (!timeoutkey) {
                    var orgOnerror = global.onerror;
                    global.onerror = function() {};
                    timeoutkey = setTimeout(function() {
                        global.onerror = orgOnerror;
                        timeoutkey = null;
                    }, 50);
                }
                throw error;
            }
        };
    };

调试后发现 foo 为整数 1000 ,args 为整数 0 。

是否支持https部署

网站最近切https, badjs部署的如果是http请求无法发出

需要

  1. 支持https和http都同时存在

代码比较奇怪的几点

1、
image
不是很明白为什么我自己提交,你要给我一个GET的 url,我还需要自己拆吗?

2、
image

image

image

为什么同一个error,会被processError给解析一遍,然后触发两次onReport?

[Object Event]

[Object Event] 是某些浏览器,特别是移动端上面,当script 资源加载失败的时候,会触发 onerror 的回调,而且onerror 的第一个参数是 event 对象, 详细见 #4

image

Converting circular structure to JSON

error.stack 进行 stringify是会有该错误,主要是error.stack某些情况下(或者某些浏览器下)是 [object event] 对象,对该对象进行stringify是会报错。
该对象的target对象指向了DOM节点,DOM节点本身有循环引用的情况,简单看下ownerDocument这个属性,指向的document对象

BJ_REPORT.tryJs().spyCustom(

BJ_REPORT.tryJs().spyCustom((customFunction)

有时候需要吧customFunction的静态属性也复制一下,不然会影响原始customFunction的使用

请问1.3版本什么时候发布?

是的 packjson.json version 版本没有改?
用1.2.3 版本,BJ_REPORT 对象只有以下方法
debug: function (e){}
info: function (e){}
init: function (e){}
push: function (e){}
report: function (e){}
tryJs: function (e){}

没和离线日志有关的方法。

BJ_REPORT.push方法中 最后也调用了_process_log

BJ_REPORT.push方法中 最后也调用了_process_log,
这里是不是多余?bj-report.js里调用BJ_REPORT.push(xx)的地方,很多地方都会再次调用_process_log的
因为BJ_REPORT.push是被设计成推入日志缓存池_log_list即可,不用在方法末尾在调用一次_process_log吧?

IE 10 以下 , setTimeout and setInterval 奇怪现象

  • IE10 以下版本中 setTimeout 为只读方法,无法篡改替换 , 而 window.setTimeout 是可以修改的
    qq 20150524233244
    所以,我们只对 window.setTimeout 进行切面处理。当然我们为了保证统一,也只对window.setInterval 进行了同样处理
  • IE6、IE7、IE8中window.setTimeout和window.setInterval为Object,非Function,没有继承apply和call方法
    所以不能对 window.setTimeout 或 window.setInterval 像其他切面处理那样直接进行 apply 。

对于init里面的repeat参数

有一个问题,对于日志去重的处理:

1.repeat参数貌似对离线日志不生效,离线日志会存入重复的日志信息,上报离线日志的时候貌似也没有去重,感觉这样会导致重复上传大量相同错误日志;

2.repeat参数去重是通过一个全局对象_log_map实现的,如果刷新页面,则会重新new 一个_log_map对象,刚才已经达到重复上线的话,刷新之后又会进行上报。

建议:以上两个问题感觉可以统一处理,上报info的时候即实时上报的时候也会存入离线日志,存入时去重存储,根据indexdb里面的是否有该类型的错误进行选择上报,有且数量已达上线,就不在上报

Script error

一、Script Error规范

script Error 是什么?

是外部加载的JS 抛出异常的时候, 出于安全方面的考虑,js错误信息中可能包含一些敏感信息,比如用户名、权限提示等,希望能够把这类信息屏蔽。目前跨域的场景下会触发这种安全限制,window.onerror无法获得具体出错信息,而只能得到Script error 0 0

image

http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#runtime-script-errors

二、解决ScriptError 问题

目前业内有以下两种方式:

  • 响应头增加 access-control-allow-orgin (以下简称AC)
  • 切面包裹入口函数, try-catch (badjs-report 方案)

响应头增加 access-control-allow-orgin

1.1 Access-Control-Allow-Origin 回包header里设置允许cros的域
1.2 script 标签增加 crossorigin="anonymous"

当1和2同时满足就拥有了打开script errors的钥匙,window.onerror就能获得详细出错信息了

哪些浏览器能打开muted errors?
ie 6-10 没有同源限制的问题
Chrome 和 Firefox支持,Safari 不支持,
所以跨域的js想在Safari下获取出错详情信息,只能用try-catch了,onerror是无能为力了。

access-control-allow-orgin 配置问题:

由于值不能设置多值,而且设置 * , 允许任何域名使用是一个很不安全的设置,所以一般会根据 浏览器请求头 refer 或则 orgin ,判断是不是白名单内的域名,是的就响应回对应的域名或则* (响应头不支持返回 *.qq.com),。当然如果cdn只对一个业务服务也可以写死域名

script 标签上面的 crossorigin 配置问题

1.anonymous(默认)
不能带cookie

副作用,当 AC 的设置不是 * 或者不等于origin时,js直接不加载

2.use-credentials
能带上cookie

副作用,当AC的设置不等于origin时,js直接不加载(不支持 *通配符了)

目前只有高级浏览器支持,如果闲麻烦可以使用自带的 try-catch 功能

切面包裹入口函数, try-catch

对于基于AMD和jQuery的网站,几乎所有业务函数都是通过回调异步触发的,所以我们只需要将所有异步函数包裹起来就可以捕获到大部分错误:

  • setTimeou ,setInterval
  • $.event.add 和 $.event.remove
  • AJAX
  • 模块入口 define 或则 require
setTimeou ,setInterval

只针对 w3c 现代的浏览器的进行包裹,ie 不进行包裹 #2

$.event.add 和 $.event.remove

没有个dom 都有这两个方法,我们没有办法对全部重写。但是我们发现目前基本都会使用 jquery 或 zepto ,所以我们对 $.event.add 和 $.event.remove 进行了切面处理。

AJAX

跟上面的类似,我们不能重写 ajax ,但是前端开发都使用 jquery ,所以我们重写了 $.ajax

模块入口 define 或则 require

目前前端开发基本都使用了模块化管理,所以模块化的入口是非常好的入口。我们也进行了包裹

监控系统不能查看到历史日志和实时日志,统计日志显示正常统计

拷贝下载的bj-report.js到工程,随后使用如下方法进行初始化

BJ_REPORT.init({
    id: 5,                                // 上报 id, 不指定 id 将不上报
    uin: 1233434,                             // 指定用户 id, (默认已经读取 qq uin)
    delay: 1000,                          // 当 combo 为 true 可用,延迟多少毫秒,合并缓冲区中的上报(默认)
    url: "//**域名**/badjs",         // 指定上报地址
    // ignore: [/Script error/i],            // 忽略某个错误
    random: 1,                            // 抽样上报,1~0 之间数值,1为100%上报(默认 1)
    // repeat: 5,                            // 重复上报次数(对于同一个错误超过多少次不上报)
                                          // 避免出现单个用户同一错误上报过多的情况
    // onReport: function(id, errObj){},     // 当上报的时候回调。 id: 上报的 id, errObj: 错误的对象
    // submit,                               // 覆盖原来的上报方式,可以自行修改为 post 上报等
    ext: {},                               // 扩展属性,后端做扩展处理属性。例如:存在 msid 就会分发到 monitor,
    offlineLog : false,                    // 是否启离线日志 [默认 true]
    offlineLogExp : 5                // 离线有效时间,默认最近5天
  });

可以看到 http://域名/badjs 接口进行正常的上报,而接口 http://域名/offlineAuto 则报错,浏览器显示状态为404,查看服务器日志返回为403.

登录监控系统可以查看统计面板中的数据,历史日志和实时日志面板中均没有正常返回日志记录。

请问出现这些问题的原因是什么?

怎么和angularjs集成使用

在angularJs的controller里写了一个错误,

 $scope.TestReport =function () {
            aaaa
        }

但是捕获不到aaaa未定义的错误

什么是 offlineLog ?

为什么要有 offlineLog?
badjs 本身已经支持 info 级别用于记录用户操作日志。但是腾讯许多业务PV 往往很高,频繁的上报info 级别日志,不仅浪费用户流量,而且也浪费存储。
所以badjs-report1.3 提供了存储在用户本地的日志,而且在离线状态下也可以用。

什么时候用 offlineLog?

  • info、error、debug 上报过多会造成流量的浪费,而且在弱网络下面还会造成流失。
  • info 和 offlineLog 的区别在于 info 不仅会记录离线日志,同时也会实时上报

所以我们建议每个小时高于500左右的上报量,我们可以建议采用offlineLog ,而且我们推荐你使用 offlienLog 详细记录用户的操作日志,便于后面排查问题

offlineLog 原理是什么?
offloneLog 使用浏览器的 indexdb 进行存储日志的,badjs-report 的所有上报都会记录到离线日志中。而且有效期默认是最近5天,所以用户不用担心用户本地的日志过多。

怎么使用?

  • offlineLog 支持用户主动上报,开发者可以提供反馈界面,方便用户直接上报日志。
  • badjs-web 标记某个uin ,当用户登陆后,badjs-report 会向服务检测然后自动上报。

Uncaught ReferenceError: QzoneApp is not defined

设备:android QQ5.5~5.7
原因:下载进度事件会调用QzoneApp.fire()
解决办法:没很好的办法,在window上挂一个空的QzoneApp
window.QzoneApp = {
fire: function() {}
}

_submit_log无法执行

当第一个log为offlinelog时,_log_list会被清空之后执行_submit_log,函数在comboTimeout被重置前返回,导致comboTimeout永远为true,_submit_log不会再执行。

跨域情况下没有对promise封装

跨域情况下unhandledrejection监听不到报错,只能通过catch方法或包裹try-catch,对promise构造函数本身如何包裹try-catch呢

安装bug

我执行:
lego install badjs-report --save
的时候总是提示:
install: badjs-report@stable exit: Object.keys called on non-object
不知道怎么解决

imprt tryJs undefined

import badjs from 'badjs-report';

badjs.init({...}).tryJs(); // 提示 tryJs 不是一个function

通过import方式不能使用tryJs,因为 bj-wrap.js 源码内并没有做相应的模块化处理。 而是简单的复制给 root.BJ_REPORT.tryJS

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.