npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

audit-log-sdk

v1.1.0

Published

A tracking SDK for Vue/React/UniApp applications with manual and automatic tracking capabilities

Readme

Audit Log SDK

一个轻量级的前端审计日志SDK,支持 Vue、React 和 UniApp 项目,提供手动埋点和 API 自动拦截功能。

安装

npm install audit-log-sdk
# 或
yarn add audit-log-sdk
# 或
pnpm add audit-log-sdk

快速开始

Vue 项目

// main.ts
import { createApp } from 'vue';
import { AuditLog, SystemNo } from 'audit-log-sdk';
import App from './App.vue';

const app = createApp(App);

app.use(AuditLog, {
  reportUrl: '/apiLog/save-batch',           // 日志上报地址(必填)
  systemNo: SystemNo.OMS,                    // 系统编码(必填)
  system: 'OMS',                               // 系统名称
  userId: 1001,                                // 用户ID
  userName: '张三',                            // 用户名称
  systemToken: 'xxx-token',                    // 用户token
  authorization: 'Basic xxx-token',             // 上报接口的 Authorization Token(必填)
});

app.mount('#app');

React 项目

// index.tsx
import { createAuditLog, SystemNo } from 'audit-log-sdk';

const audit = createAuditLog({
  reportUrl: '/apiLog/save-batch',
  systemNo: SystemNo.OMS,
  authorization: 'Basic xxxx',
  system: 'OMS',
  userId: 1001,
  userName: '张三',
  authorization: 'Basic xxx-token',            // 上报接口的 Authorization Token(可选)
});

export default audit;

UniApp 项目

Vue3 模式(推荐)

// main.js
import { createSSRApp } from 'vue';
import { createUniAuditLog, SystemNo } from 'audit-log-sdk';
import App from './App.vue';

export function createApp() {
  const app = createSSRApp(App);

  app.use(createUniAuditLog({
    reportUrl: 'https://your-api.com/apiLog/save-batch',  // 小程序端需使用完整URL
    systemNo: SystemNo.OMS,
    system: 'OMS',
    userId: 1001,
    userName: '张三',
    authorization: 'Basic xxx-token',
  }));

  return { app };
}

Vue2 模式

// main.js
import Vue from 'vue';
import { UniAuditLog, SystemNo } from 'audit-log-sdk';

Vue.use(UniAuditLog, {
  reportUrl: 'https://your-api.com/apiLog/save-batch',
  systemNo: SystemNo.OMS,
  system: 'OMS',
});

非 Vue 插件模式(直接初始化)

// utils/audit.ts
import { initUniAppDirect, track, SystemNo } from 'audit-log-sdk';

initUniAppDirect({
  reportUrl: 'https://your-api.com/apiLog/save-batch',
  systemNo: SystemNo.OMS,
  system: 'OMS',
});

export { track };

App.vue 生命周期集成(可选)

SDK 默认通过 uni.onErroruni.onUnhandledRejection 自动捕获全局错误。如果你的 UniApp 版本不支持这些 API,可以手动在 App.vue 中集成:

// App.vue
import { onAppError, onAppUnhandledRejection, onPageShow } from 'audit-log-sdk';

export default {
  onError(err) {
    onAppError(err);
  },
  onUnhandledRejection(err) {
    onAppUnhandledRejection(err.reason);
  },
};

页面生命周期集成(推荐)

为了正确追踪页面来源(referUrl),建议在页面 onShow 中调用 onPageShow

// 页面中
import { onPageShow } from 'audit-log-sdk';

export default {
  onShow() {
    onPageShow();
  },
};

配置项

基础配置

