十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
本文转载自微信公众号「运维开发故事」,作者乔克 。转载本文请联系运维开发故事公众号。

大家好,我是乔克,一名一线运维实践者。
今天和大家分享一下什么是错误跟踪系统,以及如何使用。
在应用的整个生命周期里,避无可避的就是“错误”,很多时候都是借助日志平台来捕获、查看日志,以此来找到错误的原因,但是很多时候应用的日志有很多误导性,也不能够很直观的指出问题的源点,并且也缺乏及时分析和告警能力(当然现在很多商用的日志系统都有这个功能了,但是需要Money)。
有没有比较好用的开源软件呢?
Sentry就是这样一款优秀的应用错误跟踪系统,并且支持大多数的语言,如下。
从字面上就可以很好理解,错误跟踪系统就是跟踪系统错误、异常的一个软件,旨在帮助开发、运维等技术人员跟踪应用的一些错误信息。
通过对应用的错误进行实时追踪并统一跟进,提高对错误的治理能力。让业务场景下自己发现Bug的速度快于用户报告Bug的速度。
Sentry是一个跨平台的应用错误跟踪系统,专注于错误报告。
Sentry的原理是什么呢?
首先,应用要集成Sentry的SDK,然后在应用发生错误时将错误信息发送给Sentry服务端。Sentry的服务端分为web、cron、worker这几个部分,应用(客户端)发生错误后将错误信息上报给web,web处理后放入消息队列或Redis内存队列,worker从队列中消费数据进行处理 。
其主要优点如下:
当然也有一些缺点,针对维护部署其需要的中间件非常多,有kafka、rabbitMQ、redis、pgsql等,这一套部署下来的成本还是比较高。不过瑕不掩瑜,相比于它给我们带来的好处,这些问题都可以克服。
image.png
Sentry提供服务的方式有两种:
这里主要阐述如何在Kubernetes中进行部署。
环境介绍
OpenEBS简介
OpenEBS是一款使用Go语言编写的基于容器的块存储开源软件。OpenEBS使得在容器中运行关键性任务和需要数据持久化的负载变得更可靠。
使用OpenEBS,你可以将有持久化数据的容器,像对待其他普通容器一样来对待。OpenEBS本身也是通过容器来部署的,支持Kubernetes、Swarm、Mesos、Rancher编排调度,存储服务可以分派给每个pod、应用程序、集群或者容器级别,包括:
OpenEBS的架构可以分为数据平面(Data Plane)和控制平面(Control Plane)两部分:
1、部署OpenEBS
OpenEBS支持Helm Chart和Operator部署.
(1)使用Helm Chart部署
- helm repo add openebs https://openebs.github.io/charts
 - helm repo update
 - helm install openebs --namespace openebs openebs/openebs --create-namespace
 
(2)使用Operator部署
- kubectl apply -f https://openebs.github.io/charts/openebs-operator.yaml
 
部署完成后会生成如下Pod。
- # kubectl get pod -n openebs
 - NAME READY STATUS RESTARTS AGE
 - maya-apiserver-67b5b5c858-4mstb 1/1 Running 0 5d19h
 - openebs-admission-server-6bdf9b76d6-r4r6b 1/1 Running 0 5d19h
 - openebs-localpv-provisioner-966d864cd-sf8fp 1/1 Running 0 5d19h
 - openebs-ndm-59lkx 1/1 Running 0 5d19h
 - openebs-ndm-bphgw 1/1 Running 0 5d19h
 - openebs-ndm-grxlb 1/1 Running 0 5d19h
 - openebs-ndm-operator-55b8ccc64b-r7tkr 1/1 Running 0 5d19h
 - openebs-ndm-zwhmm 1/1 Running 0 5d19h
 - openebs-provisioner-55794b6cd4-ptd85 1/1 Running 0 5d19h
 - openebs-snapshot-operator-5d78fcbd96-7xqzv 2/2 Running 0 5d19h
 
