Solo  当前访客:0 开始使用

前端日志打印收集 - 前端监控之数据收集篇


日志,一般大家听到的都是后台的日志概念。

前端由于其特殊性,console输出的我们认为是控制台调试信息

很多时候本地开发,我们定位问题还是需要debug模式进行逐行定位,但是当线上问题发生时,我们并不具备远程debug的能力或条件,那么如何进行快速问题定位呢?

问题主要分为以下几种

1. 由js错误引发,这种可以通过js堆栈还原 解决大部分问题

2. 由于后台服务异常导致的, 这种可以通过数据分析请求 解决问题

3. 还有一些可能是由于用户操作的原因,并没有明确的异常发生, 这时候就需要通过日志的方式记录关键节点的操作

 

什么是前端日志

日志至少应该具备以下几个要素

①. 分级别

日志,是我们用于输出系统消息的一些节点, 但是由于业务、编码优先级的不同,日志需要通过定义不同的基本来进行输出

chrome上可以看到对级别做了几个划分

在console的api中,我们可以将类别划分成一下

②. 多种记录方式

开发时: 我们使用console输出,便于调试

测试时:一般可以关闭输出

生产时:应该需要输出到服务端,用于定位

③. 输出级别

可第一点的级别不同,输出级别用于我们对日志的输出做更详细的控制

生产时:我们通常只需要输出级别较高的日志, 这时候我们会发现上表中的级别并不够用,这时候我们可以对输出级别在进行划分

④. 控制开关

用于控制日志的开启关闭

 

如何记录前端日志

1. 通过自定义代理

function wrapConsole(console, level, callback) {
var originalConsoleLevel = console[level];
var originalConsole = console;

if (!(level in console)) {
    return;
}

console[level] = function() {
    var args = [].slice.call(arguments);

    var msg = '' + args.join(' ');
    var data = {level: level, extra: {arguments: args}};

    if (level === 'assert') {
        if (args[0] === false) {
            msg = 'Assertion failed: ' + (args.slice(1).join(' ') || 'console.assert');
            data.extra.arguments = args.slice(1);
            callback && callback(level,msg, data);
        }
    } else {
        callback && callback(level,msg, data);
    }

    if (originalConsoleLevel) {
    Function.prototype.apply.call(originalConsoleLevel, originalConsole, args);
    }
};

};

 或者使用proxy

function warpConsole(console, level, callback) {
let handler = {
apply (target, ctx, arg) {
var args = [].slice.call(arg);

    var msg = '' + args.join(' ');
    var data = {level: level, extra: {arguments: args}};

    if (level === 'assert') {
        if (args[0] === false) {
            msg = 'Assertion failed: ' + (args.slice(1).join(' ') || 'console.assert');
            data.extra.arguments = args.slice(1);
            callback && callback(level,msg, data);
        }
    } else {
        callback && callback(level,msg, data);
    }
   return Reflect.apply(...arguments);

}
};
console[level] = new Proxy(console[level], handler)
}

 2. 加入分级管理

首先定义级别

const levelMap = {trace: 5, log:5, dir:5, debug: 10, info: 15, warn: 25, error: 30, fatal: 40}

 定义控制开关

this.consoleSettings= utils.objectMerge({
clientOn: false,
serverOn: false,
level: "error"
}, options.console || {})

 

代码中加入控制点

在warpConsole中回调源方法处加入级别和开关判断

let limitLevel = levelMap[reporter.consoleSettings.level] || 0
if(reporter.consoleSettings.clientOn && levelMap[level] >= limitLevel ) {
// 回调源方法
}

在发送到服务端的方法中同样加入开关

 

var consoleMethodCallback = function(level, msg, data) {
let limitLevel = levelMap[reporter.consoleSettings.level] || 0
if(reporter.consoleSettings.serverOn && levelMap[level] >= limitLevel ) {
if(data.extra) {
try {
data.extra = JSON.stringify(data.extra)
}catch(e){
data.extra = JSON.stringify({arguments: msg})
}
}
var session = reporter._getSessionId();
data.m_uuid = session.sid;
// 发送到服务器
reporter.captureInfo("console_data", data, {category: "console", filter: "track"})
}
};

    utils.each(['debug', 'info', 'warn', 'error', 'log'], function(_, level) {
        wrapMethod(console, level, consoleMethodCallback);
    });

3. 数据收集

console数据只是用于辅助的数据, 建议使用批量发送的方式收集


标题:前端日志打印收集 - 前端监控之数据收集篇
作者:hugh0524
地址:https://blog.uproject.cn/articles/2019/07/25/1564021229141.html

, , , 0 0