在uniapp开发中,我们都会打调试包,通过hbuilderX的日志窗口进行接口及前端内容调试,但是一但上线后,遇到接口或app异常时再想要查看异常日志就只能重新运行调试包进行查看,非常麻烦,也非常低效,我们今天提供一个5分钟就能上线的异常信息汇总平台。
本文基于企业开发者平台(www.21ds.cn)的日志管理功能进行整理。
首先登录会员中心,点击左侧“日志管理”-“站点列表”-“新增站点”,根据提示填写内容,截图如下:
- 日志参数:可自定义推送的字段名称、字段名及是否在列表页显示
- 支持搜索参数:可搜索指定字段
- SecretKey:推送数据时生成签名使用,请勿泄漏
- 是否发送通知:可选择收到日志时是否推送通知,可选择推送至短信、邮件、企微应用、企微群机器人、钉钉群机器人、飞书群机器人等平台,详见:消息推送服务
- 标签页预览参数聚合:可在一个字段中聚合其他字段内容,方便信息聚合预览
- 状态:选择启用,不启用时将收不到日志推送
提交后即可看到刚才新增的站点,如图:
- ID:用于推送时使用,均为LSI前缀的字符串
根据日志推送文档说明进行日志推送即可,文档地址:http://doc.21ds.cn/detail?doc=4731341806141859/4840069379677989
下面以uniapp为例,将详细说明如何推送异常信息到企业开发者平台。
首先建立一个log.js文件,内容如下:
需修改内容:
- 请先确保已安装js-md5,未安装可通过
npm install --save js-md5
安装 - dev_key(通过[系统管理]-[平台设置]处获得,如果没有,点击“重置”生成即可)
- lsi_id:站点ID,见上图
- secretKey:与站点ID匹配的secretKey,否则会提示签名错误
import md5 from 'js-md5'
var dev_key = 'DEV-axxxxxb'
export default {
devSignature: function(data, secretKey) {
if (data['sign'] != undefined){
delete data['sign'];
}
var parameters = {};
for (var k in data) {
parameters[k] = data[k];
}
var sortedKey = Object.keys(parameters).sort();
var parameters2 = {};
for (var i = 0; i < sortedKey.length; i++) {
parameters2[sortedKey[i]] = parameters[sortedKey[i]];
}
var buff = '';
for (var k2 in parameters2) {
buff = buff + k2 + parameters2[k2];
}
buff = secretKey + buff + secretKey;
return md5(buff).toUpperCase();
},
getCurrentDateTime: function() {
const now = new Date();
const year = now.getFullYear();
const month = ('0' + (now.getMonth() + 1)).slice(-2);
const day = ('0' + now.getDate()).slice(-2);
const hours = ('0' + now.getHours()).slice(-2);
const minutes = ('0' + now.getMinutes()).slice(-2);
const seconds = ('0' + now.getSeconds()).slice(-2);
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
},
android_ios: function() {
let type = '';
switch (uni.getSystemInfoSync().platform) {
case 'android':
type = 'android';
break;
case 'ios':
type = 'ios';
break;
default:
type = 'other';
break;
}
return type;
},
deviceInfo: function(){
return uni.getSystemInfoSync();
},
generateRequestId: function() {
const timestamp = Date.now().toString(36);
const randomString = Math.random().toString(36).substring(2, 8);
return `${timestamp}_${randomString}`;
},
getPath: function() {
let pages = getCurrentPages();
let route = pages[pages.length - 1].route;
console.error('当前页面路径:' + route)
return route
},
pushLog: function(data){
var postData = {}
for(let key in data){
postData[key] = data[key]
}
var info = this.deviceInfo();
postData['device']=info['deviceModel']
postData['os_version']=info['osName']+' '+info['osVersion']
postData['app_version']=info['appVersion']
postData['lsi_id']='LSI4xxxx4'
postData['dev_key']=dev_key
postData['time']=this.getCurrentDateTime()
postData['sign']=this.devSignature(postData,'secretKey')
uni.request({
url:'http://21ds.cn/log/push',
method:'POST',
data: postData,
success: (res) => {
console.log(res);
}
})
},
pushReqErrLog: function(data){
var postData = {}
for(let key in data){
postData[key] = data[key]
}
var info = this.deviceInfo();
postData['device']=info['deviceModel']
postData['os_version']=info['osName']+' '+info['osVersion']
postData['app_version']=info['appVersion']
postData['lsi_id']='LSI4xxx'
postData['dev_key']=dev_key
postData['time']=this.getCurrentDateTime()
postData['sign']=this.devSignature(postData,'secretKey')
uni.request({
url:'http://21ds.cn/log/push',
method:'POST',
data: postData,
success: (res) => {
console.log(res);
}
})
}
}
在uniapp的main.js中添加以下代码,用于记录Uniapp前端异常记录
import log from '@/js_sdk/log.js' #请修改为你文件的路径
Vue.config.errorHandler = function(err, vm, info) {
var data = {}
if (err.isAxiosError) {
data['url'] = err.config.url
}
data['error'] = err + ' [ ' + info + ' ]'
data['path'] = log.getPath()
console.error(JSON.stringify(data))
log.pushLog(data)
}
在uniapp中我使用的是axios进行网络请求的,所以在axios中使用拦截器进行接口异常记录,代码如下:
http.interceptors.response.use(response => {
_reslog(response)
console.log(response)
return response
}, error => {
var data = {}
data['url'] = error.config.url
data['method'] = error.config.method
data['data'] = error.config.data
data['headers'] = JSON.stringify(error.config.headers)
data['error'] = error.message
data['path'] = log.getPath()
data['request_id'] = log.generateRequestId()
console.error(JSON.stringify(data))
data['response'] = error.response.data
log.pushReqErrLog(data)
return Promise.reject(' 请求ID:'+data['request_id'])
})
这样就能实现接口异常及前端异常时自动记录功能,便于问题排查,我将我使用的站点配置一并贴在下方,供参考使用:
前端异常日志参数配置:
错误|error|1
路径|path|1
APP版本|app_version|1
设备信息|device|1
系统版本|os_version|1
请求ID|request_id|1
记录时间|time|1
接口异常日志参数配置:
URL|url|1
类型|method|1
参数|data|1
请求头|headers
APP版本|app_version|1
设备信息|device|1
系统版本|os_version|1
错误|error|1
路径|path|1
返回内容|response
请求ID|request_id|1
记录时间|time|1
全部配置好后,如果有异常,会将异常日志推送至企业开发者平台,可登录查看,如图:
点击“详情”可查看日志详情,如图:
- 鼠标放到文本框上后会在左侧出现“在新标签页显示”按钮,点击可在浏览器新标签页查看内容
效果图:
上图就是设置了“标签页预览参数聚合”后显示的内容,如果不设置,将默认显示原字段内容
至此结束,如有疑问,可通过企业开发者官网上的微信群加群咨询。