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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@be-link/cls-logger

v1.0.13

Published

@be-link cls-logger - 腾讯云 CLS 日志上报封装

Readme

@be-link/cls-logger

腾讯云 CLS(tencentcloud-cls-sdk-js-web / tencentcloud-cls-sdk-js-mini)日志上报封装,支持 Web、H5 和小程序环境,提供统一的调用方式。

特性

  • 自动环境适配(Web / H5 / 小程序)
  • 内存队列批量上报,减少网络请求
  • 页面关闭时 sendBeacon 保证日志不丢失
  • 支持浏览器空闲时上报(requestIdleCallback
  • 错误即时上报,信息日志批量上报
  • 自动采集:请求监控、性能监控、错误监控、行为埋点
  • 失败重试 + 本地缓存兜底

安装

pnpm add @be-link/cls-logger

依赖说明

| 入口 | 依赖 | 说明 | | -------------------------- | -------------------------------------------- | ----------------------------------- | | @be-link/cls-logger | tencentcloud-cls-sdk-js-web | 统一入口,自动适配环境 | | @be-link/cls-logger/web | tencentcloud-cls-sdk-js-web + web-vitals | Web/H5 专用,含 Web Vitals 性能监控 | | @be-link/cls-logger/mini | tencentcloud-cls-sdk-js-mini | 小程序专用 |

注意:所有依赖已内置,无需手动安装。

快速开始

1. 统一引入方式(推荐快速接入)

import clsLogger from '@be-link/cls-logger';

clsLogger.init({
  projectId: 'my-project',
  appId: 'my-app-id',
  source: 'my-source',
});

2. 分环境引入方式(推荐生产环境)

Web / H5:

import { clsLogger } from '@be-link/cls-logger/web';

clsLogger.init({
  projectId: 'my-web-project',
  source: 'web-source',
});

小程序:

import { clsLogger } from '@be-link/cls-logger/mini';

clsLogger.init({
  projectId: 'my-mini-project',
  appId: 'wx123456789',
  source: 'mini-source',
});

API

日志方法

// 信息日志(走批量队列)
clsLogger.info('应用启动', { startUpTime: 120 });

// 警告日志(走批量队列)
clsLogger.warn('资源加载慢', { duration: 3000 });

// 错误日志(默认即时上报)
clsLogger.error('支付失败', { orderId: '123' });

// Error 对象(自动解析堆栈)
try {
  doSomething();
} catch (err) {
  clsLogger.error(err, { module: 'payment' });
}

即时上报选项

// info/warn 强制即时上报
clsLogger.info('重要事件', { data: 1 }, { immediate: true });

// error 走批量队列(默认是即时上报)
clsLogger.error('非关键错误', { data: 1 }, { immediate: false });

自定义埋点

clsLogger.track('click_event', {
  button: 'submit',
  page: '/home',
});

统计埋点

clsLogger.stat({
  pageName: '首页',
  scene: '入口',
  subScene: '活动弹窗',
  data: 1,
});

配置项

完整配置示例

clsLogger.init({
  // 基础配置
  enabled: true, // 是否启用,默认 true
  projectId: 'my-project', // 项目标识
  appId: 'wx123456789', // 应用 ID(小程序必填)
  appVersion: '1.0.0', // 应用版本
  source: 'my-source', // CLS source

  // 腾讯云 CLS 配置
  tencentCloud: {
    endpoint: 'https://ap-shanghai.cls.tencentcs.com',
    topicID: 'your-topic-id',
    retry_times: 3,
  },

  // 批量上报配置
  batch: {
    maxSize: 50, // 队列达到此数量立即发送,默认 20
    intervalMs: 1000, // 定时批量发送间隔,默认 500ms
    startupDelayMs: 3000, // 启动合并窗口,默认 0(不启用)
    startupMaxSize: 500, // 启动窗口内的队列阈值,默认 maxSize*10(至少200)
    useIdleCallback: true, // 使用浏览器空闲时间上报,默认 false
    idleTimeout: 3000, // 空闲回调超时时间,默认 3000ms
  },

  // 请求监控配置
  requestMonitor: {
    enabled: true, // 是否开启,默认 true
    sampleRate: 1, // 采样率 0~1,默认 1
    ignoreUrls: [/localhost/], // 忽略的 URL
    includeMethod: true, // 是否携带 method,默认 true
    includeQuery: true, // 是否携带 query,默认 true
    includeBody: true, // 是否携带 body,默认 true
    maxParamLength: 2000, // 参数最大长度,默认 2000
  },

  // 错误监控配置
  errorMonitor: {
    enabled: true, // 是否开启,默认 true
    sampleRate: 1, // 采样率 0~1,默认 1
    captureResourceError: true, // 是否采集资源加载错误,默认 true
    maxTextLength: 4000, // stack/message 最大长度,默认 4000
    dedupeWindowMs: 3000, // 错误去重窗口,默认 3000ms
    dedupeMaxKeys: 200, // 去重缓存最大 key 数,默认 200
    ignoreMessages: [
      // 忽略的错误信息(默认值)
      'Script error.',
      'Script error',
      /^ResizeObserver loop/,
      'Permission was denied',
    ],
  },

  // 性能监控配置
  performanceMonitor: {
    enabled: true, // 是否开启,默认 true
    sampleRate: 1, // 采样率 0~1,默认 1
    webVitals: true, // 是否采集 Web Vitals(含 TTFB),默认 true
    resourceTiming: true, // 是否采集资源加载耗时,默认 true
    ignoreUrls: [/localhost/], // 忽略的资源 URL
    maxTextLength: 2000, // 性能指标文本最大长度,默认 2000
  },

  // 行为埋点配置
  behaviorMonitor: {
    enabled: true, // 是否开启,默认 true
    pv: true, // PV 是否开启,默认 true
    uv: true, // UV 是否开启,默认 true
    click: true, // 点击是否开启,默认 true
    sampleRate: 1, // 采样率 0~1,默认 1
    uvExpireDays: 30, // UV 标识过期天数,默认 30
    clickTrackIdAttr: 'data-track-id', // 点击元素埋点标识属性名
    clickMaxTextLength: 120, // 点击文本最大长度,默认 120
  },

  // 设备信息配置
  deviceInfo: {
    enabled: true, // 是否开启,默认 true
    includeUserAgent: true, // 是否包含 UA,默认 true
    includeNetwork: true, // 是否包含网络信息,默认 true
  },

  // 自定义基础字段
  generateBaseFields: () => ({
    userId: getUserId(),
    userName: getUserName(),
    environment: 'production',
  }),
});

常见场景配置

场景 1:首屏请求过多

页面首次加载时日志请求过多,影响其他请求:

clsLogger.init({
  batch: {
    startupDelayMs: 3000, // 启动 3 秒内的日志合并发送
    startupMaxSize: 500, // 启动窗口内允许更多日志积累(防止 maxSize 打断合并)
    maxSize: 100, // 正常运行时的队列阈值
    intervalMs: 2000, // 延长批量间隔
    useIdleCallback: true, // 等待延迟后在浏览器空闲时上报
  },
  performanceMonitor: {
    resourceTiming: false, // 关闭资源监控(首屏资源多时可大幅减少日志量)
  },
});

说明startupMaxSize 确保启动窗口内不会因为 maxSize 被频繁触发而打断日志合并。

场景 2:减少资源监控日志

开发环境资源过多,或生产环境不需要全量资源监控:

clsLogger.init({
  performanceMonitor: {
    resourceTiming: false, // 关闭资源监控
    // 或者采样
    // sampleRate: 0.1,      // 10% 采样
    // 或者过滤
    // ignoreUrls: [/localhost/, /node_modules/],
  },
});

场景 3:过滤无意义的错误

过滤第三方 SDK 的跨域错误:

clsLogger.init({
  errorMonitor: {
    ignoreMessages: [
      // 默认规则
      'Script error.',
      'Script error',
      /^ResizeObserver loop/,
      'Permission was denied',
      // 自定义规则
      /火山SDK/,
      /VolcEngine/,
      /network error/i,
    ],
  },
});

场景 4:高并发场景(直播间)

clsLogger.init({
  batch: {
    startupDelayMs: 3000, // 启动合并窗口
    startupMaxSize: 500, // 启动窗口内的队列阈值
    maxSize: 100, // 正常运行时的队列阈值
    intervalMs: 2000, // 延长批量间隔
    useIdleCallback: true, // 空闲时上报,不阻塞主线程
  },
  performanceMonitor: {
    resourceTiming: false, // 关闭资源监控
  },
  requestMonitor: {
    sampleRate: 0.1, // 请求监控采样 10%
    ignoreUrls: [
      /heartbeat/i, // 忽略心跳请求
      /polling/i, // 忽略轮询请求
      /danmaku|barrage/i, // 忽略弹幕请求
    ],
  },
});

最佳实践

1. 批量配置的正确姿势

useIdleCallback 工作原理

useIdleCallback: true 时,SDK 的上报流程为:

日志产生 → 等待 intervalMs/startupDelayMs → 等待浏览器空闲 → 发送
                    ↑ 最小等待时间            ↑ 在 idleTimeout 内空闲就发送

关键点

  • intervalMs/startupDelayMs最小等待时间,保证不会过早发送
  • idleTimeout 是空闲等待的最大时间,防止浏览器一直繁忙导致日志积压

startupMaxSize 的作用

启动阶段(startupDelayMs 窗口内)日志量通常很大(性能指标、资源加载等),如果 maxSize 设置过小,会频繁触发队列满而打断合并:

// ❌ 错误配置:startupDelayMs 会被 maxSize 打断
batch: {
  startupDelayMs: 3000,
  maxSize: 20,  // 启动期间可能产生 200+ 条日志,会触发 10+ 次发送
}

// ✅ 正确配置:使用 startupMaxSize 保护启动窗口
batch: {
  startupDelayMs: 3000,
  maxSize: 20,
  startupMaxSize: 500,  // 启动期间允许更多日志积累
}

2. 推荐配置模板

普通 H5 页面

clsLogger.init({
  batch: {
    startupDelayMs: 2000,
    startupMaxSize: 300,
    maxSize: 50,
    intervalMs: 1000,
    useIdleCallback: true,
    idleTimeout: 3000,
  },
});

首屏性能敏感(电商、活动页)

clsLogger.init({
  batch: {
    startupDelayMs: 5000, // 更长的启动窗口
    startupMaxSize: 500,
    maxSize: 100,
    intervalMs: 2000,
    useIdleCallback: true,
    idleTimeout: 5000,
  },
  performanceMonitor: {
    sampleRate: 0.3, // 性能监控采样
  },
});

高频交互页面(直播间、游戏)

clsLogger.init({
  batch: {
    startupDelayMs: 3000,
    startupMaxSize: 500,
    maxSize: 100,
    intervalMs: 3000, // 更长的间隔
    useIdleCallback: true,
    idleTimeout: 5000,
  },
  performanceMonitor: {
    resourceTiming: false, // 关闭资源监控
  },
  requestMonitor: {
    sampleRate: 0.1, // 请求监控采样
    ignoreUrls: [/heartbeat/, /polling/, /danmaku/],
  },
});

3. 日志量优化技巧

| 优化项 | 配置 | 效果 | | ------------ | ------------------------------------------ | ------------------------- | | 关闭资源监控 | performanceMonitor.resourceTiming: false | 减少 80%+ 的 perf 日志 | | 性能采样 | performanceMonitor.sampleRate: 0.1 | 只采集 10% 用户的性能数据 | | 请求采样 | requestMonitor.sampleRate: 0.1 | 只采集 10% 的请求日志 | | 忽略高频请求 | requestMonitor.ignoreUrls: [/heartbeat/] | 过滤心跳等高频请求 | | 错误去重 | errorMonitor.dedupeWindowMs: 5000 | 5秒内相同错误只上报一次 |

4. 常见问题排查

问题:首屏请求过多

现象:页面加载时发出 10+ 个日志请求

排查步骤

  1. 检查 startupDelayMs 是否配置
  2. 检查 startupMaxSize 是否足够大(建议 300-500)
  3. 检查 resourceTiming 是否需要开启(这是日志量最大的来源)

问题:日志延迟过高

现象:日志上报明显滞后

排查步骤

  1. 检查 useIdleCallback + idleTimeout 配置
  2. 检查 intervalMs 是否设置过大
  3. 考虑关闭 useIdleCallback 或减小 idleTimeout

问题:页面关闭丢日志

现象:用户快速关闭页面时日志丢失

说明:SDK 已通过 sendBeacon 处理此场景,如仍有丢失:

  1. 检查日志是否在 memoryQueue 中(可能还未触发 flush)
  2. 考虑对关键日志使用 { immediate: true }

功能说明

1. 批量上报机制

SDK 使用内存队列批量上报日志:

| 触发条件 | 说明 | | -------- | ------------------------------------------------------- | | 队列满 | 达到 maxSize(启动窗口内为 startupMaxSize)立即发送 | | 定时器 | 每 intervalMs 毫秒发送一次 | | 页面关闭 | visibilitychange + pagehide 触发 sendBeacon 发送 | | 启动合并 | startupDelayMs 窗口内的日志尽量合并 | | 空闲上报 | useIdleCallback 开启时,等待浏览器空闲后发送 |

2. 即时上报 vs 批量上报

| 方法 | 默认行为 | 说明 | | --------- | -------- | -------------------------------------------------------- | | error() | 即时上报 | 错误需要及时发现,可通过 { immediate: false } 改为批量 | | info() | 批量上报 | 可通过 { immediate: true } 改为即时 | | warn() | 批量上报 | 可通过 { immediate: true } 改为即时 | | track() | 批量上报 | - |

3. 页面关闭保障

页面关闭时(visibilitychange / pagehide),SDK 会:

  1. 使用 navigator.sendBeacon 同步发送队列中的日志
  2. 如果 sendBeacon 不可用,将日志缓存到本地存储
  3. 下次启动时自动重试发送缓存的日志

4. 失败重试机制

  • 上报失败后使用指数退避算法重试
  • 多次重试仍失败,日志落盘到本地缓存
  • 下次应用启动时自动尝试重新上报
  • 本地缓存最多保留 200 条(可配置 failedCacheMax

5. 自动采集内容

请求监控

  • Web: 拦截 fetch / XMLHttpRequest
  • 小程序: 拦截 wx.request / wx.cloud.callFunction

性能监控

  • Web: 使用 Google web-vitals 库实现
    • FCP (First Contentful Paint): 首次内容渲染
    • LCP (Largest Contentful Paint): 最大内容渲染(用户交互后自动停止)
    • CLS (Cumulative Layout Shift): 累积布局偏移(5秒会话窗口算法)
    • INP (Interaction to Next Paint): 交互到绘制延迟(替代 FID)
    • TTFB (Time to First Byte): 首字节时间
    • 资源加载耗时: PerformanceResourceTiming
    • 自动处理 BFCache 恢复时的指标重置
    • 上报数据包含 rating 字段:'good' | 'needs-improvement' | 'poor'
  • 小程序: 首屏渲染、路由切换、启动耗时

错误监控

  • Web: window.onerror, unhandledrejection, 资源加载错误
  • 小程序: wx.onError, wx.onUnhandledRejection, App.onError

行为埋点

  • PV: 页面访问
  • UV: 用户访问(自动生成持久化 ID)
  • 点击: 带 data-track-id 属性的元素点击

手动注入 SDK

在某些特殊构建环境下,可以手动注入 SDK:

import { clsLogger } from '@be-link/cls-logger/mini';
import * as MiniSdk from 'tencentcloud-cls-sdk-js-mini';

clsLogger.init({
  tencentCloud: { topicID: 'xxx', endpoint: 'xxx' },
  sdk: MiniSdk,
});

类型定义

import type {
  ClsLoggerInitOptions,
  BatchOptions,
  ReportOptions,
  RequestMonitorOptions,
  ErrorMonitorOptions,
  PerformanceMonitorOptions,
  BehaviorMonitorOptions,
  DeviceInfoOptions,
} from '@be-link/cls-logger';

License

MIT