| 参数 | 类型 | 必填 | 默认值 | 说明 | | --------------- | --------------- | ---- | -------- | -------------------------------------------- | | reportUrl | string | 是 | - | 日志上报接口地址 | | systemNo | number | 是 | - | 系统编码(0=OMS, 1=TMS, 2=IOT) | | system | string | 否 | - | 系统名称 | | userId | number| string | 否 | - | 用户ID | | userName | string | 否 | - | 用户名称 | | systemToken | string | 否 | - | 用户token | | userIp | string | 否 | - | 用户IP | | channelId | string | 否 | 自动生成 | 渠道ID(设备ID) | | channelType | string | 否 | 自动检测 | 渠道类型(web/APP/miniapp) | | authorization | string | 否 | - | 上报接口的 Authorization Token,用于接口鉴权 | | platform | string | 否 | 'auto' | 运行平台:'browser' / 'uniapp' / 'auto' |

注意

  • systemVersion 由 SDK 内部自动从 package.json 读取,无需用户配置。
  • platform 默认为 'auto',SDK 会自动检测运行环境。UniApp 小程序/App 端自动识别为 'uniapp',浏览器端自动识别为 'browser'。如需强制指定,可手动设置。

功能配置

| 参数 | 类型 | 默认值 | 说明 | | --------------------- | -------- | ------ | ------------------------------------------ | | batchSize | number | 10 | 批量发送数量 | | flushInterval | number | 5000 | 发送间隔(ms) | | samplingRate | number | 1 | 采样率(0-1) | | enableAutoTracking | boolean | true | 开启自动追踪(错误追踪) | | enableApiIntercept | boolean | true | 开启API拦截 | | enableErrorTracking | boolean | true | 开启错误追踪 | | excludeUrls | string[] | [] | 排除的URL列表(黑名单,命中不拦截) | | includeUrls | string[] | [] | 包含的URL列表(白名单,仅拦截匹配的) | | beforeSend | function | - | 发送前回调,返回 null/false 可丢弃该条日志 | | afterSend | function | - | 发送后回调 |

DOM 追踪配置 (domTrackerConfig)

通过监听用户交互事件(点击、提交等),将触发 API 请求的 DOM 元素信息关联到日志中。

注意:DOM 追踪仅在浏览器环境和 UniApp H5 端可用,小程序/App 端无 DOM,此功能自动禁用。

domTrackerConfig: {
  enable: true,                                // 是否启用DOM追踪(默认 true,跟随API拦截)
  timeWindow: 500,                             // 关联时间窗口(ms),默认 500
  events: ['click', 'submit'],                 // 监听的事件类型
  maxTextLength: 50,                           // 元素文本截断长度,默认 50
  maxSelectorDepth: 5,                         // CSS选择器最大深度,默认 5
}

工作原理

  1. DomTracker 监听 click/submit 等事件,缓存最近触发的 DOM 元素信息 + 时间戳
  2. API 拦截器捕获到请求时,检查时间窗口内是否有匹配的用户交互事件
  3. 有关联则记录 triggerDom 字段,无则不记录(不强关联)
  4. 关联后立即清除缓存,时间窗口过期也会自动清除,避免残留误关联

triggerDom 字段格式(JSON 字符串):

{
  "selector": "div.container > form > button#submit-btn",
  "tagName": "button",
  "text": "提交"
}

注意:以下场景无法关联 DOM 信息(triggerDom 为空):

  • 页面加载/组件挂载时自动发出的请求
  • 定时器/轮询触发的请求
  • 路由切换触发的请求
  • 交互后延迟超过时间窗口才发出的请求

小程序/App 端手动设置 DOM 触发信息

小程序和 App 端无 DOM API,无法自动追踪。可使用 setTriggerDom 在点击事件回调中手动设置:

import { setTriggerDom } from 'audit-log-sdk';

// 在 @tap 回调中调用,关联后续接口请求
getOrgIdList() {
  setTriggerDom('u-input.org-select', '请选择组织结构');
  this.$http.get({ url: '/api/list' }).then(...)
}

Vue 插件模式下可通过 this.$audit 调用:

this.$audit.setTriggerDom('button.submit', '提交订单');
this.$http.post({ url: '/api/submit', data: form }).then(...)