以及如下的StorageClass。
- # kubectl get sc | grep openebs
 - local (default) openebs.io/local Delete WaitForFirstConsumer false 5d19h
 - openebs-device openebs.io/local Delete WaitForFirstConsumer false 5d19h
 - openebs-hostpath openebs.io/local Delete WaitForFirstConsumer false 5d19h
 - openebs-jiva-default openebs.io/provisioner-iscsi Delete Immediate false 5d19h
 - openebs-snapshot-promoter volumesnapshot.external-storage.k8s.io/snapshot-promoter Delete Immediate false 5d19h
 
2、部署Postgresql
其实在Sentry的Helm Chart中有Postgresql的Chart包,这里之所以单独来部署,是因为通过Sentry中的Chart包部署,在Postgresql环节出现了各种问题,比如:
- FATAL: password authentication failed for user "postgres"
 
这里通过Helm Chart来部署Postgresql,具体步骤如下:
- # 添加Helm仓库
 - helm repo add bitnami https://charts.bitnami.com/bitnami
 - helm repo update
 - # 把Chart包下载下来
 - helm pull bitnami/postgresql
 
编写配置文件(my-value.yaml),如下:
- global:
 - postgresql:
 - postgresqlDatabase: "sentry"
 - postgresqlUsername: "postgres"
 - existingSecret: ""
 - postgresqlPassword: "postgres"
 - servicePort: ""
 - replicationPassword: ""
 
安装PGSQL,命令如下:
- helm install postgresql -n sentry -f my-value.yaml bitnami/postgresql
 
部署完成后,可以看到如下Pod:
- # kubectl get po -n sentry
 - NAME READY STATUS RESTARTS AGE
 - postgresql-postgresql-0 1/1 Running 0 3h39m
 
3、部署Sentry
Sentry也是采用Helm Chart来进行部署,如下:
- # 添加Helm仓库
 - helm repo add sentry https://sentry-kubernetes.github.io/charts
 - helm repo update
 - helm search repo sentry
 - # 下载Chart包,便于查看修改Chart
 - helm pull sentry/sentry
 
编写配置文件(my-value.yaml),如下:
- externalPostgresql:
 - database: sentry
 - port: 5432
 - username: postgres
 - host: postgresql
 - password: postgres
 - postgresql:
 - enabled: false
 - mail:
 - backend: dummy
 - from: "joker2021@163.com"
 - host: "smtp"
 - password: "UZKSGLFEANWGLZNT"
 - port: 465
 - useTls: true
 - username: ""
 - user:
 - create: true
 - email: admin@sentry.local
 - password: P@ssword
 
部署Sentry,如下:
- helm install sentry -n sentry -f my-value.yaml sentry/sentry
 
