日誌,通常你們聽到的都是後臺的日誌概念。html
前端因爲其特殊性,console輸出的咱們認爲是控制檯調試信息前端
不少時候本地開發,咱們定位問題仍是須要debug模式進行逐行定位,可是當線上問題發生時,咱們並不具有遠程debug的能力或條件,那麼如何進行快速問題定位呢?chrome
由js錯誤引起,這種能夠經過js堆棧還原 解決大部分問題api
因爲後臺服務異常致使的, 這種能夠經過數據分析請求 解決問題服務器
還有一些多是因爲用戶操做的緣由,並無明確的異常發生, 這時候就須要經過日誌的方式記錄關鍵節點的操做session
日誌至少應該具有如下幾個要素app
日誌,是咱們用於輸出系統消息的一些節點, 可是因爲業務、編碼優先級的不一樣,日誌須要經過定義不一樣的基原本進行輸出post
chrome上能夠看到對級別作了幾個劃分測試
在console的api中,咱們能夠將類別劃分紅一下ui
開發時: 咱們使用console輸出,便於調試
測試時:通常能夠關閉輸出
生產時:應該須要輸出到服務端,用於定位
可第一點的級別不一樣,輸出級別用於咱們對日誌的輸出作更詳細的控制
生產時:咱們一般只須要輸出級別較高的日誌, 這時候咱們會發現上表中的級別並不夠用,這時候咱們能夠對輸出級別在進行劃分
用於控制日誌的開啓關閉
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)
}
複製代碼
首先定義級別
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);
});
複製代碼
console數據只是用於輔助的數據, 建議使用批量發送的方式收集(收集方式由後續文章分享~)