专注小程序 / APP 开发,用代码改变生活

获取方案
全国分站 主站首页 北京分站 石家庄分站 唐山分站 保定分站 廊坊分站 沧州分站 郑州分站 邯郸分站

小程序监控报警:别等用户骂到脸上

营销推广 2026-10-31 0 阅读 0 点赞 原创

上周有个朋友半夜给我打电话,说他的小程序挂了两个小时,直到有用户在小红书上发帖吐槽,他才知道。我问他有没有做监控报警,他说:「云开发后台不是有日志吗?」

小程序监控报警:别等用户骂到脸上

有日志和能报警,是两码事。日志是事后验尸,报警是提前止血。这篇就聊聊小程序监控报警这件事,怎么用尽量低的成本,把「用户先发现」变成「我先发现」。

先搞清楚要监控什么

很多人一上来就想接 Sentry、接各种 APM,其实对大多数小程序来说,先把下面这几类盯住,就够挡住 80% 的事故了:

  • 接口错误率:某个后端接口 5 分钟内错误率超过阈值,基本就是线上事故的前兆。
  • 接口耗时:P95 响应时间突然翻倍,用户体感就是「卡」。
  • JS 运行时错误:小程序里的 onerror 能捕获不少白屏类问题。
  • 关键业务埋点:比如下单按钮点击后没有成功回调,这种「静默失败」最坑。
  • 版本发布后的异常波动:新版本上线后 30 分钟内错误数对比上一版本。

别贪多。先挑两三个跟钱、跟核心流程相关的指标,做扎实了再加。

错误采集:在 app.js 里埋一颗种子

小程序本身提供了 App.onError 和 App.onUnhandledRejection,这是最省事的入口。我一般会在 app.js 里统一收口,做一层节流和去重,避免一个循环报错把报警渠道刷爆。

// app.js
App({
  onLaunch() {
    this.reportQueue = []
    this.startFlushTimer()
  },

  onError(err) {
    this.pushError({
      type: 'js_error',
      msg: String(err).slice(0, 500),
      page: getCurrentPages().pop()?.route || '',
      ts: Date.now()
    })
  },

  onUnhandledRejection(res) {
    this.pushError({
      type: 'promise_rejection',
      msg: String(res.reason).slice(0, 500),
      page: getCurrentPages().pop()?.route || '',
      ts: Date.now()
    })
  },

  pushError(item) {
    // 简单去重:同一错误 60 秒内只报一次
    const key = item.type + item.msg
    const now = Date.now()
    this._seen = this._seen || {}
    if (this._seen[key] && now - this._seen[key] < 60000) return
    this._seen[key] = now
    this.reportQueue.push(item)
  },

  startFlushTimer() {
    setInterval(() => {
      if (!this.reportQueue.length) return
      const batch = this.reportQueue.splice(0, 20)
      wx.request({
        url: 'https://your-api.com/monitor/report',
        method: 'POST',
        data: { errors: batch },
        fail: () => {
          // 上报失败就丢掉,别无限重试拖垮客户端
        }
      })
    }, 10000)
  }
})

注意两个细节:一是上报接口本身失败时不要重试,否则监控反而成了负担;二是错误信息要截断,别把整个堆栈塞进去,后端存储和报警消息都会很难看。

接口层做统一拦截

如果你的请求都走一个封装的 request 方法,那就好办了。在成功和失败回调里顺手记一笔耗时和状态码,按分钟聚合后上报。

function request(options) {
  const start = Date.now()
  return new Promise((resolve, reject) => {
    wx.request({
      ...options,
      success(res) {
        trackApi({
          url: options.url,
          status: res.statusCode,
          cost: Date.now() - start
        })
        resolve(res)
      },
      fail(err) {
        trackApi({
          url: options.url,
          status: -1,
          cost: Date.now() - start,
          err: err.errMsg
        })
        reject(err)
      }
    })
  })
}

客户端只负责「记录」,判断和报警放到服务端做。原因很简单:阈值规则会变,改服务端比发版快得多。

报警通道怎么选

个人开发者和小团队,我推荐两条腿走路:

  • 企业微信/钉钉机器人:免费、配置简单,适合日常告警。用 Webhook 推一条 markdown 消息,手机就能收到。
  • 短信或电话:只留给「P0 级」事故,比如核心接口连续 5 分钟错误率 100%。短信有成本,但半夜能把你叫醒的只有它。

报警内容别只写「错误率超阈值」,要带上:哪个接口、错误率多少、影响版本、最近一条错误样例、大盘链接。不然你半夜爬起来还得先查半天。

几个踩过的坑

1. 阈值定太敏感

刚上线时我把错误率阈值设成 1%,结果每天早上被网络抖动叫醒。后来改成「连续 3 个周期都超阈值才报」,噪音少了一大半。

2. 忘了区分环境和版本

开发版、体验版的错误混进正式报警里,纯属自找麻烦。上报时带上 envVersion 和版本号,服务端按环境分流。

3. 报警没有闭环

报警发出来没人认领,等于没报。哪怕就你一个人开发,也养成习惯:收到报警先回一句「在处理」,处理完记一笔原因。时间长了你会发现,真正值得修的就那么几类。

小结

小程序监控报警不是什么高深技术,难的是「愿意花半天时间把它搭起来」。云开发的日志、微信后台的运维中心都能用,但它们是「你去看」,而报警是「它来找你」。对独立开发者来说,后者才是能让你睡个安稳觉的东西。

先把 onError 和接口拦截这两件事做了,再接一个机器人 Webhook,一个下午就能跑通。别等用户骂到脸上才想起这件事。

小程序数据备份,别等丢了才后悔小程序日志分析实战:从混乱到清晰

评论 (0)

还没有评论,快来抢沙发吧~

好想法,值得被认真交付

从小程序、APP 到全栈网站,一站式把想法变成可落地的产品

微信咨询

微信扫码,直接沟通需求