官网及文档
https://docs.sentry.io/guides/
安装教程
https://github.com/getsentry/self-hosted/tree/cd13427aa9a231b2b27c9fd14017d183cca52c1e
Sentry 是一款开源的应用监控产品,使用 Python、JavaScript、HTML、CSS 打造。在 GitHub 上有 29k Stars,是应用监控领域 Stars 数排行最高的开源项目,其官网宣称有 1 百万名开发者和 7 万个组织在使用 Sentry。除了提供开源产品外,其幕后的公司也提供付费的 SaaS 服务:sentry.io。2021 年该公司宣布获得了 6000 万美元的 D 轮融资,该轮融资使 Sentry 的总资金达到 1.27 亿美元,融资后估值为 10 亿美元。确实是一款值得关注的产品。
Sentry 原理图
概念
Event: 事件。
每次产生的日志记录,每个event有很多元信息,包括事件级别,项目信息,环境等。可通过点击具体事件对应的“JSON”数据进行查看
Issue:问题。
相同的地方产生的一个异常称为一个Issue(是同一类问题的聚合)。假如在同一个位置发生了两次报错,那么会产生两个Event事件,但是只有一个Issue。
DSN:客户端(具体项目)密钥。
DSN是一个url,包含相关密钥信息,客户端与服务端(sentry服务器)就是通过这个DSN进行通信,上报错误信息的。
Auth Token:授权令牌。
授权令牌允许基于你的账户使用Sentry API,我们主要用到使用@sentry/cli进行上传sourceMap文件等操作时,sentry/cli会基于Auth Token进行调用相应API方法。
Org:组织名称。
对应公司部署的sentry服务器上的组织名称。
Release:版本号。
Project:客户端名称。(接入sentry的具体项目名)
Tag:标签。
本地搭建sentry服务
Sentry服务依赖比较多,官方推荐使用docker方式进行部署
硬件要求
安装python3.9
这里建议还是下载3.9的,因为笔者在第一次安装的时候是3.6.5版本的,但是报错如下
明显3.6对应的pip安装出现一些问题,这里还是更新高一些的版本。
1、下载python3.9安装包
a、下载:
cd /usr/download
wget https://www.python.org/ftp/python/3.9.0/Python-3.9.0.tgz
b、解压文件:
tar -xvf Python-3.9.0.tgz
2、移除旧版本
a、 删除旧版本的软链接
rm -rf ./python3
rm -rf ./pip3
b、清空旧版本的存放内容
rm -rf /usr/local/python3/*
3、执行安装
a、编译文件,运行脚本configure
configure是一个shell脚本,根据平台的特性生成Makefile文件,为下一步的编译做准备。可以通过在 configure 后加上参数来对安装进行控制,比如下面就是指定安装目录/usr/local/python3。如果没有用这个选项,安装过程结束后,该软件所需的软件被复制到不同的系统目录下,比较混乱。编译文件 时间大概有1-3分钟
cd Python-3.9.0
sudo ./configure --prefix=/usr/local/python3
如果前面没有移除就版本,安装完会提示 ./configure --enable-optimizations,但是建议不要执行。有可能会出错。直接安装即可。如果执行后报错,只能重新清楚编译文件make distclean,然后再重新执行一遍编译安装。
b、make编译&make install安装
sudo make && sudo make altinstall
执行命令:
// export PATH=${PATH}:/usr/bin/python3
注意: 正常情况这里需要将黄色警告部分提示的路径复制添加在 export PATH= 后面的,(我的是 /usr/local/python3/bin/,但是为什么写/usr/bin/python3,因为后面要创建一个软连接,先跳过这一步).
source /etc/profile
4、创建软链接
cd /usr/local/python3/bin/
ls
注意下面的命令是python3.9和pip3.9,一不小心写错了就
sudo ln -s /usr/local/python3/bin/python3.9 /usr/bin/python3
sudo ln -s /usr/local/python3/bin/pip3.9 /usr/bin/pip3
如果提示存在,则先sudo rm -rf 文件然后再创建软连接。
export PATH=${PATH}:/usr/bin/python3
5、检查版本
python3 -V
-bash: python3: command not found
alias python3='/usr/bin/python3'
如果执行过下面的添加之后还是报错没有文件,检查第4点软链接是否设置错误
export PATH=${PATH}:/usr/bin/python3
pip3 -V
如果没有安装,执行下面命令
sudo yum update
sudo yum install python3-pip
ll /usr/bin/python*
安装docker
卸载旧的docker
# 停止 docker 服务
systemctl stop docker
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
其他方式移除
sudo apt-get remove docker-compose
sudo rm /usr/local/bin/docker-compose
pip3 uninstall docker-compose
建立仓库
sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
安装docker engine
sudo yum install docker-ce docker-ce-cli containerd.io
启动docker
# 在容量最大的目录下创建文件夹
mkdir -p /data/var/lib/
# 将 docker 的默认数据复制到新路径下,删除旧数据并创建软连接,即使得存储实际占用磁盘为新路径
/bin/cp -a /var/lib/docker /data/var/lib/docker && rm -rf /var/lib/docker && ln -s /data/var/lib/docker /var/lib/docker
sudo systemctl start docker
测试hello-world
sudo docker run hello-world
设置开机自启动
systemctl enable docker
通过修改daemon配置文件/etc/docker/daemon.json来使用加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://djqpokpz.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
测试配置是否成功
docker search nginx
查看版本信息
docker info
或者
docker -v
docker system df 命令,类似于 Linux上的 df 命令,用于查看 Docker 的磁盘使用情况:
TYPE列出了 Docker 使用磁盘的 4 种类型:
Images :所有镜像占用的空间,包括拉取下来的镜像,和本地构建的。
Containers :运行的容器占用的空间,表示每个容器的读写层的空间。
Local Volumes :容器挂载本地数据卷的空间。
Build Cache :镜像构建过程中产生的缓存空间(只有在使用 BuildKit 时才有,Docker 18.09 以后可用)。
最后的 RECLAIMABLE 是可回收大小
容器清理
docker container prune : 仅删除停止运行的容器。
docker rm -f (docker container ls -aq) : 同上。
镜像清理
docker rmi <image id> :通过镜像的id来删除指定镜像。
有一些镜像是隐形的:
子镜像,就是被其他镜像引用的中间镜像,不能被删除。
悬挂状态的镜像,就是不会再被使用的镜像,可以被删除。
其他命令:
docker image ls -f dangling=true : 可以列出所有悬挂状态的镜像
并使用命令 docker image rm (docker image ls -q) :删除所有镜像。但正在被容器使用的镜像无法删除。
数据卷清理
docker volume rm $(docker volume ls -q) :删除不再使用的数据卷。
docker volume prune :同上。
缓存清理
Docker 18.09 引入了 BuildKit ,提升了构建过程的性能、安全、存储管理等能力。
docker builder prune :删除 build cache。
docker system prune : 可以用于清理磁盘,删除关闭的容器、无用的数据卷和网络,以及 dangling 镜像(即无 tag 的镜像)。
docker system prune -a : 清理得更加彻底,可以将没有容器使用 Docker镜像都删掉。
注意,这两个命令会把你暂时关闭的容器,以及暂时没有用到的 Docker 镜像都删掉了。
安装 docker-compose
指定版本1.29.2
sudo curl -L https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
安装最新版本
compose_version=$(curl https://api.github.com/repos/docker/compose/releases/latest | jq .name -r)
output='/usr/local/bin/docker-compose'
curl -L https://github.com/docker/compose/releases/download/$compose_version/docker-compose-$(uname -s)-$(uname -m) -o $output
chmod +x $output
echo $(docker-compose --version)
查看docker-compose 版本
docker-compose version
安装redis
linux 服务器出现redis exceptions ConnectionError Error 113 connecting to 你的ip No route to host
运行命令 sudo iptables -F
下载Sentry仓库
yum install -y git
git clone https://github.com/getsentry/onpremise.git
cd onpremise
ls
最新版本的
git clone https://github.com/getsentry/self-hosted.git --depth=1
fatal: unable to access 'https://github.com/getsentry/self-hosted.git/': Encountered end of file
yum update nss curl git -y
git pull --unshallow #或者 git fetch --unshallow
切换需要安装的分支,这里必须切换分支,因为master分支上有很多无用的容器,启动的时候会报错
git checkout 21.12.0
文件结构与作用
要对部署和运行进行修改的话,需要找到对应的配置文件,先看下 onpremise 部署实现的主要文件结构和作用:
clickhouse/config.xml:clickhouse 配置文件
cron/:定时任务的镜像构建配置和启动脚本
nginx/nginx.conf:nginx 配置
relay/config.example.yml:relay 服务配置文件
sentry/:sentry-onpremise-local 镜像的构建和基于此镜像启动的主服务的配置都在这个文件夹下
Dockerfile:sentry-onpremise-local 的镜像构建配置,会以此启动很多服务
requirements.example.txt:由此生成 requirements.txt,需要额外安装的 Django 插件需要被写在这里面
.dockerignore:Docker 的忽略配置,初始忽略了 requirements.txt 之外的所有文件,如果构建新镜像时需要 COPY 新东西则需要修改此文件
config.example.yml:由此生成 config.yml,一般放运行时不能通过管理后台修改的配置
sentry.conf.example.py:由此生成 sentry.conf.py,为 python 代码,覆盖或合并至 sentry 服务中,从而影响 sentry 运行。
.env:镜像版本、数据保留天数、端口等配置
docker-compose.yml:Compose 工具配置,多 docker 的批量配置和启动设置
install.sh:Sentry 一键部署流程脚本
同时需要注意的是,一旦部署过之后,install.sh 脚本就会根据 xx.example.xx 生成实际生效的文件,而且,再次执行 install.sh 脚本时会检测这些文件存不存在,存在则不会再次生成,所以需要修改配置后重新部署的情况下,我们最好将生成的文件删除,在 xx.example.xx 文件中修改配置。
根据服务组成和运行机制得知,主服务是基于 sentry-onpremise-local 镜像启动的,而 sentry-onpremise-local 镜像中的 sentry 配置会合并 sentry.conf.py,此文件又是由 sentry.conf.example.py 生成,所以后续定制化服务时,会重点修改 sentry.conf.example.py 配置模板文件。
直接 ./install.sh执行安装,可是各种错误,并没有像网上教程那样顺利安装。比如postgres的错误。其实由于服务器是新配置的,很多基础配置都没有,这里需要先安装对应的依赖。
1、docker volume create --name=sentry-data && docker volume create --name=sentry-postgres
- Make our local database and sentry volumes Docker volumes have to be created manually, as they are declared as external to be more durable.
2、 cp -n .env .env.custom
- create env config file
3、docker-compose build
- Build and tag the Docker services
4、docker-compose run --rm web config generate-secret-key
- Generate a secret key. Add it to .env as SENTRY_SECRET_KEY.
5、docker-compose run --rm web upgrade
- Build the database. Use the interactive prompts to create a user account.
6、docker-compose up -d
- Lift all services (detached/background mode).
Access your instance at localhost:9000!
如果需要通过服务器ip访问,则需要将服务器防火墙开放该端口的访问权限,这里注意一点如果是腾讯云,通过宝塔面板放行的端口并没有真正生效,还需要服务器上再开放一下
If you're upgrading from < 21.12.0 then be sure to stop your old containers with this command before installing:
COMPOSE_PROJECT_NAME=sentry-self-hosted docker-compose down --rmi local --remove-orphans
Without this you may run into errors about snuba-api
being unhealthy. This is because of we finished renaming from onpremise
to self-hosted
in 21.12.0 including the project name. We put the above code under install.sh
in #1384, but it didn't make it into 22.3.0, sorry. <g-emoji class="g-emoji" alias="confused" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f615.png" style="box-sizing: border-box; display: inline-block; min-width: 1ch; font-family: "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; font-size: 1.25em; font-weight: 400; line-height: 1; vertical-align: -0.075em; font-style: normal !important;">😕</g-emoji> It will be in 22.4.0.
还是不行
for id in id; done
./install.sh --skip-commit-check
docker-compose --env-file /usr/local/self-hosted/.env.custom up -d
运行部署脚本:
cd onpremise
./install.sh
#安装指定版本
SENTRY_IMAGE=getsentry/sentry:21.12.0 ./install.sh
中间会要求输入初始管理员邮箱账号密码,输入y
启动服务
最后出现You're all done,并让你输入docker-compose up -d启动服务
记得需要在onpremise 目录底下运行
docker-compose up -d
安装过程并没有那么顺利,各种问题,比如下面,主要是网络不稳定造成的,重新执行一次即可解决。
然后又报了下面的错误,明显是端口地址被占用,需要更改配置
修改端口映射
查看端口 必须用sudo
sudo netstat -pna | grep 9000
查看是什么程序占用端口
如果知道php-fpm这个进程没用,直接kill掉前面的id即可,比如7992
sudo kill 7992
再次重启
docker start 41xxxxxxxad0 #前提是知道容器id
或者
docker-compose up -d
明显笔者这个是不能关闭的,因此需要修改配置端口了。
sudo vi sentry/sentry.config.py
SENTRY_WEB_PORT = 9090
主要更改.env文件,这里需要注意的是.开头的是隐藏文件,ls需要增加-a显示所有文件
ls -a
vi编辑文件,按 i 进入编辑模式
vi .env
SENTRY_EVENT_RETENTION_DAYS 将90更改未15,表示保存15天事件数据,视自己情况而定
SENTRY_BIND 将9000改为9090
HEALTHCHECK_INTERVAL=30s
HEALTHCHECK_TIMEOUT=60s
HEALTHCHECK_RETRIES=5
编辑config
sudo vi /sentry/config.yml
sudo vi nginx/nginx.conf
sudo vi relay/config.yml
docker-compose logs -f
...
Got errors as above: error trying to connect: dns error: no record found for name: web. type: AAAA
docker-compose restart relay
docker-compose logs -f
如果使用到kafka集群,可以在文件最后可添加 “限制 Kafka 磁盘使用量” 的配置,新版 Sentry 使用的 Kafka 会大量的写入日志信息,特别容易导致磁盘跑满,具体限制额度根据自己的磁盘情况而定。具体可常见 Sentry disk cleanup [kafka]
KAFKA_LOG_RETENTION_HOURS=24
KAFKA_LOG_RETENTION_BYTES=53687091200
KAFKA_LOG_SEGMENT_BYTES=1073741824
KAFKA_LOG_RETENTION_CHECK_INTERVAL_MS=300000
KAFKA_LOG_SEGMENT_DELETE_DELAY_MS=60000
编辑完成后,按 esc 退出编辑模式,然后按 shift + : 输入 wq 后回车。如果没有编辑可输入 q 或 q! 退出。
再次执行
sudo docker-compose down
sudo docker-compose build
sudo docker-compose up -d
检查安装镜像
全部是done,没有错误产生,执行检查镜像命令,查看env指定的镜像都有了。
docker images
查看Sentry 启动服务容器
通过 docker ps 命令,我们可以查看 Sentry 容器 服务状态信息
创建项目的superuser
Web 服务
docker-compose run --rm web upgrade
修改Sentry配置
进入sentry文件夹,可以发现有config.yml和sentry.conf.py
cd sentry/
ls
vi config.yml
部署Sentry,以后如果添加新的插件支持或者修改参数都得重新build
docker-compose build --pull # Build the services again after updating, and make sure we're up to date on patch version
docker-compose run --rm web upgrade # Run new migrations
docker-compose up -d # Recreate the services
启动后docker-compose ps看到的结果
首先我们修改一下映射端口。因为默认绑定端口是9000,因为我这台电脑启动了php-fpm服务绑定了9000端口,所以我这里需要将9000改成10000。具体相关配置如下:
docker-compose.yml
web:
<<: *defaults
ports:
- '9090:9000' # 修改位置
grep -rn '9000' ./
修改完Sentry配置,重启服务
sudo docker-compose restart web worker cron sentry-cleanup
重启所有所有服务
sudo docker-compose restart
本地简单测试
curl 127.0.0.1:9090
使用netstat命令查询端口状态:
netstat -ntlp | grep 9090
sudo lsof -i -P -n | grep LISTEN
Sentry 的邮件配置
安装邮箱 ssl 钉钉等插件
默认情况下,在Sentry控制台的插件列表里是没有钉钉的,使用钉钉需要先安装这个插件,编辑目录下的 requirements.txt 文件
# Add plugins here
django-smtp-ssl==1.0
redis-py-cluster==2.1.0
sentry-gitlab
修改邮箱配置
Sentry 支持邮件发送的功能很是重要,当 Sentry 捕获事件以后,能够将此捕获的事件发送到你的我的邮箱(针对 Sentry 管理员帐号)。要修改目前的邮件配置是不能在界面上操做的,须要进行如下步骤:
修改 sentry/config.yml
###############
# Mail Server #
###############
# mail.backend: 'smtp' # Use dummy if you want to disable email entirely
mail.host: 'smtp.qq.com'
mail.port: 587
mail.username: '894266648@qq.com'
mail.password: '换成你的授权码'
mail.use-tls: true
# The email address to send on behalf of
mail.from: '894266648@qq.com'
上面记得更改mail.from,之前这里没改,默认的是sentry@localhost,下面发送邮件就报错了。
解决sentry禁用qq邮箱的问题
查看docker容器id
docker ps
进入web容器
docker exec -it 68f013b00894 bash
修改配置文件
vi /usr/local/lib/python3.9/site-packages/sentry/conf/server.py
注意有的是Python3.8 查看/usr/local/lib/ 底下即可知道
vi /usr/local/lib/python3.8/site-packages/sentry/conf/server.py
如果没有vi编辑器,去安装一个:
apt-get update
apt-get install vim -y
定位到1570行,vi编辑器使用 :1570
# block domains which are generally used by spammers -- keep this configurable in case an onpremise
# install wants to allow it
INVALID_EMAIL_ADDRESS_PATTERN = re.compile(r'\@qq\.com$', re.I)
https://github.com/getsentry/sentry/issues/13541
注意有的是Python3.8 并且源码不一定在1570,不同版本不一样,最新版本在2195,代码80%多位置
直接注释掉即可,如果container 重新创建之后,就会被覆盖
或者换成 INVALID_EMAIL_ADDRESS_PATTERN = re.compile(r'@xxxxxx.com$', re.I)
于是顺便提交了一个合并
https://github.com/getsentry/sentry/pull/32982/commits/6f29e6a5d65b7cf02e9b791cd0913c8ded506d01
输入“exit”或者按键“Ctrl + C”退出container
iptables failed: iptables --wait -t nat -I DOCKER
重新启动Docker sudo systemctl restart docker
修改 docker-compose.yml ,注释掉 SENTRY_EMAIL_HOST 配置,由于这个配置默认为 smtp ,会致使 .env 文件中的相同配置失效。
docker-compose down
docker-compose run --rm web upgrade
docker-compose up -d
重启后查看web端网页在左上角头像菜单下出现管理选项,进入email中可以发送测试邮件,验证是否配置正确。
保存后执行docker-compose build会下载安装插件。然后重新启动docker服务。
访问WEB端网页项目下的legacy integrations,可以看到钉钉的插件选项了
开启插件后,在钉钉的群组里创建自定义机器人,会生成一个带token的url,将其填写进项目设置里的dingtalk robot url中。保存后项目中产生BUG就会在钉钉群组收到通知。
避免 Sentry 引发雪崩
引入新的技术或者工具,或多或少都会增加系统的复杂度和运行风险。
我们之前出过一次严重问题:某个日均三千万接口请求量的服务发生故障,大量的错误信息涌向 Sentry 服务器,导致 Sentry 响应严重延迟,其 Redis 队列内存容量接近占满,而 Nginx 也全都响应 504 Gateway Timeout。恰好该故障的服务由于请求 Sentry 服务端未设置超时时间,导致 HTTP 请求同步阻塞,反倒拖垮了服务本身。
为了规避此类问题,有以下做法:
保障 Sentry 服务端高可用
这点最重要,但实际我们并未做好。目前我们自部署的 Sentry 是一个单点,并没有集群或冗余。如果要实现高可用,那么付出的金钱成本会较高,甚至可能超过了使用 Sentry SaaS 付费服务的成本。由于 Sentry 官方并未提供中国区的服务,HTTP 请求到国外的速度并不理想,使用官方 SaaS 服务也不见得是太好的选择。
设置 timeout
使用 Sentry SDK 时,一定要设置向 Sentry 服务器发送请求的超时时间,建议 3 秒以下。
设置 sample_rate
使用 Sentry SDK 时,可以设置采样率,0.00 表示拒绝发送任何事件,1.00 表示发送全部事件。建议前期设置较小的值,然后视应用的 PV 大小进行调整。使用采样率可能会带来这样的负面影响:零星的错误可能未上报,导致一直未被发现。
及时熔断
假如当 Sentry 服务器不堪重负时,应该避免应用继续请求 Sentry 了。比如:可以手动将采样率设置为 0.00。
使用异步方式(async)发送请求
如果 SDK 支持异步发送请求,那就使用,避免同步阻塞。
隔离生产环境的 Sentry
运维同事隔离部署了两套 Sentry,一套是体验环境,供开发环境/测试环境/预发布环境的应用接入使用;另外一套是正式环境,供生产环境/私有化环境的应用接入使用。如果要试验 Sentry 的功能或调整 Sentry 的配置,那我们会先在体验环境的 Sentry 中进行,确认没有问题后,才会调整生产环境的 Sentry,借此保障生产环境 Sentry 的稳定性。
通过队列来缓冲请求至 Sentry 的并发压力
假设应用的请求量和并发量都巨大,当出现严重故障时每个请求处理都发生错误,那么即使在 SDK 中设置了较低的采样率(比如:0.01),可能请求到 Sentry 的并发量依旧超过其有限承载。为了避免这个问题,我们在流量最大的服务中做了如下尝试:我们增加了一个队列,将服务的错误事件先入列,启动了少量的消费进程去消费该队列缓缓上报错误至 Sentry 服务端。并且应用程序中做了处理,即使该队列容量占满也不会影响正常业务(只是丢弃错误事件)。实践证明,这种中转缓冲的方式非常有效,不过也增加了接入 Sentry 工作量,大家可自行取舍。