sentry异常上报和统计系统
# sentry上报和统计系统
# 总结
# 上报和分析维度
- 异常-exception,crash,anr
- 业务信息-msg,可用于业务异常趋势监控
- 性能-启动时间,网络,页面性能-大多数为自动采集,有开关控制
# 额外上报内容
- uid
- deviceId- 在Android上为AndroidId
- topPage-顶部页面名字, 以及当前栈里所有页面列表
- 设备信息
- 其他的各种自定义tag,额外的msg
# 服务端方案
- 使用sentry.io官网提供的后台服务-免费版本有流量限制,或者需要付费. 且国内无法直连,需要用fq
- 自己部署后台: 更加自由,但非常耗内存
# 客户端方案
Android,flutter各提供一套库,但api是统一的
aop切入日志工具,warn以上日志上报到sentry
提供过滤功能,过滤量大,无必要的上报.
# 官方后台使用
https://sentry.io
登录后会重定向到你自己的个人域名,比如: https://tommy-cat.sentry.io/
然后和私有化部署的完全一样的操作.
# 代理fq:
拷贝dsn测试时发现,sentry.io需要fq,所以需要nginx配置代理访问
dsn的配置为: 项目的key@用户id.ingest.sentry.io/项目id
其中项目key在实际请求中,会出现在请求头,而不是url中,所以代理无需关注这点.
可以配置http+ip的访问
如果需要https访问,则需要在dns服务商那配置域名,且nginx配置https证书.第一次会比较复杂,后面新增配置就比较简单.
# nginx配置:
server {
listen 443 ssl;
server_name sentryio.xxxx.top;
location / {
proxy_pass https://用户id.ingest.sentry.io/; # 转发规则
proxy_set_header Host '用户id.ingest.sentry.io';
proxy_set_header referrer '';
proxy_ssl_server_name off;
# proxy_ssl_name ingest.sentry.io;
proxy_ssl_protocols SSLv3 TLSv1.1 TLSv1.2 TLSv1.3;
proxy_ssl_verify off;
}
# gzip配置
gzip off;
gzip_buffers 32 4K;
gzip_comp_level 6;
gzip_min_length 100;
gzip_types application/json application/javascript text/css text/xml;
gzip_disable "MSIE [1-6]\."; #配置禁用gzip条件,支持正则。此处表示ie6及以下不启用gzip(因为ie低版本不支持)
gzip_vary on;
# ssl配置
ssl_certificate /etc/nginx/ssl/acme_cert.pem;
ssl_certificate_key /etc/nginx/ssl/acme_key.pem;
ssl_stapling on;
ssl_stapling_verify on;
ssl_reject_handshake off;
ssl_protocols TLSv1.2;
resolver 8.8.8.8 8.8.4.4 1.1.1.1 valid=60s;
resolver_timeout 2s;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# cloudflare dns配置:
然后,在客户端设置dns时,将https://key@用户id.ingest.sentry.io/项目id中间的"用户id.ingest.sentry.io"替换成你自己的三级或四级域名 即可
# 开源服务端部署
不是使用docker hub上镜像,而是根据这个:
https://develop.sentry.dev/self-hosted/
要求:
docker-compose版本在1.28.0以上
空闲内存在4G以上,实际占用内存约10G
# centos 内置docker-compose版本太低,需要卸载重装:
[root@localhost self-hosted-23.5.2]# yum remove docker-compose
已加载插件:fastestmirror
正在解决依赖关系
--> 正在检查事务
---> 软件包 docker-compose.noarch.0.1.18.0-4.el7 将被 删除
--> 解决依赖关系完成
2
3
4
5
6
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-Linux-x86_64" -o /usr/local/bin/docker-compose && sudo chmod +x /usr/local/bin/docker-compose
无法下载的话,手动下载包,并放到/usr/bin/目录下
docker-compose --version
docker-compose version 1.29.2, build 5becea4c
2
# 下载sentry最新包,并解压
https://github.com/getsentry/self-hosted/releases
cd到目录下,运行:
./install.sh
有错误就解决错误,直到没有错误
常见错误: 包里很多.sh文件没有执行权限,要一个个去chmod +x xxx/yyy.sh
如果成功,命令行会让你创建账户和密码.
然后运行: 启动sentry
docker-compose up -d
# sentry flutter文档
https://docs.sentry.io/platforms/flutter/
https://docs.sentry.io/platforms/dart/configuration/integrations/dio/
https://github.com/skyNet2017/sentry-dart/tree/main/dio
http://39.101.221.145:9000/sentry/mychatai-java/getting-started/java/
# 客户端-Android
# 初始化
不进行代码的显式初始化,全部由manifest来初始化:
https://docs.sentry.io/platforms/android/configuration/options/
因为sentryProvider的自动初始化会校验是否配置dsn,未配置时会崩溃,因此在封装库里声明:
<application>
<meta-data android:name="io.sentry.dsn" android:value="" />
</application>
2
3
在实际的工程里声明:
<meta-data tools:replace="android:value" android:name="io.sentry.dsn" android:value="https://xxxx@yyyy.ingest.sentry.io/67777" />
其他配置项参考https://docs.sentry.io/platforms/android/configuration/options/
# api调用:
# aop切入日志工具:
@Aspect
public class AspectLogUtils {
/**
* log(final int type, final String tag, final Object... contents)
* @param joinPoint
* @return
* @throws Throwable
*/
@Before("execution(* com.blankj.utilcode.util.LogUtils.log(..))")
public void weaveJoinPoint(JoinPoint joinPoint) throws Throwable {
int type = (int) joinPoint.getArgs()[0];
if(type < LogUtils.W){
return;
}
Object[] objects= (Object[]) joinPoint.getArgs()[2];
if(objects == null || objects.length ==0){
return;
}
SentryUtil.Builder builder = SentryUtil.create();
boolean hasThrowable = false;
int count = 0;
for (Object object : objects) {
if(object instanceof Throwable){
hasThrowable = true;
Throwable throwable = (Throwable) object;
builder.exception(throwable);
}else {
count++;
builder.addExtra("extra"+count,object+"");
}
}
String typeStr = "warn";
if(type == LogUtils.E){
typeStr = "error";
}else if(type == LogUtils.A){
typeStr = "assert";
}else {
typeStr = type+"";
}
builder.addTag("logLevel",typeStr);
if(hasThrowable){
// builder.addExtra("extraMsg",joinPoint.getArgs()[0]+"");
}else {
builder.msg(objects[0]+"");
}
String tag = joinPoint.getArgs()[1]+"";
if(!tag.equals("") && !"null".equals(tag)){
builder.addTag("extraTag",joinPoint.getArgs()[1]+"");
}
builder.doReport();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# 客户端-flutter
https://pub.dev/packages/sentry_dio4 兼容dio4的版本