1.1.0 • Published 9 months ago

@lx-frontend/multi-track v1.1.0

Weekly downloads
-
License
ISC
Repository
gitlab
Last release
9 months ago

@lx-frontend/multi-track

sls 监控日志上报

用法

前提

  1. 在阿里云 sls 创建好 projectstore
  2. store 需要开启:WebTracking
  3. 小程序项目需要再后台 request 域名增加上述 project 域名
  4. 项目需要接入 @lx-frontend/taro-plugin-monitor

示例配置

  1. 在 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
          }
        }
      ]
    ],
  1. 新建 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 || '',
    }
  },
})
  1. 新建 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)
})
  1. 在小程序入口处引用
// 引用监控
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
1.1.0

9 months ago

1.1.0-beta.1

9 months ago

0.1.8-beta.1

10 months ago

0.1.7

11 months ago

0.1.6

11 months ago

0.1.5

11 months ago

0.1.3

12 months ago

0.1.2

12 months ago

0.1.1

12 months ago