| 参数 | 类型 | 说明 | | ---------- | ------ | ---------------------------- | | selector | string | 元素选择器/标识 | | text | string | 元素文本内容(截断前 50 字) |

注意:H5 端已自动追踪 DOM 事件,无需手动调用。设置后 500ms 内的下一个接口请求会关联此信息,自动填入 triggerDom 字段。

API 拦截配置 (apiInterceptConfig)

apiInterceptConfig: {
  interceptRequest: true,    // 是否记录请求信息(默认 true)
  interceptResponse: true,   // 是否记录响应状态(默认 true)
  logRequestBody: true,      // 是否记录请求体(默认 true)
  logResponseBody: false,     // 是否读取响应体用于提取错误信息(默认 false)
  logHeaders: true,          // 是否记录请求头(默认 true)
  maxBodySize: 10000,        // 最大body大小(默认 10000)
  excludeUrls: ['/health'],  // API拦截层排除的URL
}

说明:每个 API 请求只会产生一条日志。httpBody 记录的是请求体;当接口返回错误时,会从响应中提取 errorCodeerrorMsg 写入对应字段。

手动埋点

基础用法

import { track, EventStatus } from 'audit-log-sdk';

// 基础埋点
track({
  eventNo: 'ORDER_CREATE',
  event: '创建订单',
});

// 带状态的埋点
track({
  eventNo: 'ORDER_SUBMIT',
  event: '提交订单',
  eventStatus: EventStatus.SUCCESS,  // 0=成功, 1=失败, 2=异常
});

// 带错误信息的埋点
track({
  eventNo: 'ORDER_ERROR',
  event: '订单错误',
  eventStatus: EventStatus.ERROR,
  errorCode: 'ERR_001',
  errorMsg: '库存不足',
});

// 立即发送
track({
  eventNo: 'IMPORTANT_EVENT',
  event: '重要事件',
  immediate: true,
});

完整参数

track({
  eventNo: 'ORDER_QUERY',           // 事件编码
  event: '查询订单',                 // 事件名称
  eventStatus: EventStatus.SUCCESS, // 事件状态:0=成功 1=失败 2=异常
  errorCode: '',                    // 错误编码(失败时自动从响应提取)
  errorMsg: '',                     // 错误描述(失败时自动从响应提取)
  httpUrl: '/api/order/query',      // 请求地址
  httpBody: '{"page":1}',           // 请求报文
  httpMethod: HttpMethod.POST,      // 请求方式
  operationDuration: 150,           // 操作耗时(ms)
  extText: '{"extra":"data"}',      // 扩展字段
  immediate: false,                 // 是否立即发送
});

API 方法

设置用户信息

import { setUser, setToken, setAuthorization } from 'audit-log-sdk';

// 登录后设置用户信息
setUser(1001, '张三', 'xxx-token');

// 单独设置用户 token
setToken('new-user-token');

// 动态修改上报接口的 Authorization Token
setAuthorization('Basic new-auth-token');

设置页面上下文

import { setPageContext, clearPageContext } from 'audit-log-sdk';

// 进入页面时设置
setPageContext('订单管理', 'ORDER_MGMT');

// 离开页面时清除
clearPageContext();

手动刷新队列

import { flush } from 'audit-log-sdk';

// 立即发送当前队列中的所有日志
flush();

Vue Router 集成

// router/index.ts
import { setPageContext, clearPageContext } from 'audit-log-sdk';

router.beforeEach((to, from, next) => {
  clearPageContext();
  next();
});

router.afterEach((to) => {
  if (to.meta?.businessType) {
    setPageContext(to.meta.businessType, to.meta.businessTypeNo);
  }
});

// 路由定义
const routes = [
  {
    path: '/order/list',
    component: OrderList,
    meta: {
      businessType: '订单列表',
      businessTypeNo: 'ORDER_LIST',
    },
  },
];

Vue 组件中使用

// Vue 3
import { getCurrentInstance } from 'vue';

