进程监控:Zabbix 和 Nightingale 生态对比

巴辉特 2024-11-07 11:36:04

Zabbix 监控进程和 Nightingale 监控进程的原理是一样的,但是产品体验很不相同,Zabbix 更多的是通过页面管理,Nightingale 更多的是 Prometheus 生态的玩法,靠 agent 配置驱动,采集相关进程的监控数据。本文分别演示两个产品的配置方式,帮助大家更好的理解两者的区别。

监控进程的原理

所谓的进程监控,通常是指监控进程的数量以及进程占用的 CPU、内存等资源。比如监控 Nginx 进程,平时 Nginx 进程数是 8,如果进程数不是 8 了,就不符合预期,同时,我们也希望知道 Nginx 进程占用了多少 CPU、内存等资源,甚至想知道 Nginx 进程的句柄限制等。

在 Linux 系统中,进程的信息都可以通过 /proc 文件系统获取,比如 /proc/1 是进程 1 的信息,/proc/1/status 是进程 1 的状态信息,/proc/1/cmdline 是进程 1 的启动命令等。所以,监控进程的原理就是读取 /proc 文件系统中的信息,然后计算出我们需要的监控数据。

这里我给大家看一下样例:

root@ubuntu-linux-22-04-desktop:~/works# ps aux|grep zabbix_agent
zabbix    116675  0.0  0.0  21688  4140 ?        S    Nov02   0:00 /usr/sbin/zabbix_agentd -c /etc/zabbix/zabbix_agentd.conf
zabbix    116678  0.0  0.0  21688  2588 ?        S    Nov02   4:00 /usr/sbin/zabbix_agentd: collector [idle 1 sec]
zabbix    116679  0.0  0.0  23340  4740 ?        S    Nov02   2:03 /usr/sbin/zabbix_agentd: listener #1 [waiting for connection]
zabbix    116680  0.0  0.0  23344  4736 ?        S    Nov02   2:02 /usr/sbin/zabbix_agentd: listener #2 [waiting for connection]
zabbix    116681  0.0  0.0  23340  4736 ?        S    Nov02   2:06 /usr/sbin/zabbix_agentd: listener #3 [waiting for connection]
zabbix    116682  0.0  0.0  23340  4736 ?        S    Nov02   2:03 /usr/sbin/zabbix_agentd: listener #4 [waiting for connection]
zabbix    116683  0.0  0.0  23340  4740 ?        S    Nov02   2:04 /usr/sbin/zabbix_agentd: listener #5 [waiting for connection]
zabbix    116684  0.0  0.0  23344  4732 ?        S    Nov02   2:06 /usr/sbin/zabbix_agentd: listener #6 [waiting for connection]
zabbix    116685  0.0  0.0  23344  4732 ?        S    Nov02   2:06 /usr/sbin/zabbix_agentd: listener #7 [waiting for connection]
zabbix    116686  0.0  0.0  23344  4732 ?        S    Nov02   2:04 /usr/sbin/zabbix_agentd: listener #8 [waiting for connection]
zabbix    116687  0.0  0.0  23344  4732 ?        S    Nov02   2:05 /usr/sbin/zabbix_agentd: listener #9 [waiting for connection]
zabbix    116688  0.0  0.0  23340  4736 ?        S    Nov02   2:05 /usr/sbin/zabbix_agentd: listener #10 [waiting for connection]
zabbix    116689  0.0  0.0  22228  3808 ?        S    Nov02   3:27 /usr/sbin/zabbix_agentd: active checks #1 [idle 1 sec]
root     1789894  0.0  0.0   9016  1860 pts/1    S+   11:43   0:00 grep --color=auto zabbix_agent
root@ubuntu-linux-22-04-desktop:~/works# head -n 3 /proc/116675/status
Name:	zabbix_agentd
Umask:	0002
State:	S (sleeping)
root@ubuntu-linux-22-04-desktop:~/works# cat /proc/116675/cmdline | tr '\0' ' '; echo
/usr/sbin/zabbix_agentd -c /etc/zabbix/zabbix_agentd.conf