部署完成后,会生成如下Pod:
- # kubectl get po -n sentry
 - NAME READY STATUS RESTARTS AGE
 - postgresql-postgresql-0 1/1 Running 0 3h50m
 - sentry-clickhouse-0 1/1 Running 0 3h50m
 - sentry-clickhouse-1 1/1 Running 0 3h50m
 - sentry-clickhouse-2 1/1 Running 0 3h50m
 - sentry-cron-578647dd7-gk7gf 1/1 Running 0 3h50m
 - sentry-ingest-consumer-7564f644bf-srkj2 1/1 Running 0 3h47m
 - sentry-kafka-0 1/1 Running 2 3h50m
 - sentry-kafka-1 1/1 Running 2 3h50m
 - sentry-kafka-2 1/1 Running 2 3h50m
 - sentry-nginx-675d779699-tfdr5 1/1 Running 0 3h50m
 - sentry-post-process-forward-5f586f6cdf-lxmc4 1/1 Running 0 3h47m
 - sentry-rabbitmq-0 1/1 Running 0 3h50m
 - sentry-rabbitmq-1 1/1 Running 0 3h49m
 - sentry-rabbitmq-2 1/1 Running 0 3h48m
 - sentry-relay-75597cb98b-jm282 1/1 Running 0 3h47m
 - sentry-sentry-redis-master-0 1/1 Running 0 3h50m
 - sentry-sentry-redis-slave-0 1/1 Running 0 3h50m
 - sentry-sentry-redis-slave-1 1/1 Running 0 3h49m
 - sentry-sessions-consumer-6b499bf64d-lm7gq 1/1 Running 0 3h47m
 - sentry-snuba-api-5586d5f9f8-tcn5s 1/1 Running 0 3h50m
 - sentry-snuba-cleanup-errors-1630472400-xv5wh 0/1 Completed 0 134m
 - sentry-snuba-cleanup-errors-1630476000-xd7d2 0/1 Completed 0 74m
 - sentry-snuba-cleanup-errors-1630479600-sd59b 0/1 Completed 0 14m
 - sentry-snuba-cleanup-transactions-1630472400-l9bcx 0/1 Completed 0 134m
 - sentry-snuba-cleanup-transactions-1630476000-cjsbd 0/1 Completed 0 74m
 - sentry-snuba-cleanup-transactions-1630479600-zn5dz 0/1 Completed 0 14m
 - sentry-snuba-consumer-58b7bfd545-rnjmx 1/1 Running 0 3h47m
 - sentry-snuba-outcomes-consumer-57c589bf6d-lxg5m 1/1 Running 0 3h47m
 - sentry-snuba-replacer-5bf4d6b5d7-gcc7g 1/1 Running 0 3h47m
 - sentry-snuba-transactions-consumer-57bb7f8ccb-q6gkt 1/1 Running 0 3h47m
 - sentry-web-7c9766768b-njxjl 1/1 Running 0 3h50m
 - sentry-worker-844fd65687-6b26p 1/1 Running 2 3h50m
 - sentry-worker-844fd65687-k2h6z 1/1 Running 2 3h50m
 - sentry-worker-844fd65687-rfjcl 1/1 Running 2 3h50m
 - sentry-zookeeper-0 1/1 Running 0 3h50m
 
然后可以通过ingress或者nodeport的方式进行访问,用户名和密码是上面配置的admin@sentry.local和P@ssword。
进入WEB UI界面,在项目专栏创建项目,如下:
我这里创建一个Go项目,如下:
点击创建后,就会生成一个Dsn地址,并且给出一个配置示例,如下:
- package main
 - import (
 - "fmt"
 - "github.com/getsentry/sentry-go"
 - sentrygin "github.com/getsentry/sentry-go/gin"
 - "github.com/gin-gonic/gin"
 - "github.com/pkg/errors"
 - "net/http"
 - )
 - func main() {
 - // To initialize Sentry's handler, you need to initialize Sentry itself beforehand
 - if err := sentry.Init(sentry.ClientOptions{
 - Dsn: "https://b06bcc1c67b44084a3f65fc8b219a5fc@o985819.ingest.sentry.io/5942245",
 - }); err != nil {
 - fmt.Printf("Sentry initialization failed: %v\n", err)
 - }
 - sentry.CaptureMessage("It works!")
 - sentry.CaptureException(errors.New("error msg"))
 - // Then create your app
 - app := gin.Default()
 - // Once it's done, you can attach the handler as one of your middleware
 - app.Use(sentrygin.New(sentrygin.Options{}))
 - // Set up routes
 - app.GET("/", func(ctx *gin.Context) {
 - ctx.String(http.StatusOK, "Hello world!")
 - })
 - // And run it
 - app.Run(":3000")
 - }
 
其他类型的项目与此类似,具体步骤也就三步:
然后应用部署过后,就会通过Post的方式上报应用错误,届时就可以在WEB界面进行查看。
image.png
创建警报
可以创建的告警类型还是比较丰富,如下:
然后创建规则,如下:
除此之外还可以进行团队、成员管理,日志审计等,更多功能需要自己去实践了。