Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

procstat监控JVM无法屏蔽掉pid标签,会导致数据图不连续 #1108

Open
rollingsunn opened this issue Dec 12, 2024 · 16 comments
Open

Comments

@rollingsunn
Copy link

rollingsunn commented Dec 12, 2024

Relevant config.toml

配置如下:
 [[instances]]
 search_cmdline_substring = "baili.jar"
 gather_total = true
 gather_per_pid = false
 gather_more_metrics = [
     "threads",
     "fd",
     "io",
     "uptime",
     "cpu",
     "mem",
     "limit",
     "jvm"
 ]
发现的问题:
gather_per_pid = false 对cpu、mem等指标,都是有效的。
但是: 对jvm gc指标无效. 无法屏蔽pid标签。 

另外,categraf 是通过 jstat -gc 来抓取jvm GC信息,指标少,主要是不直观。
能够改为(或者增加) jstat -gcutil  抓取jvm GC信息 ?  
这个是按比例显示jvm内存使用,都比较友好/易用。 

最后,辛苦&谢谢n9e的大佬们 :)

Logs from categraf

./categraf  --version
v0.3.82-d0633717eafc21d8e303f7435454eec7ea6aae9f

System info

v0.3.82-d0633717eafc21d8e303f7435454eec7ea6aae9f

Docker

No response

Steps to reproduce

procstat_jvm_GCT agent_hostname=bjf-baili-web00.bjf.wande.com pid=24823 search_string=baili.jar 1.447

Expected behavior

  1. 干掉 pid 标签;
  2. 改为(或者增加) jstat -gcutil ;

Actual behavior

/usr/local/categraf/categraf --test --inputs procstat | grep baili.jar

Additional info

附上截图
121212121212121212121212

No response

@zzmark
Copy link
Contributor

zzmark commented Dec 12, 2024

  1. pid问题稍后我去核实
  2. 替换为gcutil不合理。理由:采集插件更倾向于原始信息,gcutil缺少具体数值,无法应对分代容量变更的情况,无法应对整个堆容量变更的情况,而util提供的百分比,只要简单做个除法就可以得到。

也有个疑问,为啥存在pid会造成数据图不连续,难不成没有指定label格式,将所有线都展示出来了?

@kongfei605
Copy link
Collaborator

jstat -gc $PID , 可以考虑下,如果有多个java进程,是否需要区分pid ?

@zzmark
Copy link
Contributor

zzmark commented Dec 13, 2024

procstat 各个指标都是两种计算:

  1. gather_per_pid=True,按进程拆分
  2. gather_total=True ,各个进程的汇总值

而jvm没遵循这个规则,只返回了按进程拆分,可以考虑调整。

到目前为止没有人爆出此问题,我这里也有大范围使用procstat,也没有遇到需要将某个服务多个jvm进程的数值加起来看的需求。个人经验上,这功能,做了也不该有人用到才对。

顺带一提,你这两个诉求有冲突性。
gcutil 拿到的只有百分比,这种数值是没法做累加的。

@rollingsunn
Copy link
Author

  1. pid问题稍后我去核实
  2. 替换为gcutil不合理。理由:采集插件更倾向于原始信息,gcutil缺少具体数值,无法应对分代容量变更的情况,无法应对整个堆容量变更的情况,而util提供的百分比,只要简单做个除法就可以得到。

也有个疑问,为啥存在pid会造成数据图不连续,难不成没有指定label格式,将所有线都展示出来了?

我没有单独设置label(偷懒),categraf 抓到的 metric:
procstat_jvm_MC agent_hostname=bjg-baili-web01.bjg.wande.com pid=1921 search_string=baili.jar 231640.0

就靠里面的 search_string=baili.jar 做区分。
然后出图做了模版,用了这种PromQL:
procstat_jvm_S0U{search_string="$java_app"} / procstat_jvm_S0C{search_string="$java_app"} * 100

我是新手,在学习,我理解, 如果 tag 有变更(重启java导致pid发生变化)就是新的一条指标,所以dashboard就不连续了,曲线凌乱。 ~ 捂脸 ~

@rollingsunn
Copy link
Author

procstat 各个指标都是两种计算:

  1. gather_per_pid=True,按进程拆分
  2. gather_total=True ,各个进程的汇总值

而jvm没遵循这个规则,只返回了按进程拆分,可以考虑调整。

到目前为止没有人爆出此问题,我这里也有大范围使用procstat,也没有遇到需要将某个服务多个jvm进程的数值加起来看的需求。个人经验上,这功能,做了也不该有人用到才对。

