34.错误信息上报、Sentry介绍、部署、异常发送钉钉

469 阅读3分钟

什么是Sentry

develop.sentry.dev/self-hosted…

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的工作流

image.png

Sentry的架构

image.png

  • Symbolicator: 用来解析函数名,堆栈中的文件位置,代码上下文
  • Relay: 用来处理收到的请求,会立刻返回200或者429, 然后把事件放在内存中排队, 然后发到 Kafka ingest-events
  • ingest-consumer: 消费处理 Relay 发出的消息
  • process_event: 堆栈处理,插件预处理
  • postgresql: 用来保存完整的事件数据
  • Snuba: 事件数据的存储和查询服务 对clickhouse做了封装
  • clickhouse: 用作数据仓库,用于 OLAP,搜索,聚合,标签统计
    • 其他的hbase hive

Snuba 的作用

安装 sentry(使用 Docker)

使用 release 版本

github.com/getsentry/o…

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),
]

image.png

修改中间件 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和 钉钉 image.png