前端监控神器Sentry

1,679 阅读6分钟

Sentry介绍与使用

1.什么是sentry?

sentry是一个基于Django构建的现代化的实时事件日志监控、记录和聚合平台,主要用于如何快速的发现故障。支持几乎所有主流开发语言和平台,并提供了现代化UI,它专门用于监视错误和提取执行适当的事后操作所需的所有信息,而无需使用标准用户反馈循环的任何麻烦。官方提供了多个语言的SDK.让开发者第一时间获悉错误信息,并方便的整合进自己和团队的工作流中.官方提供saas版本免费版支持每天5000个event.

sentry支持自动收集和手动收集两种错误收集方法.我们能成功监控到vue中的错误、异常,但是还不能捕捉到异步操作、接口请求中的错误,比如接口返回404、500等信息,此时我们可以通过Sentry.caputureException()进行主动上报。使用sentry需要结合两个部分,客户端与sentry服务端;客户端就像你需要去监听的对象,比如公司的前端项目,而服务端就是给你展示已搜集的错误信息,项目管理,组员等功能的一个服务平台。

2.什么是DSN?

DSN是连接客户端(项目)与sentry服务端,让两者能够通信的钥匙;每当我们在sentry服务端创建一个新的项目,都会得到一个独一无二的DSN,也就是密钥。在客户端初始化时会用到这个密钥,这样客户端报错,服务端就能抓到你对应项目的错误了。之前版本的sentry对于密钥分为公钥和私钥,一般前端用公钥(DSN(Public)),但是现在的版本舍弃了这种概念,只提供了一个密钥。

3.什么是event

每当项目产生一个错误,sentry服务端日志就会产生一个event,记录此次报错的具体信息。一个错误,对应一个event。

4.什么是issue

同一类event的集合,一个错误可能会重复产生多次,sentry服务端会将这些错误聚集在一起,那么这个集合就是一个issue。

5.监控原理

1.传统的前端监控原理分为异常捕获和异常上报。一般使用onerror捕获前端错误:

window.onerror = (msg, url, line, col, error) => {
  console.log('onerror')
  // TODO
}

2.但是onerror事件无法捕获到网络异常的错误(资源加载失败、图片显示异常等),例如img标签下图片url 404 网络请求异常的时候,onerror无法捕获到异常,此时需要监听unhandledrejection。

window.addEventListener('unhandledrejection', function(err) {
  console.log(err)
})

3.捕获的异常如何上报?常用的发送形式主要有两种: 通过 ajax 发送数据(xhr、jquery...) 动态创建 img 标签的形式

function report(error) {
  var reportUrl = 'http://xxxx/report'
  new Image().src = reportUrl + '?error=' + error
}

架构概述

75il52tzbj.jpeg

  1. Loadbalancer(负载均衡器)负责路由转发(这一服务由用户搭建),错误上报转发到 /api/\d+/store ,其他项目、成员、错误管理功能由 Sentry Web 负责。这一层的承担数据入口、展示的作用
  2. Relay 负责消息中继转发,并把数据先汇集到 Kafka;Snuba 负责接收 SentryWeb 的请求,进行数据的聚合、搜索;Sentry Worker 则是一个队列服务,主要负责数据的存储。
  3. Kafka 作为消息队列,ClickHouse 负责接近实时的数据分析,Redis(主要) 和 Memcached 负责项目配置、错误基础信息的存储和统计。Postgres 承担基础数据持久化(主要是项目、用户权限管理等)Symbolicator 主要用于错误信息格式化。
  4. 最底下的 Zookeeper 是 Kafka 用于节点信息同步的,如果我们设置了多个 ClickHouse 节点,也可以用它来保存主从同步信息或者做分布式表。

Relay —— 错误信息处理的中转站

x4dtdo14j9.jpeg

Relay 收到原始数据后,主要做这几件事。

  1. 对其格式进行有效性校验
  2. 查询内存或者从 Redis 拉取缓存得到项目配置信息,校验请求是否合法(项目是否存在或者有没有触发限流,没触发限流则会对 API 额度进行累计,写入 Redis)
  3. 发起一个异步请求给定时任务(SentryWorker,postprocess-event)做下一步处理

Kafka 和 Celery —— 应用解耦和异步保存数据

Relay 数据转发到 Kafka 的 ingest-events Topic(Ingest 即摄取),消费者消费后把消息放入 postprocess-event 这个 Celery 定时任务服务排队处理。队列做的事情如下

  1. Symbolicate-event,在 iOS 上有个叫 symbolicate-crash 的工具,是将机器的崩溃日志转化为可读的崩溃代码定位日志,这里的 Symbolicator 同样承担类似的职能,由它经手的消息,我们就可以在页面上看到代码在哪里出错了。
  2. process-event,字面含义就是处理消息,在 Sentry 上启用的插件(Plugins or Integration)会在这个步骤中应用到消息体上,例如,整合了一个 Slack bot(机器人),就会在这个步骤发送告警。
  3. save-event,消息经过简化,保存到数据库,同时再次发到 Kafka,但这次换到 event Topic,Snuba 这个搜索组件内部会有一个消费者,对这部分数据批量写入到 ClickHouse。你可能好奇为什么不直接存进去算了还要搞多这一步,这是因为 ClickHouse 虽然大数据量处理能力很强,但频繁写入能力是真的菜鸡(假设做了主从,那就更灾难了,把从库和 Zookeeper 都一起拉下水),所以需要 Snuba 来限制写入频率

sentry安装

地址 github.com/getsentry/s…

git clone  https://github.com/getsentry/self-hosted

安装需求

  • Docker 19.03.6+
  • Compose 1.28.0+
  • 4 CPU Cores
  • 8 GB RAM
  • 20 GB Free Disk Space

将clone下来的文件做修改(不然后面kafka会报错) .env文件

[root@sentry self-hosted]# vim .env
COMPOSE_PROJECT_NAME=sentry-self-hosted
SENTRY_EVENT_RETENTION_DAYS=7  # 将30天清理改成7天
# You can either use a port number or an IP:PORT combo for SENTRY_BIND
# See https://docs.docker.com/compose/compose-file/#ports for more
SENTRY_BIND=9000
# Set SENTRY_MAIL_HOST to a valid FQDN (host/domain name) to be able to send emails!
# SENTRY_MAIL_HOST=example.com
SENTRY_IMAGE=getsentry/sentry:nightly
SNUBA_IMAGE=getsentry/snuba:nightly
RELAY_IMAGE=getsentry/relay:nightly
SYMBOLICATOR_IMAGE=getsentry/symbolicator:nightly
WAL2JSON_VERSION=latest
HEALTHCHECK_INTERVAL=30s
HEALTHCHECK_TIMEOUT=60s
HEALTHCHECK_RETRIES=10
[root@sentry self-hosted]# ./install.sh --skip-user-creation # 安装sentry 这个过程很漫长

安装之后会提示创建用户登录

[root@sentry self-hosted]# docker-compose run --rm web createuser
创建相应的邮箱,密码 指的就是登录用户名,密码 提示作为超级用户
[root@sentry self-hosted]# docker-compose up -d # 运行sentry 然后浏览器访问 http://localhost:9000

登录界面如下(该图使用的saas平台sentry界面)

Snipaste_2023-03-21_15-44-29.png

设置时区及中文(刷新立即生效)

Snipaste_2023-03-21_15-49-10.png