export default {
  setup() {
    const { proxy } = getCurrentInstance();
  
    const handleClick = () => {
      proxy.$audit.track({
        eventNo: 'BTN_CLICK',
        event: '按钮点击',
      });
    };
  
    return { handleClick };
  },
};

// Vue 2
export default {
  methods: {
    handleClick() {
      this.$audit.track({
        eventNo: 'BTN_CLICK',
        event: '按钮点击',
      });
    },
  },
};

React 组件中使用

// hooks/useAudit.ts
import { getAuditLog } from 'audit-log-sdk';

export const useAudit = () => {
  const audit = getAuditLog();
  return audit;
};

// 组件中使用
import { useAudit } from './hooks/useAudit';

function MyComponent() {
  const audit = useAudit();
  
  const handleClick = () => {
    audit?.track({
      eventNo: 'BTN_CLICK',
      event: '按钮点击',
    });
  };
  
  return <button onClick={handleClick}>提交</button>;
}

UniApp 平台说明

平台自动检测

SDK 会在初始化时自动检测运行环境:

| 运行环境 | 检测结果 | 使用的平台适配器 | | --------- | -------- | ---------------- | | 浏览器 | browser | 浏览器 API(fetch、localStorage、DOM 等) | | UniApp H5 | browser | 浏览器 API(H5 模式下浏览器 API 完整可用) | | UniApp 小程序 | uniapp | UniApp API(uni.request、uni.getStorageSync 等) | | UniApp App | uniapp | UniApp API(uni.request、uni.getStorageSync 等) |

你也可以通过配置 platform: 'uniapp'platform: 'browser' 强制指定平台。

UniApp 与浏览器的差异

| 功能 | 浏览器 | UniApp 小程序/App | | ---- | ------ | ----------------- | | 网络请求上报 | fetch + keepalive | uni.request | | 本地存储 | localStorage | uni.getStorageSync / uni.setStorageSync | | UserAgent | navigator.userAgent | 通过 uni.getSystemInfoSync() 拼接 | | 页面 URL | window.location.href | getCurrentPages() 路由拼接 | | 页面标题 | document.title | 页面路由(兜底) | | 来源页面 | document.referrer | SDK 维护页面栈 | | 渠道类型 | 基于 UA 判断(web/APP) | 基于 uniPlatform 判断(APP/miniapp) | | API 拦截 | 拦截 fetchXMLHttpRequest | 拦截 uni.request | | 错误捕获 | window.addEventListener('error') | uni.onError | | Promise 拒绝 | window.addEventListener('unhandledrejection') | uni.onUnhandledRejection | | DOM 追踪 | 支持 | 不支持(自动禁用) | | 页面隐藏处理 | beforeunload / pagehide / visibilitychange | uni.onAppHide |

UniApp 小程序端注意事项

  1. reportUrl 必须使用完整 URL:小程序不支持相对路径,必须使用 https:// 开头的完整地址
  2. 无 DOM 追踪:小程序端没有 DOM,domTrackerConfigtriggerDom 字段不生效
  3. 页面来源追踪:小程序端没有 document.referrer,需在页面 onShow 中调用 onPageShow() 来维护页面栈
  4. 错误捕获:部分低版本 UniApp 不支持 uni.onError,需在 App.vue 中手动调用 onAppError()
  5. channelType 差异:小程序端 channelType 返回 'miniapp',App 端返回 'APP',浏览器端返回 'web'

发送数据格式

SDK 批量发送 JSON 数据(浏览器端使用 fetch + keepalive,UniApp 端使用 uni.request):