顺带一提,你这两个诉求有冲突性。 gcutil 拿到的只有百分比,这种数值是没法做累加的。

可能我没表达好:

  1. 不是要求把多个jvm进程数值加起来, gather_total=True 我理解以为是把多线程的值汇总到进程。
  2. -gcutil 会比 -gc 更易于阅读,结果大部分都是百分比,数值确实不够原始,但是 研发习惯。
    用公式去做除法,其实确实比较科学, 既有原始数据,又有计算后的百分比,例如:
    procstat_jvm_S0U{search_string="$java_app"} / procstat_jvm_S0C{search_string="$java_app"} * 100
    但是就是被 pid 那个导致图像不连续,新的pid曲线是别的颜色,搞的凌乱了~

@rollingsunn
Copy link
Author

jstat -gc $PID , 可以考虑下,如果有多个java进程,是否需要区分pid ?

我理解,jstat抓的数据,是按照 search_string=“xxx.jar” 区分进程,就不用pid了。
(或者换句话,pid是一个没有意义的tag,因为,频繁变化,我这么理解对吧~ )

@zzmark
Copy link
Contributor

zzmark commented Dec 13, 2024

@rollingsunn

对于 gather_total 理解不对,这个就是按条件筛选出一批进程,将指标汇总,基本是求和。uptime是最大值,jvm没有支持。

categraf属于exporter,它是负责抽取数据的,可以说不需要遵循任何部门的习惯。

终端用户的使用习惯,要用dashboard适配。
所以,至少我不会考虑额外摄取百分比来浪费存储(虽然,cpu和load是有这个的)。

其实你遇到的不连续问题,大概率是看板配置的时候,如何确定某批数据属于一条line,做歪了。
grafana、n9e的习惯是,Legend自己做表达式,给你展示下我们的玩法:

[[instances]]
search_cmdline_regexp = "loader.jar"
gather_total = false
gather_per_pid = true
gather_more_metrics = [
    "threads",
    "fd",
    "io",
    "uptime",
    "cpu",
    "mem",
    "limit",
    "jvm"
]
labels_from_cmdline_reggroup = "--appname=(?P<appName>\\w*).*--serverId=(?P<serverId>\\d*)"

然后看板配置参数:

appName: label_values(procstat_info,appName)
serverId: label_values(procstat_info,serverId)

看板表达式,拿eden区堆使用率举例:
procstat_jvm_EU{appName="$appName", serverId=~"$serverId"} / procstat_jvm_EC{appName="$appName", serverId="$serverId"}
细节:serverId 是模糊匹配,用来支持多选。

Legend: {{ serverId }}
这样实现:每个进程一个服,看板上对应一条线

@zzmark
Copy link
Contributor

zzmark commented Dec 13, 2024

而且,稍微多一些的话,这种总览,是一点用没有的。
除了能让浏览器卡死,多吃点数据库资源,实际是没眼看的。

后边必然是针对功能做通用看板,针对业务拼出基础指标看板

@rollingsunn
Copy link
Author

而且,稍微多一些的话,这种总览,是一点用没有的。 除了能让浏览器卡死,多吃点数据库资源,实际是没眼看的。

后边必然是针对功能做通用看板,针对业务拼出基础指标看板

好的 ,谢谢大佬, 学习你们的正规玩法,我这个玩法比较小学生了。

@kongfei605
Copy link
Collaborator

jstat -gc $PID , 可以考虑下,如果有多个java进程,是否需要区分pid ?

我理解,jstat抓的数据,是按照 search_string=“xxx.jar” 区分进程,就不用pid了。 (或者换句话,pid是一个没有意义的tag,因为,频繁变化,我这么理解对吧~ )

pid 变化确实是不稳定标签,我想问的是,如果包含xxx.jar 对应是多个进程的场景,这种场景去掉pid 后,会有数值覆盖的情况

@rollingsunn
Copy link
Author

jstat -gc $PID , 可以考虑下,如果有多个java进程,是否需要区分pid ?

我理解,jstat抓的数据,是按照 search_string=“xxx.jar” 区分进程,就不用pid了。 (或者换句话,pid是一个没有意义的tag,因为,频繁变化,我这么理解对吧~ )

pid 变化确实是不稳定标签,我想问的是,如果包含xxx.jar 对应是多个进程的场景,这种场景去掉pid 后,会有数值覆盖的情况