上例中,我首先通过 ps aux|grep zabbix_agent 命令找到了 zabbix_agentd 进程的 PID,然后通过 /proc/116675/status 文件查看了 zabbix_agentd 进程的状态信息,通过 /proc/116675/cmdline 文件查看了 zabbix_agentd 进程的启动命令。

其中 status 文件中的 Name 字段是进程的名字,我们监控进程的时候,经常靠这个字段来做匹配,Name 字段是有长度限制的,一般是 15 个字符。cmdline 文件中是进程的启动命令,但是这个 cmdline 的内容是以 \0 分隔的,所以我用 tr '\0' ' ' 命令将 \0 替换为空格,方便大家查看。\0 是不可见不可打印的字符,如果你直接 cat /proc/116675/cmdline,会看到是一长串字符串,没有分隔。

要监控什么进程,用户得告诉监控系统,怎么告诉?本质就是告诉监控系统想要监控的进程的 Name 是啥,cmdline 是啥,即传入一些匹配条件,匹配到的进程就是用户要求监控的进程。

Zabbix 监控进程

这里我在 Zabbix 中创建了一个监控项,监控 zabbix_agentd 进程的数量。如下图所示:

Zabbix item list

首先是进入 Hosts 菜单,然后找到我要监控的机器,点击 Items 进入机器的监控项列表,然后点击 Create item 创建一个监控项。创建的时候最最核心要填写的是 Key,我这里写的 Key 是 proc.num[zabbix_agentd],这个 Key 的意思是监控 zabbix_agentd 进程的数量。这个 Key 是 Zabbix 自带的,不需要用户自己写,只需要填写好参数即可。完事点击 Test,就可以发起一个测试请求,看看监控项是否正常。

Zabbix item test

如果一切正常,就可以创建告警规则了,在 Zabbix 中称为 Trigger,如下图所示:

Zabbix Trigger

这里我故意把阈值设置为等于 13 就告警,让它立马产生告警,因为我的环境里,这个值就是 13。上面可以看到 Value 是 PROBLEM,表示这个监控项已经触发了告警。

Zabbix 告警设计小结

对于 Zabbix 内置的指标,整体还是比较丝滑的,不需要改配置文件,在页面上就可以完成。当然,Zabbix-Agent 毕竟无法采集所有数据,有些数据还是需要用户自己写脚本来采集,这个时候就需要改配置文件了。

Zabbix-Agent 采集的任何数据都有一个称为 Key 的东西作为标识,Key 对应的监控数据会因为参数不同而结果不同,比如 proc.num[zabbix_agentd]proc.num[nginx],这两个 Key 都是监控进程数量的,但是参数不同,一个是 zabbix_agentd,一个是 nginx。

姑且可以理解为:Zabbix-agent 提供了一个接口,然后远端的 Zabbix-Server 通过这个接口获取监控数据,而要获取哪些监控数据,肯定是需要通过参数传给 Zabbix-agent 的,这个参数就是 Key 以及 Key 的参数。

其实 proc.num 还有别的参数,比如 proc.num[,,run],这个参数的意思是监控所有 run 状态的进程的数量。

proc.num 实际有多个参数,其调用格式为:proc.num[<name>,<user>,<state>,<cmdline>,<zone>],各个参数的含义,可以参考 Zabbix 官方文档。

  • name - the process name (default is all processes);
  • user - the user name (default is all users);
  • state - possible values:
    • all (default),
    • disk - uninterruptible sleep,
    • run - running,
    • sleep - interruptible sleep,
    • trace - stopped,
    • zomb - zombie;
  • cmdline - filter by command line (it is a regular expression);
  • zone - the target zone: current (default), or all. This parameter is supported on Solaris only.

