社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  docker

重启sentry+升级ExceptionLess版本,以及docker排坑记录

dotNET跨平台 • 4 月前 • 134 次点击  

前言

自从去年sentry又挂了之后,再加上大部分项目都是 C# 的,使用 ExceptionLess 的体验已经很不错了,所以我们就一直没再使用 sentry 🦎

前天刚把 Gitlab 配置好,接下来有一些其他语言☕️的项目要监控,我想着继续把 sentry 也重启了。然后 ExceptionLess 也很久没更新了,官方已经出到8.x版本,我们还在用 7.x,这次也顺便升级一下⛰️

没想到这一搞就折腾了一整天时间🥱,人都麻了🐎

sentry

关于sentry📄

在软件开发的世界里,错误跟踪和性能监控是保证应用健康和用户满意度的关键。这就是 Sentry 发挥作用的地方。Sentry 是一个开源的实时错误跟踪工具,它能有效帮助开发者监控和修复各种编程语言中的错误。无论是前端 JavaScript 错误还是后端 Python 异常,Sentry 都能捕捉到,并提供详尽的错误报告和分析。

核心功能

  • 实时监控:Sentry 提供实时错误监控,一旦应用出现错误,它会立即捕获并通知开发者。
  • 跨平台支持:支持多种编程语言和框架,包括 JavaScript, Python, Java, Ruby, PHP 等。
  • 详细的错误报告:每个错误报告都包含了足够的信息,帮助开发者快速定位问题源头。这些信息包括错误发生的堆栈跟踪、受影响的用户、错误发生的时间以及错误前后的应用状态。
  • 性能监控:不仅可以跟踪错误,还能监控应用的性能状况,如页面加载时间、API响应时间等,帮助开发者优化用户体验。
  • 问题分析与解决:提供问题的趋势分析、影响范围评估及解决方案建议,使问题处理更加高效。

使用场景

Sentry 的使用场景广泛,它不仅适用于大型企业的复杂应用,也适合小型开发团队和个人项目。例如,在开发过程中集成 Sentry 可以持续监控应用状态,一旦部署新版本后出现问题,Sentry 可以帮助快速回滚并修复。此外,其用户友好的界面和强大的配置能力,让它成为处理错误和提升应用质量的得力工具。

self hosted

首先是部署 sentry,实际上并不难

为什么会折腾那么久,最后总结下来最主要的就是网络问题,其次是版本问题,官方文档用的是 24.1.0,我一开始用了 github 上最新的 24.7.0 一直不行🙅‍♀️

最终是通过 cloudflare worker 解决的,可以参考之前这篇文章:使用Cloudflare Worker加速docker镜像


官方文档写得很详细: https://develop.sentry.dev/self-hosted/

按照官方的步骤走就完事了

解决网络问题之后,基本没啥障碍🥱

安装sentry⏬

VERSION="24.1.0"
git clone https://github.com/getsentry/self-hosted.git
cd self-hosted
git checkout ${VERSION}
sudo ./install.sh

如果要安装过程显示详细一点,可以加上 DEBUG=1 环境变量,然后顺便把遥测关了📴

sudo DEBUG=1 ./install.sh --no-report-self-hosted-issues

问题记录📝

当时安装时真的一波三折😭,这里记录遇到的一些问题

  • 配置了 .env.custom 文件,导致执行 upgrade-clickhouse.sh 出错,一开始我还没用 Cloudflare Worker 来加速docker,所以打算用代理来pull image,官网文档说要把代理写在 /etc/environment 里,但我不想这么做,于是把代理配置放在 .env.custom 里,结果一直报错。
  • 然后是 docker compose 版本的问题,本地的 compose 版本小于他要求的版本,升级这个 compose 也遇到一点小小的问题,我的 compose 执行文件在 ~/.docker/cli-plugins/docker-compose ,表现是 docker plugins ,不过却识别不到,没法用 docker plugins 命令来更新,最后是直接在 github 下载可执行文件去替换,真正的解决方法往往是这么朴实无华。
  • 剩下的就是网络🌍问题了,有几个镜像一直拉不下来

主要组件⚙️

Sentry 的本体是基于 Django 开发的,Python 的灵活性和生态系统中的丰富库使其成为开发复杂应用程序如 Sentry 的一个理想选择,前端页面是 React 开发的。