大佬,我理解:如果同一个jar, 要启动多个进程, 那应该是 通过其他启动参数来区分。

反正,我被 pid 变化搞的:
每次重启jar之后 , GC指标趋势图,曲线变颜色了。 然后 Legend(主机名ident) 也增加了一倍。捂脸~

我已经参考楼上 zzmark 大佬的玩法, 但是似乎不解决我的问题。
我也试着使用 PromQL 的 without 给 pid 干掉是啥效果。但是没有用到 聚合参数,用不上 without ...

image

procstat_jvm_MU{jarName="$jarName",envName="$envName"} / procstat_jvm_MC{jarName="$jarName",envName="$envName"} * 100

[[instances]]
search_cmdline_substring = "baili.jar"
gather_total = false
gather_per_pid = true
gather_more_metrics = [
"threads",
"fd",
"io",
"uptime",
"cpu",
"mem",
"limit",
"jvm"
]
labels_from_cmdline_reggroup = "java -jar.bin/(?P.\.jar).--spring.profiles.active=(?P\w)"

@kongfei605
Copy link
Collaborator

比如,search string用了 kafka, 那这个台机器上的kafka和 连kafka的client都可能被搜到。
我们可以做一个优化,如果查到的是多个进程,就附加上pid ,如果查到只有一个进程,就不附加pid 。这种设定对于java的场景是否合理?

@rollingsunn
Copy link
Author

rollingsunn commented Dec 20, 2024

比如,search string用了 kafka, 那这个台机器上的kafka和 连kafka的client都可能被搜到。 我们可以做一个优化,如果查到的是多个进程,就附加上pid ,如果查到只有一个进程,就不附加pid 。这种设定对于java的场景是否合理?

让大佬费心了,我就说说我的想法:

这样的Kafka用户特例,或者其他用户的奇葩特例场景, 都需要:
用户自己想办法解决,平台工具无法做到 100% 满意。真的是众口难调。

用户可以通过不同的启动参数cmdline,或者部署方式( 避免 Client 和Server在同一台机器~) 来解决。
(另外Kafka有插件去抓取,通过 procstat 去抓取kafka进程,我理解,这是非主流的,姿势不对,非最佳实践)

就像楼上 zzmark 大佬说的, categraf 已经提供了 jstat -gc 来抓取,是科学的/符合 工具平台的做法。
但有的用户,习惯用 jstat -gcutil 抓取,那就需要自己理解&适应,捂脸~

我是Prometheus的初学者,我理解:
jvm_gc_name{tag_1=xx, label_2=yy, pid=123 }
jvm_gc_name{tag_1=xx, label_2=yy, pid=456 }
这变成了不同的数据。(除非有的情况,使用 聚合函数,可以使用 by、without 处理 label )

单单就 jstat 抓 GC信息来说,计算很简单,就是计算一个百分比。
无法使用聚合函数 去处理label了。

所以:重启进程pid变化, 导致:趋势图线条新增了一批、旧的逐渐成为历史脏数据,展板趋势图很不友好。
不符合绝大多数用户的需求预期。

我的结论是:
pid 这个标签,真的是没啥卵用,只能添乱。不符合绝大多数用户的需求预期。
如果真的有人使用pid,那pid变化,难道需要天天去修改对应的一堆 PromQL 吗, 捂脸~

结论:
我们就给 pid 干掉, 就完事了。简单有效。
其他的存在多个进程的部署方式, 用户自己可以想办法解决,并且也不难。

kongfei 大佬,你看我的理解对不对 :)

@kongfei605
Copy link
Collaborator

完全去掉对于实现最简单。但是对于配置出来多个pid,不同进程的数据搞到一起更不科学。 所以现在就是如果你的进程数大于1 ,就附加pid,只有一个进程,就不附加pid了。 新版本已经发布,用v0.3.85 跑一下https://github.com/flashcatcloud/categraf/releases/tag/v0.3.85

@kongfei605
Copy link
Collaborator

v0.3.85的jstat是否附加pid,完全依赖你配置的 search string了。

@rollingsunn
Copy link
Author

完全去掉对于实现最简单。但是对于配置出来多个pid,不同进程的数据搞到一起更不科学。 所以现在就是如果你的进程数大于1 ,就附加pid,只有一个进程,就不附加pid了。 新版本已经发布,用v0.3.85 跑一下https://github.com/flashcatcloud/categraf/releases/tag/v0.3.85

谢谢大佬,我这就试试 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants