什么是Sentry
Sentry 是一个错误信息收集系统 通过在项目中集成Sentry的SDK可以将
- 项目中的日志、报错 发送到Sentry后台展示
- 展示API接口的响应速度 一些性能数据
解决的问题
应用的错误,异常监控统计,报警通知;性能监控统计,对问题进行跟踪
Sentry 架构之美
- API 简单、易用,自动集成;安装简单:架构依赖多,但使用 Docker 可以一个命令安装
- 自动对错误,异常进行统计聚合,按照上下文的Tag进行聚合
- 可以对性能进行统计分析,可抽样;可视化的趋势分析
- 多租户,支持双因素认证,敏感内容自动脱敏
开放的架构:
- 可与 AD 域账号集成,与 Google/Stackoverflow 等账号集成
- 开放的架构:有完善的插件支持:Webhook/Gitlab/Jira/Slack/PushOver/....
- 支持不同环境(开发、测试、预发、线上);可以配置灵活的告警
- 跨平台,跨端的支持:Python/Java/JavaScript/Ruby/Go/..., Android/iOS/Web/
两种方法安装 Sentry
- 使用 Docker 官方服务(量大需要付费,使用方便);
- 自己搭建 服务(从源码安装,或者使用docker 搭建服务);
Sentry的工作流
Sentry的架构
- Symbolicator: 用来解析函数名,堆栈中的文件位置,代码上下文
- Relay: 用来处理收到的请求,会立刻返回200或者429, 然后把事件放在内存中排队, 然后发到 Kafka ingest-events
- ingest-consumer: 消费处理 Relay 发出的消息
- process_event: 堆栈处理,插件预处理
- postgresql: 用来保存完整的事件数据
- Snuba: 事件数据的存储和查询服务 对clickhouse做了封装
- clickhouse: 用作数据仓库,用于 OLAP,搜索,聚合,标签统计
- 其他的hbase hive
Snuba 的作用
安装 sentry(使用 Docker)
使用 release 版本
wget https://github.com/getsentry/self-hosted/archive/refs/tags/23.11.0.tar.gz
tar -xf 23.11.0.tar.gz
cd self-hosted-23.11.0
# 配置依赖 下载镜像
./install.sh
# 一键启动
docker-compose up -d
集成sentry
配置setting
import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration
sentry_sdk.init(
dsn="http://xxx@recruit.ihopeit.com:9000/2",
integrations=[DjangoIntegration()],
# performance tracing sample rate, 采样率, 生产环境访问量过大时,建议调小(不用每一个URL请求都记录性能)
traces_sample_rate=1.0, #
# If you wish to associate users to errors (assuming you are using
# django.contrib.auth) you may enable sending PII data.
send_default_pii=True
)
配置URL
def trigger_error(request):
division_by_zero = 1 / 0
urlpatterns = [
path('sentry-debug/', trigger_error),
]
修改中间件 interview/performance.py
from sentry_sdk import capture_exception
class PerformanceAndExceptionLoggerMiddleware:
def __init__(self, get_response):
self.get_response = get_response
# One-time configuration and initialization.
def __call__(self, request):
# Code to be executed for each request before
# the view (and later middleware) are called.
start_time = time.time()
response = self.get_response(request)
duration = time.time() - start_time
response["X-Page-Duration-ms"] = int(duration * 1000)
logger.info("duration:%s url:%s parameters:%s", duration, request.path, request.GET.dict() )
# Code to be executed for each request/response after
# the view is called.
return response
def process_exception(self, request, exception):
if exception:
message = "url:{url} ** msg:{error} ````{tb}````".format(
url = request.build_absolute_uri(),
error = repr(exception),
tb = traceback.format_exc()
)
logger.warning(message)
# send dingtalk message
dingtalk.send(message)
# capture exception to sentry:
capture_exception(exception)
return HttpResponse("Error processing the request, please contact the system administrator.", status=
修改setting
MIDDLEWARE = [
'interview.performance.PerformanceAndExceptionLoggerMiddleware',
interview/dingtalk.py
#coding=utf-8
from dingtalkchatbot.chatbot import DingtalkChatbot
from django.conf import settings
def send(message, at_mobiles=[]):
# 引用 settings里面配置的钉钉群消息通知的WebHook地址:
webhook = settings.DINGTALK_WEB_HOOK
# 初始化机器人小丁, # 方式一:通常初始化方式
xiaoding = DingtalkChatbot(webhook)
# 方式二:勾选“加签”选项时使用(v1.5以上新功能)
# xiaoding = DingtalkChatbot(webhook, secret=secret)
# Text消息@所有人
xiaoding.send_text(msg=('面试通知: %s' % message), at_mobiles = at_mobiles )
错误信息 已经上报到 Sentry和 钉钉