侧边栏壁纸
博主头像
翻斗

开始一件事最好是昨天,其次是现在

  • 累计撰写 44 篇文章
  • 累计创建 42 个标签
  • 累计收到 2 条评论

Firebase应用报错信息发送到企业微信

翻斗
2022-03-14 / 0 评论 / 0 点赞 / 1,295 阅读 / 3,158 字

本博客类似文章:使用AWS Lambda做webhook

缘由

公司的服务器端报错都有实时监控,出现异常后,会自动发送到企业微信上,这样方便在生产上实时了解到有哪些问题,服务器要做这个比较简单,就是AOP检测系统异常后,发送HTTP请求到企业微信的webhook(也就是群机器人)即可。现在是要考虑做客户端的错误搜集上报。

我司用的是FirebaseCrashlytics做错误搜集,当然了,他有很不错的界面,可以统计各种错误信息,崩溃趋势,问题状态和详细情况等等,还有不错的报表查看功能。但是,这个需要我们自己登录Firebase后台查看,这个需要我们自发主动的看,或者邮件提醒(有延迟),万一团队成员没人注意,或者邮件被大家下意识忽略(我相信很多人都会因为邮件太多而忽略吧!),那么这个问题就会被延迟发现,甚至埋没,一直存在于APP中,影响用户使用。

那,可以做实时推送吗?

可以,但,官方内置继承的只有Slack,jiraPagerDuty,并不支持企业微信(或者钉钉)之类的消息推送,因此,我们需要自己做一个。

入口

我这里假设大家不会,所以来一步步引导大家制作这个工具

首先,在Firebase的Crashlytics管理界面中,在问题展览页面中的右边,选择三个点的图标,选择疾速崩溃提醒设置

弹出的界面我们点击了解详情,这里能看到一些文档,我们下拉到设置发送到第三方服务的高级提醒,我们找到里面的编写并部署一个函数链接

这里会有一个发送到Discord频道的例子

基本概念

可能有些朋友看到这里会有点晕,这写的是个什么东西呢?何为函数?如何处理崩溃事件呢?

其实这里的函数就是我们常说的FAAS(函数即服务)的概念中的函数,也是我们说的Serverless(无服务)概念的载体,如果有听说过AWS Lambda的朋友,大概就能了解,这是一类东西。

那这个函数是如何处理数据的呢?数据流是怎么样的?

这个跟AWS Lambda还是类似,它们的本质是一个可以按需启动使用的代码段,可以有两种形式触发:

1、该共有云(AWS/Google Cloud)内部的触发器(各种关键事件发生的时候触发,携带已定义好的数据段)

2、提供公共访问URL,直接外部使用HTTP访问

很显然,Firebase崩溃提醒这里是使用第一类的内部触发器,当某个APP崩溃后,Firebase Crashlytics收集到信息,就会触发事件,这里的Function就会启动并执行,所以我们在这里添加访问webhook的代码即可。

相关文档参考下面:
https://firebase.google.com/docs/functions/get-started?authuser=0&hl=zh&gen=2nd

编码

按照官方文档,我们先要完成各种权限创建后,再做如下操作

1、设置环境和Firebase CLI

安装Node.js以及npm
安装Firebase CLI

npm install -g firebase-tools

2、初始化项目
2.1、这里需要进行认证,具体是运行

firebase login

然后会启动浏览器,进行浏览器登录认证

2.2、略过教程的初始化firestore流程(因为我们没有使用,我们只是接受Firebase消息)

2.3、初始化函数代码

firebase init functions

一步步跟随提示做好选择后,会有如下的文件列表:

现在开始写代码,我们根据示例https://github.com/firebase/functions-samples/blob/385ab5e58f69f013aa5e78d51ddd433b31afc37a/Node/alerts-to-discord/functions/index.js#L66-L66来编写即可,我们只是需要做崩溃报警,所以只需要实现对事件onNewFatalIssuePublished的处理即可。
下面是基础处理代码:


const {
  onNewFatalIssuePublished,
} = require("firebase-functions/v2/alerts/crashlytics");
const logger = require("firebase-functions/logger");
const fetch = require("node-fetch");
// 这里填自己的企业微信机器人地址即可
const webhookUrl = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx";
async function sendWechatWebhook(msg) {
    return fetch(webhookUrl, {
        method: "POST",
        headers: {"Content-Type": "application/json"},
        body: JSON.stringify(
        {
          msgtype: "markdown",
          markdown: {
            "content":msg
          }
        },
    ),
    })
}

exports.sendfatalmsg = onNewFatalIssuePublished(async (event) => {
    logger.info('');
    const appId = event.appId;
    const {id, title, subtitle,appVersion} = event.data.payload.issue;
    const message = 
    `
iOS客户端崩溃异常\n
appID: ${appId}\n
id :${id}\n
appVersion: ${appVersion}\n
title: ${title}\n
subtitle: ${subtitle}\n
    `;
    logger.info("new fatal published, ", message);
    try{
        const response = await sendWechatWebhook(message);
        if (response.ok){
            logger.info('send alert to wechat ok');
        }else{
            throw new Error(response.error);
        }
        logger.info('fatal occur:', message)
    }catch(error){
        logger.error('send to wxchat robot with error ',error);
    }
});

如果要处理更多的事件,可以参考官方文档: https://firebase.google.com/docs/reference/functions/2nd-gen/node/firebase-functions.alerts?authuser=0&hl=zh-cn

部署与查看

如果你看官方文档,他有本地测试功能,但是我们本地不太好模拟具体事件(需要test.wrap封装测试),因此我们直接部署到线上查看即可。

firebase deploy --only functions

执行命令后,会自动部署到我们的后台上,当遇到崩溃消息后,会自动触发该Function的运行,然后转发到企业微信的机器人上。

如果要查看相关日志,参考如下:

总结

不同的云厂商都有自己的serverless或者function运行时,都是最近的FAAS概念的另一种阐释,有机会就多了解了解,会给我们带来很多工作上的便捷。

0

评论区