前端异常监控

技术调研:因不能使用已经成熟的其他插件,如FunDebug(收费),所以需要自己写一个。

实现要求: 将线上的(主要指前端)错误收集起来,动态在本地创建一个文件夹,每天一个文件(以时间命名),只保留7天内的文件

项目技术:Vue.config.errorHandler(项目是vue)

注意:ActiveXObject可以在本地创建文件,但是IE特有的,所以我选择通过node来做

实现

import moment from 'moment';
import axios from 'axios';
let errorType = '';
const errorHandler = (error, vm, info) => {
    let {
        message, // 异常信息
        name, // 异常名称
        script,  // 异常脚本
        line,  // 异常行号
        column,  // 异常列号
        stack // 异常堆栈信息 script, line, column可以从这里面匹配到
    } = error;
    console.log('抛出全局异常');

    let now = moment().locale('zh-cn').format('YYYY-MM-DD HH:mm:ss');
    let data = `${now}
${stack}type:${errorType}`;
    console.log(error, 'error');
    axios.post('/error/errordata', data)
    .then(res => {
        console.log(res.data, '请求成功');
    })
    .catch(error => {
        console.log(error);
    });
};
let GlobalError = {
    install: (Vue, type) => {
        errorType = type;
        Vue.config.errorHandler = errorHandler;
        Vue.mixin({
            beforeCreate() {
                const methods = this.$options.methods || {};
                Object.keys(methods).forEach(key => {
                    let fn = methods[key];
                    this.$options.methods[key] = function (...args) {
                        let ret = fn.apply(this, args);
                        if (ret && typeof ret.then === 'function' && typeof ret.catch === 'function') {
                            return ret.catch(errorHandler);
                        } else { // 默认错误处理
                            return ret;
                        }
                    };
                });
            }
        });
        Vue.prototype.$throw = errorHandler;
    }
};
export default GlobalError;

 node

let h = require("http");
let fs = require('fs');
const url = require('url');
let path = require('path');
let moment = require('moment');
h.createServer((req, res) => {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('bug统计');
    let parsed_url = url.parse(req.url);
    let errorname = '';
    if (parsed_url.pathname === '/error/errordata') { //匹配路由
        // 定义了一个post变量,用于暂存请求体的信息
        let postData = '';
        let date = '';
        req.on('data', chunk => { //在on函数中获取请求体
            postData += chunk; //请求数据过大时会自动进行多次请求

        })
        req.on('end', () => { //请求结束
            res.writeHead(201, { 'content-type': 'text/plain' });
            res.end(postData);
            let last7 = moment().subtract(7, 'days').format('YYYY-MM-DD');
            date = postData.slice(0, 10);
            errorname = postData.split("type:")[1] + 'Error';
            // date = "2020-06-24";
            let newpath = `/Users/xxxxx/Desktop/${errorname}/`;
            // let newpath = path.join(__dirname, `../${errorname}/`)
            fs.exists(newpath, exists => {
                // fs.exists测试某个路径下的文件是否存在。回调函数包含一个参数exists,true则文件存在,否则是false。
                if (!exists) {
                    // fs.mkdir mode:目录权限(读写权限)  默认0777
                    fs.mkdir(newpath, 0777, err => {
                        if (err) {
                            console.log(err, '创建文件夹错误');
                        } else {
                            fs.writeFile(newpath + `${date}.txt`, `${postData}`, null, err => {
                                if (err) {
                                    console.error(err, '写入错误');
                                } else {
                                    console.log('写入成功');
                                }
                            });
                        }
                    });
                }
                else {
                    fs.exists(newpath + `${date}.txt`, exists =>{
                        if (exists) {
                            fs.appendFile(newpath + `${date}.txt`, `

${postData}`, 'utf-8', err => {
                                if (err) {
                                    console.log(err, '追加错误');
                                    return false;
                                }
                                console.log('追加成功!!!');
                            });
                        }
                        else {
                            fs.writeFile(newpath + `${date}.txt`, `${postData}`, null, err => {
                                if (err) {
                                    console.error(err, '写入错误');
                                } else {
                                    console.log('写入成功');
                                }
                            });
                        }
                    })
                }
                fs.readdir(newpath, (err, files) => {
                    if (err) {
                        return console.log('目录不存在')
                    }
                    files.forEach(item => {
                        let time = item.slice(0, 10);
                        // let isBefore = false;
                        let isBefore = moment(time).isBefore(last7);
                        if (isBefore) {
                            fs.unlink(newpath + item, err => {
                                if (err) {
                                    console.log(err, '删除错误');
                                    return false;
                                }
                                console.log('删除文件成功');
                            });
                        }
                    });
                })
            });
        })
    }
}).listen(8888);
console.log("服务器开启啦~~");

 实现之后: 

原文地址:https://www.cnblogs.com/chenjingran-0119/p/13215151.html