低配环境下的Sentry错误监控的坑

低配环境下的Sentry错误监控的坑

十月 30, 2019

Sentry 是一个实时事件日志记录和汇集的平台,可以收集前端、后端程序的错误日志。
Sentry官方docker安装在内存低于3g时会直接退出。
但实际上如果数据量较小,在配置更低的服务器上也可以安装并流畅使用。

环境准备

官方推荐的方法是使用Docker, 为安装方便就以使用Docker为例,安装docker和docker-compose:

  1. 安装docker

    1
    2
    3
    4
    5
    6
    #国内Daocloud镜像
    curl -sSL https://get.daocloud.io/docker | sh
    #官方安装
    wget -qO- https://get.docker.com/ | sh
    #检查
    docker -v
  2. 安装docker-compose

    1
    2
    3
    4
    5
    6
    7
    8
    #docker-compose 国内 https://get.daocloud.io/#install-compose
    curl -L "https://get.daocloud.io/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
    chmod +x /usr/local/bin/docker-compose
    #docker-compose 官方
    curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
    chmod +x /usr/local/bin/docker-compose
    #检查
    docker-compose --version
  3. 下载Sentry官方一键包

    1
    2
    git clone https://github.com/getsentry/onpremise.git sentry
    cd sentry

安装

为了安装方便,建议直接使用一键脚本install.sh

内存限制

首先修改install.sh前几行中的内存限制:

1
2
MIN_RAM=1024 #3072 # MB
#改为你的内存大小

禁用自带邮件服务器

sentry自带exim4作为邮件服务器,但如果使用smtp这个exim4就只能占内存了,因此可以通过修改docker-compose.yml把它禁用掉。
需要修改三处:

1
2
3
4
5
6
7
#找到这里
depends_on:
- redis
- postgres
- memcached
#注释下面这行
#- smtp
1
2
3
4
5
6
7
#找到这里
environment:
SENTRY_MEMCACHED_HOST: memcached
SENTRY_REDIS_HOST: redis
SENTRY_POSTGRES_HOST: postgres
#注释下面这行
#SENTRY_EMAIL_HOST: smtp
1
2
3
4
5
6
#找到这里
services:
#注释下面这段
# smtp:
# restart: unless-stopped
# image: tianon/exim4

构建容器

此时我们可以就直接使用一键脚本安装了。但是如果内存太小,初始化可能会出问题,后文会提供解决方案。

1
bash install.sh

由于有大量操作,安装速度可能比较慢,需要耐心等待
如果没有提示创建管理员,需要通过docker-compose run --rm web createuser手动创建用户,这在内存不足的机器上特别常见。

修改环境变量

打开.env文件,添加以下内容:

1
2
3
SENTRY_EMAIL_HOST=  #邮箱smtp地址
SENTRY_EMAIL_PORT= #smtp端口,有tls就587
SENTRY_SINGLE_ORGANIZATION=0

安装成功之后,就可以运行docker-compose up -d启动sentry了。
如果启动后无法访问,请尝试使用docker-compose run --rm web upgrade重新初始化。

首次登录

浏览器打开http://IP:9000登录,之后会进入初始化页面(此处设定可以之后修改),主要是填写地址和smtp信息。

低配环境的坑

以下坑点基本上是因为内存不足造成的(参见:issue #4095),因此也可以通过创建大内存服务器然后把内存改小解决低配安装

无法首次登录/没有默认组织

首次登录后,如果提示创建新组织或报Internal project (id=1) does not exist错误,则是因为安装过程中未能创建Sentry收集自身错误的项目,此处应该手动创建:

1
docker-compose run --rm web shell

之后会进入python终端,执行以下代码

1
2
3
from sentry.models import Project
from sentry.receivers.core import create_default_projects
create_default_projects([Project])

上文中修改环境变量中增加SENTRY_SINGLE_ORGANIZATION=0一行(允许多个组织存在),也是防止因出现此类错误导致无法进入系统(默认组织没被创建,又不允许创建新的组织,自然报错)。

无法收集事件

此种情况下,执行docker-compose ps找到worker容器的名称,再执行docker logs -f --tail 100 sentry_worker_1查看日志,搜索对应方案。
如果错误是

1
ProgrammingError: ProgrammingError('function sentry_increment_project_counter(integer, integer) does not exist

则可用如下方法解决:

  1. 执行docker-compose ps找到postgres容器的名称,一般为onpremise_postgres_1或者sentry_postgres_1

  2. 进入数据库容器的bash:

    1
    docker exec -it sentry_postgres_1 bash
  3. 连接数据库:

    1
    psql -h 127.0.0.1 -d postgres -U postgres`
  4. 执行以下命令:

    1
    create or replace function sentry_increment_project_counter( project bigint, delta int) returns int as $$ declare new_val int; begin loop update sentry_projectcounter set value = value + delta where project_id = project returning value into new_val; if found then return new_val; end if; begin insert into sentry_projectcounter(project_id, value) values (project, delta) returning value into new_val; return new_val; exception when unique_violation then end; end loop; end $$ language plpgsql;
  5. Ctrl+D退出sql,exit退出shell,docker-compose down && docker-compose up -d重启

参见:Sentry官方论坛

其他配置

允许使用QQ邮箱

在sentry中添加和自行注册qq邮箱都会提示无效邮箱,原因是官方发现,qq.com 在saas版本中有很多滥用行为,所以直接硬编码拉黑了。
但如果是自行安装的,可以修改文件解决。

  1. 执行docker-compose ps找到web容器的名称,一般为onpremise_web_1或者sentry_web_1

  2. 进入数据库容器的bash:

    1
    docker exec -it sentry_web_1 bash
  3. 一键替换

    1
    sed -i "s/qq/aaaaaaaa/g" /usr/local/lib/python2.7/site-packages/sentry/conf/server.py

这样被禁用的就是aaaaaaaa.com了。
重建docker容器后会恢复原状,所以不是完美解决方案,但已注册的账号不受影响。
参见:issue #13541

数据清理

清理Web容器中的数据:
1
docker exec -it sentry_web_1 sentry cleanup --days 7

清理耗时很长。

清理sql中的数据残余

cleanup的使用delete命令删除postgresql数据,但postgrdsql对于delete, update等操作,只是将对应行标志为DEAD,并没有真正删除。

1
docker exec -it sentry_postgres_1 vacuumdb -U postgres -d postgres -v -f --analyze
计划任务
1
docker exec -it sentry_web_1 sentry cleanup --days 7  && docker exec -it sentry_postgres_1 vacuumdb -U postgres -d postgres -v -f --analyze

crontab中设置上面那行命令定期执行即可。