整个 sentry 还是比较复杂的,当前版本跑起来之后有28个容器,对服务器的性能有一定要求。

主要🈶️这些组件:

  • ClickHouse: 一个高性能的列式数据库,专门用于处理大规模数据分析,Sentry 用它来存储和查询事件数据。
  • Redis: 一个内存中的数据结构存储系统,用作数据库、缓存和消息代理,Sentry 用它来处理队列和缓存任务。
  • PostgreSQL: 一个强大的开源关系数据库,Sentry 使用它来存储核心数据,包括项目配置和用户数据。
  • Kafka: 一个分布式流处理平台,Sentry 使用 Kafka 来处理事件流和确保数据的弹性处理。
  • Zookeeper: 主要用于服务协调和配置管理,在 Sentry 中与 Kafka 配合使用,用于维护 Kafka 的服务状态。
  • Snuba: Sentry 的服务组件之一,用 Python 编写,主要负责查询 ClickHouse 中的数据。
  • Symbolicator: 用于处理原生堆栈跟踪的服务,帮助解析和符号化未处理的堆栈跟踪。
  • Relay: 一个独立的服务,用于处理从客户端发送到 Sentry 的事件,提供数据清洗和安全性控制。

各个容器介绍📂

这些容器共同构成了 Sentry 的复杂架构,确保从数据收集到处理再到存储的每一环节都能高效、稳定地运行。

可以看到 sentry 是个非常重的监控服务

  1. attachments-consumer: 处理和存储错误报告中的附件数据。
  2. billing-metrics-consumer: 管理和处理与计费相关的度量数据。
  3. cron: 处理定时任务,如清理作业和触发定期任务。
  4. events-consumer: 接收和处理事件数据,确保它们被正确地存储和索引。
  5. generic-metrics-consumer: 处理通用度量数据,用于监控和分析。
  6. ingest-monitors: 处理和监控数据摄取过程中的事件和状态。
  7. ingest-occurrences: 处理事件发生的数据摄取。
  8. ingest-profiles: 管理用户的性能分析数据摄取。
  9. ingest-replay-recordings: 处理回放录像的数据摄取,用于错误复现。
  10. memcached: 提供内存缓存服务,增强数据读写速度和效率。
  11. metrics-consumer: 处理和聚合应用性能监控(APM)的度量数据。
  12. nginx: 作为反向代理服务器,处理 HTTP 请求和负载平衡。
  13. post-process-forwarder-errors: 处理错误事件的后处理和转发任务。
  14. post-process-forwarder-issue-platform: 处理问题平台的事件后处理和转发。
  15. post-process-forwarder-transactions: 处理事务事件的后处理和转发。
  16. postgres: 为 Sentry 提供关系数据库服务,存储配置和用户数据。
  17. redis: 提供队列管理和缓存服务,支持事件处理和数据缓存。
  18. relay: 接收客户端的事件,进行清洗和安全校验后转发到 Sentry。
  19. smtp: 处理电子邮件发送,用于通知和报告。
  20. snuba-api: 提供 API 接口访问 ClickHouse 存储的数据。
  21. snuba-replacer: 处理和替换 Snuba 中的数据,用于数据修正和去重。
  22. subscription-consumer-events: 管理事件数据订阅,处理相关通知。
  23. subscription-consumer-generic-metrics: 管理通用度量数据的订阅和通知。
  24. subscription-consumer-metrics: 管理度量数据的订阅和处理。
  25. subscription-consumer-transactions: 管理事务数据的订阅和处理。
  26. transactions-consumer: 处理和存储事务数据,支持应用性能监控。
  27. vroom: 处理特定于 Sentry 的内部请求和作业。
  28. zookeeper: 作为分布式服务的协调者,管理 Kafka 和其他服务的状态信息。

sentry有替代品吗?

🈶️

折腾的过程中,我一度想过要放弃,然后找到了两个看起来好像不错的开源替代品:

  • https://glitchtip.com/
  • https://www.highlight.io/

还没尝试,有空来部署试试,虽然现在sentry能用了,但毕竟还是太重了。

ExceptionLess

🌟 遇见 Exceptionless:你的代码的小小守护精灵! 🌟