{
  "dataList": [
    {
      "systemNo": 0,
      "system": "OMS",
      "systemVersion": "1.0.16",
      "referenceId": "1700000000000_abc123def",
      "httpUrl": "/api/user/info",
      "httpMethod": 2,
      "httpBody": "{\"id\":1001}",
      "operationTime": "2024-01-01 12:00:00",
      "operationDuration": 230,
      "eventStatus": 0,
      "errorCode": null,
      "errorMsg": null,
      "businessType": "订单管理",
      "businessTypeNo": "ORDER_MGMT",
      "userId": 1001,
      "userName": "张三",
      "systemToken": "xxx-token",
      "userIp": null,
      "channelId": "device-id-xxx",
      "channelType": "web",
      "userAgent": "Mozilla/5.0...",
      "referUrl": "https://example.com/dashboard",
      "triggerDom": "{\"selector\":\"button#submit-btn\",\"tagName\":\"button\",\"text\":\"提交\"}"
    }
  ]
}

API 拦截日志示例(成功,含触发DOM)

{
  "referenceId": "xxx",
  "httpUrl": "/api/user/info",
  "httpMethod": 2,
  "httpBody": "{\"id\":1001}",
  "operationTime": "2024-01-01 12:00:00",
  "operationDuration": 150,
  "eventStatus": 0,
  "errorCode": null,
  "errorMsg": null,
  "triggerDom": "{\"selector\":\"button#query-btn\",\"tagName\":\"button\",\"text\":\"查询\"}"
}

API 拦截日志示例(失败,自动提取错误信息)

{
  "referenceId": "xxx",
  "httpUrl": "/api/user/info",
  "httpMethod": 2,
  "httpBody": "{\"id\":1001}",
  "operationTime": "2024-01-01 12:00:00",
  "operationDuration": 230,
  "eventStatus": 1,
  "errorCode": "50001",
  "errorMsg": "用户不存在"
}

错误信息提取规则:SDK 会尝试从响应 JSON 中按以下顺序查找字段: code / errorCodemessage / msg / errorMsg

枚举值

SystemNo 系统编码

| 值 | 说明 | | -- | ---- | | 0 | OMS | | 1 | TMS | | 2 | IOT |

EventStatus 事件状态

| 值 | 说明 | | -- | ---- | | 0 | 成功 | | 1 | 失败 | | 2 | 异常 |

HttpMethod 请求方式

| 值 | 说明 | | -- | ------ | | 1 | GET | | 2 | POST | | 3 | DELETE | | 4 | PATCH | | 5 | PUT |

URL 过滤规则

支持通配符 * 匹配,例如 /api/* 可匹配所有以 /api/ 开头的 URL。

excludeUrls(黑名单):命中则不拦截

excludeUrls: ['/health', '/static/*']   // 这两个不拦,其他都拦

includeUrls(白名单):未命中则不拦截

includeUrls: ['/api/*']                  // 只有 /api/ 开头的拦截,其他都不拦

组合使用

apiInterceptConfig: {
  excludeUrls: ['/health'],              // 先排除健康检查
  includeUrls: ['/api/*'],               // 再只保留 /api/ 开头的请求
}

注意事项

  1. reportUrlsystemNo 是必填项
  2. 浏览器端使用 fetch + keepalive 发送数据,支持自定义请求头(如 Authorization),页面关闭时数据仍可正常发送;UniApp 端使用 uni.request
  3. SDK 自身的上报请求不会被拦截器拦截(自动过滤)
  4. 浏览器的 OPTIONS 预检请求 会被自动过滤,不会产生日志
  5. 每个 API 请求只产生一条日志,httpBody 始终记录请求体
  6. 接口返回错误(状态码 >= 400)时,SDK 会尝试从响应 JSON 中提取 errorCodeerrorMsg
  7. keepalive 有请求体大小限制(一般 64KB),超大会直接失败(仅浏览器端)
  8. 建议在生产环境设置合理的 samplingRate 以减少日志量
  9. 页面上下文需要在路由切换时设置,用于标识日志来源页面
  10. 排除项目中不需要拦截的接口,如文件上传接口等大流量场景
  11. UniApp 小程序端 reportUrl 必须使用完整 HTTPS URL
  12. UniApp 小程序端 不支持 DOM 追踪,triggerDom 字段始终为空

License

MIT