@lx-frontend/multi-track
v1.1.3
Published
sls 日志上传功能,当前支持小程序、web
Readme
@lx-frontend/multi-track
sls 监控日志上报
用法
前提
- 在阿里云 sls 创建好
project和store - store 需要开启:
WebTracking - 小程序项目需要再后台
request域名增加上述project域名 - 项目需要接入
@lx-frontend/taro-plugin-monitor
示例配置
- 在 taro 配置增加
taro-plugin-monitor使用,在config/index.js
plugins: [
[
'@lx-frontend/taro-plugin-monitor',
{
monitor: {
/**
* 允许触发事件的节点名称
*/
allowNodeNames: ['view', 'button', 'text', 'image'] as string[],
/**
* 是否开启节点监控
*/
enableNodeMonitor: true,
/**
* 是否开启 API 监控
*/
enableApiMonitor: true,
/**
* 是否开启生命周期监控
*/
enableLifecycleMonitor: true,
/**
* 是否开启错误监控
*/
enableErrorMonitor: true
}
}
]
],- 新建
monitor/track.ts文件
import { MiniTrack } from '@lx-frontend/multi-track'
import Taro from '@tarojs/taro'
// 用于存储,门店、用户等信息。
const _userInfo: Record<string, any> = {}
/**
* 在企业微信中可能存在下面 API 不支持情况
* @returns
*/
const getMiniAppInfo = () => {
const windowInfo = Taro.getWindowInfo?.() || {}
const systemSetting = Taro.getSystemSetting?.() || {}
const deviceInfo = Taro.getDeviceInfo?.() || {}
const appBaseInfo = Taro.getAppBaseInfo?.() || {}
const appAuthorizeSetting = Taro.getAppAuthorizeSetting?.() || {}
return {
windowInfo,
systemSetting,
deviceInfo,
appBaseInfo,
appAuthorizeSetting,
}
}
const getUserInfo = () => {
return _userInfo || {}
}
export const setUserInfo = (userInfo: Record<string, any> = {}) => {
Object.assign(_userInfo, userInfo)
}
// 排除掉一些带有敏感数据的接口。
const ignoreRequestUrlList: string[] = ['xxxx/MpLogin', 'xxxx/ChooseStore', 'auth/xxx_wxlogin']
/**
* 日志上报 track 实例
*
* 针对一些异步登录,初始化等场景,需要手动调用 track.setUploadEnabled(true) 来开启上报。
*/
export const track = new MiniTrack({
slsOptions: {
host: 'cn-hangzhou.log.aliyuncs.com', // 替换成 sls 提供的
project: 'xxxx', // 替换成 sls project 名称
logstore: 'xxxx', // 替换成 sls project 下 store 名称
topic: process.env.TARO_APP_RUN_ENV || 'test',
source: 'xxxx-mp-frontend', // 一般为项目仓库名,随便写
tags: {
// 用于 区分日志的 tag,对象即可,这里我只加了一个
version: VERSION,
},
},
trackOptions: {
/**
* 上报队列,add 数据达到10条就触发一次上报
*/
maxQueueSize: 10,
/**
* 最后一次 add 后,没任何操作 5s 后上报
*/
debounceTime: 5000,
/**
* 是否持久化
*/
persistLogs: true,
/**
* 持久化 key
*/
localStorageKey: 'localStorageKey',
},
// add 日志都会经过该函数处理
sendPayload: (log) => {
// 简单数据校验
if (!log?.eventType) {
return {}
}
const { userInfo } = getUserInfo()
// 需要处理掉一些敏感数据,比如请求头 和 登录接口响应的
// ParkBffService/MpLogin
if (log.eventType === 'http') {
log.headers = JSON.stringify({})
}
if (log.eventType === 'http' && ignoreRequestUrlList.some((item) => log.requestUrl.includes(item))) {
log.body = JSON.stringify({})
}
return {
...log,
// 增加一些业务
...(log.eventType === 'lifecycle' && log.lifecycleStage === 'onLaunch' ? getMiniAppInfo() : {}),
userId: userInfo?.user?.id || '',
userName: userInfo?.user?.displayName || '',
storeId: userInfo?.user?.storeId || '',
}
},
})- 新建
monitor/index.ts文件
import Taro from '@tarojs/taro'
import { track } from './track'
// 这些高频触发 api 忽略不上报,对定位问题基本没作用。
const apiCallIgnoreList: string[] = [
'getWindowInfo',
'getSystemSetting',
'getDeviceInfo',
'getAppBaseInfo',
'getAppAuthorizeSetting',
'getStorage',
'getStorageInfo',
'getStorageSync',
'getStorageInfoSync',
'reportEvent',
'getSystemInfo',
'getSystemInfoSync',
'getPrivacySetting',
]
// 注意要忽略本身
const httpIgnoreList: string[] = ['APIVersion=0.6.0']
Taro?.monitorEvent?.on('all', (log) => {
// 简单数据校验
if (!log?.eventType) {
return
}
// 过滤一些不需要上报的事件
if (log?.eventType === 'api' && apiCallIgnoreList.includes(log?.apiName)) {
return
}
if (log?.eventType === 'http' && httpIgnoreList.some((item) => log?.requestUrl?.includes(item))) {
return
}
if (log?.eventType === 'lifecycle' && log?.lifecycleStage === 'onReady') {
return
}
track.add(log)
})- 在小程序入口处引用
// 引用监控
import '@/monitor'
import { PropsWithChildren } from 'react'
import { useLaunch } from '@tarojs/taro'
import './app.less'
function App({ children }: PropsWithChildren<any>) {
useLaunch(() => {
console.log('App launched.')
// 检查版本更新
checkVersion()
})
// children 是将要会渲染的页面
return children
}
export default App