嘿,亲爱的开发者朋友们!有没有想过,如果你的代码中有一个小小的守护精灵,它会帮你捕捉所有那些调皮的错误和异常,然后偷偷地告诉你哪里出了问题,让你的调试工作变得轻松又愉快呢?好消息,这个小精灵已经存在了,它的名字叫 Exceptionless!🎉

🚀 什么是 Exceptionless?

Exceptionless 不仅仅是一个工具,它是一个超级可爱的、功能强大的开源错误和事件报告服务。它就像是你的编程旅程中的忠实伙伴,一旦集成到你的应用中,它就会自动捕获未处理的异常和事件。想象一下,无论何时你的代码有点小插曲,Exceptionless 都会在第一时间抓住它们,并把这些信息安静地放在你的仪表板上,等你去查看。🐞

🌈 为什么它如此特别?

  • 自动化监控:你只需轻轻一集成,Exceptionless 就会自动开始监控,你甚至不需要告诉它从何处开始!
  • 实时反馈:收到实时错误报告,让你可以即刻了解发生了什么,就像有一个小精灵在你耳边低语。
  • 深入洞察:不仅仅是告诉你“出错啦”,Exceptionless 还会告诉你为什么出错,哪里出错,甚至是谁遇到了这个错误。🕵️‍♂️

💖 开发者的最佳朋友

是否厌倦了那些冷冰冰的日志文件?让 Exceptionless 加入你的开发生活吧!它会用它那可爱的方式,带给你错误跟踪的全新体验。它不仅能帮助你修复错误,还能帮助你优化你的应用,让用户体验更上一层楼!

所以,让我们一起欢迎 Exceptionless,让它成为我们代码世界中的小英雄吧!使用 Exceptionless,一起把“糟糕”的时刻变成“搞定啦”的时刻!🌟

升级版本

OK,就像之前说的那样,我要把7.x升级到8.x

ExceptionLess 的文档比 sentry 差太多了,写得不清不楚的,不过好在我已经熟练使用这玩意了。

这个也比 sentry 简单一些,就几个组件。

  • ExceptionLess 官网文档是虚假的文档 ✖
  • Github 仓库才是真正的文档 ✅

直接使用这个配置: https://github.com/exceptionless/Exceptionless/blob/main/samples/docker-compose.yml

不过为了更好的部署,还需要做一些小小的修改:

  • 每个容器加上了 container_name 配置
  • 加上 restart 保证容器会自动启动
  • 关闭 app 容器的 HTTPS 功能,使用 swag 来提供就行
  • 把所有端口映射关掉
  • 把 volumes 映射全改成当前目录了,记得先创建这些目录,并且赋权,例如 chmod -R 1000:1000 esdata/
  • 与 swag 网络桥接,外部无法访问到这组容器,只能通过 swag 进行反代
  • 配置了邮箱,具体可以参考之前的 ExceptionLess 安装配置文章
services:
  app:
    restart: always
    depends_on:
      - elasticsearch
      - redis
    image: exceptionless/app:latest
    container_name: exless_app
    environment:
      EX_AppMode: Production
      EX_ConnectionStrings__Cache: provider=redis
      EX_ConnectionStrings__Elasticsearch: server=http://elasticsearch:9200
      EX_ConnectionStrings__MessageBus: provider=redis
      #EX_ConnectionStrings__Metrics: provider=statsd;server=statsd;
      EX_ConnectionStrings__Queue: provider=redis
      EX_ConnectionStrings__Redis: server=redis,abortConnect=false
      EX_ConnectionStrings__Storage: provider=folder;path=/app/storage
      #ASPNETCORE_URLS: http://+;https://+
      ASPNETCORE_URLS: http://+:80
      #ASPNETCORE_HTTPS_PORT: 5001
      #ASPNETCORE_Kestrel__Certificates__Default__Password: password
      #ASPNETCORE_Kestrel__Certificates__Default__Path: /https/aspnetapp.pfx
      EX_RunJobsInProcess: 'false'
    volumes:
      - ./appdata:/app/storage
      - ./ssldata:/https
    networks:
      - default
      - swag

  jobs:
    restart: always
    depends_on:
      - app
    image: exceptionless/job:latest
    container_name: exless_jobs
    environment:
      EX_AppMode: Production
      EX_BaseURL: http://app:80
      EX_ConnectionStrings__Cache: provider=redis
      EX_ConnectionStrings__Elasticsearch: server=http://elasticsearch:9200
      EX_ConnectionStrings__Email: smtps://邮箱(需转义):密码@smtp.exmail.qq.com:465
      EX_SmtpFrom: 邮箱地址
      EX_ConnectionStrings__MessageBus: provider=redis
      #EX_ConnectionStrings__Metrics: provider=statsd;server=statsd;
      EX_ConnectionStrings__Queue: provider=redis
      EX_ConnectionStrings__Redis: server=redis,abortConnect=false
      EX_ConnectionStrings__Storage: provider=folder;path=/app/storage
    volumes:
      - ./appdata:/app/storage
    networks:
      - default

  elasticsearch:
    image: exceptionless/elasticsearch:8.14.1
    restart: always
    container_name: exless_es
    environment:
      discovery.type: single-node
      xpack.security.enabled: "false"
      ES_JAVA_OPTS: -Xms1g -Xmx2g
    expose:
      - 9200
      - 9300
    volumes:
      - ./esdata:/usr/share/elasticsearch/data
    networks:
      - default

  kibana:
    restart: always
    depends_on:
      - elasticsearch
    image: docker.elastic.co/kibana/kibana:8.14.1
    container_name: exless_kibana
    expose:
      - 5601
    networks:
      - default

  redis:
    restart: always
    image: redis:7.2-alpine
    container_name: exless_redis
    expose:
      - 6379
    networks:
      - default