这种 Key 的设计,今天来看,实际是不太合理的,尤其是做聚合计算的时候,因为参数和 Key 是没有结构化区分的,比如我想计算某个服务的所有接口的平均响应时间,这个时候,我就需要写很多 Key,然后做聚合计算,这个时候,Key 的设计就显得不够灵活了。而 OpenTSDB、Prometheus 等设计的 metric_name + 多维度标签的方式,则更为方便实现这类需求。

Nightingale 监控进程

夜莺监控 Nightingale 其实并不能采集监控数据,所以说用 Nightingale 来监控什么什么,其实不太合理,Nightingale 更多的是一个告警引擎,监控数据的采集是通过 Prometheus 的 Exporter 来完成的,或者通过 Telegraf、Categraf、Datadog-Agent 等各类采集器来完成的。

我这里以 Categraf 来举例,Categraf 是一个 Go 语言编写的监控数据采集器,支持很多插件,监控进程的插件叫 procstat,如下图是 procstat 的配置文件:

[[instances]]
# # executable name (ie, pgrep <search_exec_substring>)
search_exec_substring = "zabbix_agentd"

# # pattern as argument for pgrep (ie, pgrep -f <search_cmdline_substring>)
# search_cmdline_substring = "n9e server"

# # windows service name
# search_win_service = ""

# # search_exec_regexp: Use a regular expression to match the executable path
# # executable name filter to regexp (like "ps -e | grep -E <search_exec_regexp>" but using re2 regexp )
# search_exec_regexp = ""

# # search_cmdline_regexp: Use a regular expression to match the command line
# # executable name filter to regexp (like "ps -ef | grep -E <search_cmdline_regexp>" but using re2 regexp )
# search_cmdline_regexp = ""

# # [option] search process with specific user
# search_user = ""


# # mode to use when calculating CPU usage. can be one of 'solaris' or 'irix'
# mode = "irix"

# sum of threads/fd/io/cpu/mem, min of uptime/limit
gather_total = true

# will append pid as tag
gather_per_pid = true

gather_more_metrics = [
    "threads",
    "fd",
    "io",
    "uptime",
    "cpu",
    "mem",
    "limit"
]

上例中也是采集 zabbix_agentd 进程的数据,不止可以采集 zabbix_agentd 的进程数量,也可以采集其 threads 数量、fd 数量、io 情况、cpu 占用情况、内存占用情况等。要采集什么监控数据,用户就只需要配置这么一个配置文件即可,如果要采集多个进程,就拷贝 [[instances]] 配置块即可。

Zabbix 要采集什么数据基本都是需要在 WEB 上配置的,而 Prometheus 生态要采集什么数据,大都是通过配置采集器来完成的,不但数据的采集,数据的处理、转换等,也都是在采集器中完成的。

配置完成 procstat.toml 之后,执行如下命令可以查看采集到了哪些指标:

./categraf --test --inputs procstat

如果一切正常,就可以使用 systemd 之类的进程管理器启动 Categraf,让 Categraf 把采集到的数据通过 remote write 协议推给远端的 Nightingale,或者直接推给远端的时序库都是可以的。(远端地址是配置在 Categraf 的主配置文件中的)

数据采集之后,就可以在 Nightingale 中配置告警规则了。一般公司会监控很多进程,没必要为每个进程都分别配置一条告警规则,在 Prometheus 生态里,可以写这么一条 PromQL 即可对所有 Categraf 采集的进程实现进程存活监控:

procstat_lookup_count != 0

总结

本文围绕进程监控这个需求,演示了 Zabbix 和 Nightingale 两个产品的配置方式,希望能帮助大家更好的理解两者的区别。对于刚接触监控领域的朋友而言,总之觉得能监控进程存活即可,但从笔者而言,这两个产品的设计截然不同,了解他们的思路非常有意思,对于未来我们的选型也至关重要。

快猫星云 联系方式 快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云
OpenSource
开源版
Flashcat
Flashcat