Sentry 错误预警系统的运维

在上一章中,我们介绍了EBLK的日志分析平台。

在日志分析平台上,我们可以很方便的查找系统的日志。然而,EBLK并总是能满足需求:

  • 日志绝大多数是INFO等级的,即信息日志。如果系统运行出现问题,我们想从中查找,实际希望的是找到ERROR类型的或者异常信息。
  • 我们经常需要排查一些历史故障,即需要增加时间维度的信息
  • 我们希望经常出现的类似错误,能够聚合在一起,方便我们排查

Sentry是一个实时的事件日志和聚合平台,我们可以通过配置,把所有ERROR类型的日志发送给Sentry保存下来,并通过其聚合结果,迅速的定位线上问题。

在本节中,我们将探讨Sentry预警系统的运维工作。

由于Sentry服务本身比较复杂,涉及多个步骤初始化步骤及多个Volume,因此我们不再采用Kubernetes集群,而是通过Docker直接部署在某台物理机上。

Sentry存储依赖的部署

Sentry服务需要使用两个存储:Redis、Postgres,我们首先启动这两个依赖服务。

首先创建redis, sentry-redis.sh:

  1. #!/bin/bash
  2. NAME="sentry-redis"
  3. VOLUME="/home/coder4/docker_data/sentry-redis"
  4. # make sure volume valid
  5. mkdir -p $VOLUME && sudo chmod -R 777 $VOLUME
  6. # kill old and run new
  7. docker ps -q -a --filter "name=$NAME" | xargs -I {} docker rm -f {}
  8. docker run \
  9. --hostname $NAME \
  10. --name $NAME \
  11. --volume "$VOLUME":/data \
  12. --detach \
  13. --restart always \
  14. redis:4

如上所述:

  • 创建了基于redis 4的容器
  • 设置volume到/data,这样,重启redis并不会导致数据丢失

接着,我们创建Postegres数据库, sentry_postgres.sh:

  1. #!/bin/bash
  2. NAME="sentry-postgres"
  3. VOLUME="/home/coder4/docker_data/sentry-postgres"
  4. POSTGRES_DB_USER="sentry"
  5. POSTGRES_DB_PASS="sentry_pass"
  6. # make sure volume valid
  7. sudo mkdir -p $VOLUME && sudo chmod -R 777 $VOLUME
  8. # kill old and run new
  9. docker ps -q -a --filter "name=$NAME" | xargs -I {} docker rm -f {}
  10. docker run \
  11. --hostname $NAME \
  12. --name $NAME \
  13. --volume "$VOLUME":/var/lib/postgresql/data \
  14. --env POSTGRES_USER=$POSTGRES_DB_USER \
  15. --env POSTGRES_PASSWORD=$POSTGRES_DB_PASS \
  16. --detach \
  17. --restart always \
  18. postgres:10

Sentry 服务的部署

在正式部署Sentry之前,首先要生成key:

  1. docker run --rm sentry config generate-secret-key

输出结果是

  1. q5%_k4t#w#43rlnd(mr1ms%p8(mjofh9z&4al8d1q&a3f#19_d

记住这个key,我们马上会用到。

下面,我们对Sentry进行初始化:

  1. #!/bin/bash
  2. NAME="sentry-main"
  3. REDIS_LINK="sentry-redis:redis"
  4. POSTGRES_LINK="sentry-postgres:postgres"
  5. SENTRY_SECRET="q5%_k4t#w#43rlnd(mr1ms%p8(mjofh9z&4al8d1q&a3f#19_d"
  6. # kill old and run new
  7. docker ps -q -a --filter "name=$NAME" | xargs -I {} docker rm -f {}
  8. docker run \
  9. --hostname $NAME \
  10. --name $NAME \
  11. --env SENTRY_SECRET_KEY=$SENTRY_SECRET \
  12. -it \
  13. --restart always \
  14. --link $REDIS_LINK \
  15. --link $POSTGRES_LINK \
  16. sentry:9 upgrade

在执行db操作一段时间后,会有一个交互,如下:

  1. Email: lihy@coder4.com
  2. Password:
  3. Repeat for confirmation:
  4. Should this user be a superuser? [y/N]: y
  5. User created: lihy@coder4.com
  6. ...

创建好的用户,就是之后默认的管理员用户

初始化完毕后,我们正式创建Sentry:

  1. #!/bin/bash
  2. NAME="sentry-main"
  3. REDIS_LINK="sentry-redis:redis"
  4. POSTGRES_LINK="sentry-postgres:postgres"
  5. SENTRY_SECRET="q5%_k4t#w#43rlnd(mr1ms%p8(mjofh9z&4al8d1q&a3f#19_d"
  6. # kill old and run new
  7. docker ps -q -a --filter "name=$NAME" | xargs -I {} docker rm -f {}
  8. docker run \
  9. --hostname $NAME \
  10. --name $NAME \
  11. -p 8080:9000 \
  12. --env SENTRY_SECRET_KEY=$SENTRY_SECRET \
  13. --detach \
  14. --restart always \
  15. --link $REDIS_LINK \
  16. --link $POSTGRES_LINK \
  17. sentry:9

与上面的初始化相比,脚本基本是类似的,差别在于:

  • 使用的是后台运行detach而非-it交互模式
  • 没有执行upgrade命令
  • 开放了8080端口

执行成功后,我们访问http://localhost:8080,即可成功进入登录界面,如下图所示:

Sentry登录界面

如果你现在登录的话,会提示”Background workers havn’t checked in recently…”,即后台收集进程&定时任务没有启动。

我们首先来启动收集进程:

  1. #!/bin/bash
  2. NAME="sentry-worker"
  3. REDIS_LINK="sentry-redis:redis"
  4. POSTGRES_LINK="sentry-postgres:postgres"
  5. SENTRY_SECRET="q5%_k4t#w#43rlnd(mr1ms%p8(mjofh9z&4al8d1q&a3f#19_d"
  6. # kill old and run new
  7. docker ps -q -a --filter "name=$NAME" | xargs -I {} docker rm -f {}
  8. docker run \
  9. --hostname $NAME \
  10. --name $NAME \
  11. --env SENTRY_SECRET_KEY=$SENTRY_SECRET \
  12. --detach \
  13. --restart always \
  14. --link $REDIS_LINK \
  15. --link $POSTGRES_LINK \
  16. sentry:9 run worker

然后启动定时任务:

  1. #!/bin/bash
  2. NAME="sentry-cron"
  3. REDIS_LINK="sentry-redis:redis"
  4. POSTGRES_LINK="sentry-postgres:postgres"
  5. SENTRY_SECRET="q5%_k4t#w#43rlnd(mr1ms%p8(mjofh9z&4al8d1q&a3f#19_d"
  6. # kill old and run new
  7. docker ps -q -a --filter "name=$NAME" | xargs -I {} docker rm -f {}
  8. docker run \
  9. --hostname $NAME \
  10. --name $NAME \
  11. --env SENTRY_SECRET_KEY=$SENTRY_SECRET \
  12. --detach \
  13. --restart always \
  14. --link $REDIS_LINK \
  15. --link $POSTGRES_LINK \
  16. sentry:9 run cron

启动后稍等一会,我们用初始化时设置的用户名、密码登录系统,进入初始化界面:

Sentry初始配置界面

配置如下:

  • Root URL写入一个可以DNS解析的域名,例如sentry.coder4.com
  • Admin Email写入任意一个邮件地址,例如sentry@coder4.com

配置好后,进入如下的登台添加新项目界面,至此,Sentry的部署工作配置完成。

Sentry完成界面

思考与拓展

  • 在本节的部署中,我们使用了默认的账户配置模式。前面介绍过,在团队内部,应该使用统一的帐号系统以提升效率。如何让Sentry系统接入LDAP帐号服务呢,请自行查找资料,实现这个功能。