networks:
  default:
    name: exless
  swag:
    name: swag
    external: true

折腾的问题

  • Elasticseach 版本升级问题: 之前是7.x版本,现在升级后是8.x版本,这俩版本的数据文件都不一样,需要做迁移,但因为前一天部署 sentry 把环境搞烂了,这次 ExceptionLess 也跑不起来,最后干脆整个 Elasticsearch 都删掉了
  • Elasticsearch 健康检查不通过问题: 一直报错提示 [02:22:16 ERR] Health check Elasticsearch with status Unhealthy completed after 242.2644ms with message 'null' ,这个是多方面的问题,等下来说
  • docker 内部的DNS解析问题: 很奇怪,其他的项目都不会这样,后面也莫名其妙解决了,真实奇怪,盲猜和代理可能有点关系?🥱

Elasticsearch Unhealthy 问题

这个是最折磨的

一开始是7升级8的问题

然后把数据清理掉从头开始,已经能正常启动es8了

但是app和jobs容器还一直连不上

然后又经历了漫长的排错阶段,包括使用 busybox 和 alpine 容器去各种测网络

其中的玄学问题自不必说

一会就 docker DNS 失效

一会就各种连不上,最终在代理服务器的日志上发现了一堆标红的 elasticsearch:9200 访问,才发现问题出在代理上。

但我把环境变量、~/.docker/config.json 的代理都去掉了,还是会走代理,真的服了,这也成玄学问题了。

最终只能在代理服务器上加了个规则……

docker排坑

折腾花了好多时间

技术没学到

docker 排坑经验倒是增加了一丢丢

查容器的IP地址

其实用 portainer 这类工具可以很方便查看的,不过用命令也不难

exless-es 是容器名称,下面都会用这个作为栗子

docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' exless-es

使用临时容器测试网络连通性

现在的容器一般都是基于 alpine 这种轻量级发行版构建,没有 curl 之类的工具可以测试网络

没事,我们可以创建一个临时容器,加入到这组 compose 的网络里来测试,本文里这个网络名称是 exless

curl

以下命令是启动一个 curl 容器来测试 http://elasticsearch:9200 地址能否访问

docker run --rm --network=exless appropriate/curl http://elasticsearch:9200

busybox/alpine

docker run --rm -it --network=exless busybox

或者🔥

docker run --rm -it --network=exless alpine

这样就可以使用 ping, nslookup, dig 之类的工具,来排查网络问题

在 compose 配置里加入临时容器

这个方法也可以

services:
  busybox:
    image: busybox
    container_name: exless-busybox
    command: sleep 3600  # 让容器运行一个小时,足够进行测试
    networks:
      - default  # 确保这是你其他服务使用的网络

小结

就这样吧

折腾的过程真的是究极折磨

写这篇文章仿佛又被折磨了一遍……

参考资料

  • https://develop.sentry.dev/self-hosted/
  • https://github.com/exceptionless/Exceptionless


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/172481
 
134 次点击