# vue捕捉统计错误日志

\\ main.js

//日志搜集-初始化
import ErrorLog from '@/utils/ErrorLog';
ErrorLog._init({
  projectName: 'web端',
  projectCode: 'xzWeb',
  url: '/api/logs/saveLogsData',
});

//日志搜集-错误
Vue.config.errorHandler = function (error, vm, info) {
  console.error(error);
  ErrorLog._notifyError({ type: 'js_error', error: { message: error.message, stack: error.stack } });
};
//日志搜集-警告
Vue.config.warnHandler = function (message, vm, stack) {
  console.error(message);
  ErrorLog._notifyWarn({ type: 'js_warn', warn: { message, stack } });
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
\\ ErrorLog.js
const errorLog = {
  config: {
    //项目名称
    projectName: 'xz-project',
    //项目标识
    projectCode: 'xz-',
    //脚本名称
    scriptVersion: '1.0',
    //运行环境
    env: 'dev',
    //接口
    url: '',
  },
  //请求参数处理
  formatParams: (data) => {
    var arr = [];
    for (var name in data) {
      arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));
    }
    arr.push(('v=' + Math.random()).replace('.', ''));
    return arr.join('&');
  },
  //获取设备
  getDevices: (_) => {
    let ua = navigator.userAgent;
    let devices = ['Android', 'iPhone', 'ymbianOS', 'Windows Phone', 'iPad', 'iPod', 'Windows'];
    return devices.filter((item) => {
      return ua.indexOf(item) > 0;
    })[0];
  },
  //请求方法
  Ajax: (options) => {
    options = options || {};
    options.type = (options.type || 'GET').toUpperCase();
    options.dataType = options.dataType || 'json';
    let params = errorLog.formatParams(options.data);
    let xhr = '';
    if (window.XMLHttpRequest) {
      xhr = new XMLHttpRequest();
    } else {
      xhr = new ActiveXObject('Microsoft.XMLHTTP');
    }
    xhr.onreadystatechang = function () {
      if (xhr.readyState === 4) {
        let status = xhr.status;
        if (status >= 200 && status < 300) {
          options.success && options.success(xhr.responseText, xhr.responseXML);
        } else {
          options.fail && options.fail(status);
        }
      }
    };
    if (options.type === 'GET') {
      xhr.open('GET', options.url + '?' + params, true);
    } else {
      xhr.open('post', options.url, true);
      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
      xhr.send(params);
    }
  },
  //初始化
  _init: (config) => {
    let { url, env, projectName, projectCode } = config || {};
    errorLog.config = { url, projectName, env, projectCode };
    //重写console.error
    window.console.error = ((errorFn) => {
      return function () {
        errorFn.apply(console, arguments);
        if (arguments[0] === 'network_error') {
          let { status, api, params, message = '' } = arguments[1];
          errorLog._notifyError({ type: 'network_error', error: { status, api, params: JSON.stringify(params), message } });
        }
      };
    })(console.error);
  },
  //上报错误-error
  _notifyError: ({ type, error }) => {
    let { message = '', stack = '', api, params, status } = error;
    let title = document.title,
      url = window.location.href,
      ua = window.navigator.userAgent,
      os = errorLog.getDevices();
    errorLog._logReport({ message, stack, title, url, ua, os, type, status, params, api });
  },
  //上报错误-warn
  _notifyWarn: ({ type, warn }) => {
    const { message, stack } = warn;
    let title = document.title,
      url = window.location.href,
      ua = window.navigator.userAgent,
      os = errorLog.getDevices();
    errorLog._logReport({ message, stack, title, url, ua, os, type });
  },
  //错误数据上报
  _logReport: (data) => {
    if (process.env.NODE_ENV !== 'dev') {
      setTimeout(() => {
        // 把错误信息发送给后台
        errorLog.Ajax({
          url: process.env.VUE_APP_ERROR_LOG_URL + errorLog.config.url, // 请求地址
          type: 'POST', // 请求方式
          data: { projectName: errorLog.config.projectName, projectCode: errorLog.config.projectCode, ...data }, // 请求参数
          dataType: 'json',
          success: function () {},
          fail: function () {},
        });
      }, 0);
    }
  },
};
export default errorLog;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
Last Updated: 2/17/2023, 3:14:55 PM