Project Icon

process-exporter

基于Prometheus的进程监控及指标导出工具

process-exporter是一个为Prometheus设计的导出工具,通过解析/proc目录获取选定进程的指标。它提供灵活的配置选项,支持自定义进程分组和命名。该工具可收集CPU使用率、内存占用和I/O操作等关键指标,特别适用于难以直接植入Prometheus监控代码的应用。process-exporter支持二进制包和Docker镜像安装,为IT运维人员提供了简便的进程监控方案。

process-exporter

一个用于挖掘/proc目录并报告所选进程信息的Prometheus导出器。

发布 由GoReleaser驱动 构建

有些应用程序直接进行instrumentation是不切实际的,原因可能是你无法控制代码,或者它们是用难以与Prometheus进行instrumentation的语言编写的。在这种情况下,我们必须转而挖掘/proc目录。

安装

你可以从发布页面下载适用于你操作系统的软件包,或通过docker进行安装。

运行

使用方法:

  process-exporter [选项] -config.path 文件名.yml

或通过docker运行:

  docker run -d --rm -p 9256:9256 --privileged -v /proc:/host/proc -v `pwd`:/config ncabatoff/process-exporter --procfs /host/proc -config.path /config/文件名.yml

重要选项(运行process-exporter --help查看完整列表):

-children(默认:true)使得任何原本不属于自己组的进程在向上遍历进程树时成为找到的第一个组(如果有)的一部分。换句话说,子进程的资源使用会被加到其父进程的使用中,除非子进程标识为不同的组名。

-threads(默认:true)意味着指标将按线程名和组名进行细分。

-recheck(默认:false)意味着在每次抓取时重新评估进程名。默认情况下,这个功能是禁用的,以优化性能,但由于进程可以选择更改其名称,如果我们在进程采用其正确名称之前首次看到它,这可能导致进程被归类到错误的组中。你可以使用-recheck-with-time-limit在进程启动后的特定时间内启用此功能。

-procnames旨在作为使用配置文件的快速替代方案。详情见下一节。

要禁用这些选项中的任何一个,请使用-选项=false

配置和组命名

要选择和分组要监控的进程,可以提供命令行参数或使用YAML配置文件。

推荐的选项是通过-config.path使用配置文件,但为了方便和向后兼容,-procnames/-namemapping选项也可作为替代方案。

使用配置文件

-config.path YAML文件的一般格式是一个顶级的process_names部分,包含一个名称匹配器列表:

process_names:
  - 匹配器1
  - 匹配器2
  ...
  - 匹配器N

deb/rpm包附带的默认配置是:

process_names:
  - name: "{{.Comm}}"
    cmdline:
    - '.+'

一个进程只能属于一个组:即使多个项目都匹配,文件中列出的第一个会胜出。

(注:为避免与YAML元素cmdline混淆,我们将进程的/proc/<pid>/cmdline命令行参数称为数组argv[]。)

使用配置文件:组名

process_names中的每个项目都给出了识别和命名进程的方法。可选的name标签定义了用于命名匹配进程的模板;如果未指定,name默认为{{.ExeBase}}

可用的模板变量:

  • {{.Comm}}包含原始可执行文件的基本名称,即/proc/<pid>/stat中的第二个字段
  • {{.ExeBase}}包含可执行文件的基本名称
  • {{.ExeFull}}包含可执行文件的完整限定路径
  • {{.Username}}包含有效用户的用户名
  • {{.Matches}}映射包含应用cmdline正则表达式后的所有匹配结果
  • {{.PID}}包含进程的PID。注意使用PID意味着该组将只包含单个进程。
  • {{.StartTime}}包含进程的启动时间。这在与PID一起使用时可能有用,因为PID会随时间重复使用。
  • {{.Cgroups}}包含(如果支持)进程的cgroups(/proc/self/cgroup)。这对于识别进程属于哪个容器特别有用。

不建议使用PIDStartTime:这几乎从来不是你想要的,并且可能导致Prometheus难以处理的高基数指标。

使用配置文件:进程选择器

process_names中的每个项目必须包含一个或多个选择器(commexecmdline);如果存在多个选择器,它们必须全部匹配。每个选择器是一个字符串列表,用于匹配进程的commargv[0],或在cmdline的情况下,应用于命令行的正则表达式。cmdline正则表达式使用Go语法

对于commexe,字符串列表是一个OR关系,意味着匹配任何字符串的任何进程都将被添加到该项目的组中。

对于cmdline,正则表达式列表是一个AND关系,意味着它们都必须匹配。正则表达式中的任何捕获组都必须使用?P<name>选项为捕获指定一个名称,该名称用于填充.Matches

性能提示:除了任何cmdline子句外,还要给出exe或comm子句,这样可以避免在可执行文件名不匹配时执行正则表达式。


process_names:
  # comm是/proc/<pid>/stat的第二个字段减去括号。
  # 它是基本可执行文件名,截断为15个字符。
  # 它不能被程序修改,与exe不同。
  - comm:
    - bash

  # exe是argv[0]。如果没有斜杠,只需匹配argv[0]的基本名称。
  # 如果exe包含斜杠,argv[0]必须完全匹配。
  - exe:
    - postgres
    - /usr/local/bin/prometheus

  # cmdline是应用于argv的正则表达式列表。
  # 每个都必须匹配,任何捕获都会被添加到.Matches映射中。
  - name: "{{.ExeFull}}:{{.Matches.Cfgfile}}"
    exe:
    - /usr/local/bin/process-exporter
    cmdline:
    - -config.path\s+(?P<Cfgfile>\S+)

这是我在家用机器上使用的配置:


process_names:
  - comm:
    - chromium-browse
    - bash
    - prometheus
    - gvim
  - exe:
    - /sbin/upstart
    cmdline:
    - --user
    name: upstart:-user

使用-procnames/-namemapping替代config.path

procnames列表中的每个名称都成为一个进程组。进程的默认名称是/proc//stat的第二个字段("comm")中的值,截断为15个字符。通常这与可执行文件的名称相同。

如果未提供-namemapping,则comm值出现在-procnames中的每个进程都会根据该名称分配到一个组,其他进程则被忽略。

-namemapping选项是一个由名称、正则表达式值交替组成的逗号分隔列表。它允许基于进程名称和命令行的组合为进程分配名称。例如,使用

-namemapping "python2,([^/]+).py,java,-jar\s+([^/]+).jar"

将使每个不同的python2和java -jar调用都能用不同的指标进行跟踪。重新映射后名称不在procnames列表中的进程将被忽略。在一台用作工作站的Ubuntu Xenian机器上,以下是跟踪几个不同关键用户应用程序资源使用情况的好方法:

process-exporter -namemapping "upstart,(--user)"
-procnames chromium-browse,bash,gvim,prometheus,process-exporter,upstart:-user

由于upstart --user是X11会话的父进程,这将使用户启动的所有应用程序都归入名为"upstart:-user"的组,除非它们是-procnames中明确命名的其他应用程序之一,比如gvim。

组指标

没有有意义的方法来命名一个只会命名单个进程的进程,所以process-exporter假设每个指标都会附加到一组进程上 - 不是技术意义上的进程组,而只是一个或多个符合配置规定的应监控和命名方式的进程。

所有这些指标都以namedprocess_namegroup_开头,并至少具有标签groupname

num_procs 仪表

该组中的进程数。

cpu_seconds_total 计数器

基于/proc/[pid]/stat字段utime(14)和stime(15)的CPU使用情况,即用户和系统时间。这类似于node_exporter的node_cpu_seconds_total

read_bytes_total 计数器

基于/proc/[pid]/io字段read_bytes的读取字节数。手册页说

尝试计算这个进程实际上导致从存储层获取的字节数。这对于基于块的文件系统是准确的。

但我建议对此持保留态度。

由于/proc/[pid]/io被内核设置为仅对进程的用户可读(参见#137),要获取这些值,你应该以该用户或root身份运行process-exporter。否则,我们无法读取这些值,你将在指标中得到恒定的0。

write_bytes_total 计数器

基于/proc/[pid]/io字段write_bytes的写入字节数。与read_bytes一样,有些可疑。可能对于隔离哪些进程在做最多的I/O有用,但可能无法准确测量实际发生了多少I/O。

major_page_faults_total 计数器

基于/proc/[pid]/stat字段majflt(12)的主要页面故障数。

minor_page_faults_total 计数器

基于/proc/[pid]/stat字段minflt(10)的次要页面故障数。

context_switches_total 计数器

基于/proc/[pid]/status字段voluntary_ctxt_switches和nonvoluntary_ctxt_switches的上下文切换次数。额外的标签ctxswitchtype可以有两个值:voluntarynonvoluntary

memory_bytes 仪表

使用的内存字节数。额外的标签memtype可以有三个值:

resident:来自/proc/[pid]/stat的rss(24)字段,其文档说:

这只是计入文本、数据或堆栈空间的页面。这不包括尚未按需加载或已被换出的页面。

virtual:来自/proc/[pid]/stat的vsize(23)字段,虚拟内存大小。

swapped:来自/proc/[pid]/status的VmSwap字段,从KB转换为字节。

如果启用了收集smaps文件,memtype会增加两个额外的值:

proportionalResident:/proc/[pid]/smaps中"Pss"字段的总和,其文档说:

进程的"比例集大小"(PSS)是它在内存中的页面计数,其中每个页面除以共享它的进程数。

proportionalSwapped:/proc/[pid]/smaps中"SwapPss"字段的总和

open_filedesc 仪表

文件描述符数量,基于计算/proc/[pid]/fd目录中的条目数。

worst_fd_ratio 仪表

组内所有进程中打开的文件描述符与文件描述符限制的最差比率。该限制基于/proc/[pid]/limits中的fd软限制。 通常Prometheus指标应尽可能"基本"(即原始值而非衍生比率),但我们在这里使用比率是因为没有其他更合理的方式。假设一个组中有10个进程,每个进程的软限制为4096,其中一个有4000个打开的文件描述符,而其他进程只有40个,它们的总文件描述符数量是4360,总软限制是40960,所以比率是1:10。但实际上其中一个进程即将耗尽文件描述符。通过worst_fd_ratio我们能够了解这一点:在上述例子中它将是0.97,而不是如果你计算sum(open_filedesc) / sum(limit_filedesc)得到的0.10。

oldest_start_time_seconds 仪表

组内最老进程的启动时间(自1970年1月1日起的秒数)。这是从/proc/[pid]/stat的starttime(22)字段得出的,加上启动时间以使其相对于纪元。

num_threads 仪表

组内所有进程的线程数之和。基于/proc/[pid]/stat的num_threads(20)字段。

states 仪表

组内处于各种状态的线程数,基于/proc/[pid]/stat的state(3)字段。

额外的标签state可以有以下值:RunningSleepingWaitingZombieOther

组线程指标

由于发布线程指标会增加大量开销,如有必要,可以使用-threads命令行参数来禁用它们。

所有这些指标都以namedprocess_namegroup_开头,至少包含groupnamethreadname标签。threadname是/proc/[pid]/stat的comm(2)字段。就像groupname将进程集分解成组一样,threadname将给定的进程组分解成子组。

thread_count 仪表

此线程子组中的线程数。

thread_cpu_seconds_total 计数器

与cpu_user_seconds_total和cpu_system_seconds_total相同,但按线程子组细分。与cpu_user_seconds_total/cpu_system_seconds_total不同,使用cpumode标签来区分usersystem时间。

thread_io_bytes_total 计数器

与read_bytes_total和write_bytes_total相同,但按线程子组细分。与read_bytes_total/write_bytes_total不同,使用iomode标签来区分readwrite字节。

thread_major_page_faults_total 计数器

与major_page_faults_total相同,但按线程子组细分。

thread_minor_page_faults_total 计数器

与minor_page_faults_total相同,但按线程子组细分。

thread_context_switches_total 计数器

与context_switches_total相同,但按线程子组细分。

工具性能开销

process-exporter的CPU消耗与系统中的进程数量及新进程创建的速率成正比。最耗费资源的部分 - 应用正则表达式和执行模板 - 对于每个观察到的进程只执行一次,除非提供了-recheck命令行选项。

如果你主要有长期运行的进程,process-exporter的开销应该很小:每次抓取发生时,它会为每个被监控的进程解析/proc/$pid/stat和/proc/$pid/cmdline,并进行一些简单的数学计算。

仪表板

可以在https://grafana.net/dashboards/249 查看用于查看这些指标的示例Grafana仪表板。

构建

需要安装Go 1.21(或更高版本)。

make

通过HTTPS暴露指标

web-config.yml

# 最小TLS配置示例。此外,还需要证书和密钥文件。
tls_server_config:
  cert_file: server.crt
  key_file: server.key

运行

$ ./process-exporter -web.config.file web-config.yml &
$ curl -sk https://localhost:9256/metrics | grep process

# HELP namedprocess_scrape_errors 通用抓取错误:在一个周期内未收集到进程指标
# TYPE namedprocess_scrape_errors counter
namedprocess_scrape_errors 0
# HELP namedprocess_scrape_partial_errors 每次跟踪的进程指标收集部分失败时递增,例如不可读的I/O统计
# TYPE namedprocess_scrape_partial_errors counter
namedprocess_scrape_partial_errors 0
# HELP namedprocess_scrape_procread_errors 每次进程指标收集失败时递增
# TYPE namedprocess_scrape_procread_errors counter
namedprocess_scrape_procread_errors 0
# HELP process_cpu_seconds_total 用户和系统CPU总时间(以秒为单位)。
# TYPE process_cpu_seconds_total counter
process_cpu_seconds_total 0.21
# HELP process_exporter_build_info 一个常量为'1'的指标,标记了构建process_exporter的版本、修订、分支和go版本。
# TYPE process_exporter_build_info gauge
process_exporter_build_info{branch="",goversion="go1.17.3",revision="",version=""} 1
# HELP process_max_fds 最大打开文件描述符数。
# TYPE process_max_fds gauge
process_max_fds 1.048576e+06
# HELP process_open_fds 打开的文件描述符数。
# TYPE process_open_fds gauge
process_open_fds 10

有关TLS配置的更多信息,请访问:exporter-toolkit

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

稿定AI

稿定设计 是一个多功能的在线设计和创意平台,提供广泛的设计工具和资源,以满足不同用户的需求。从专业的图形设计师到普通用户,无论是进行图片处理、智能抠图、H5页面制作还是视频剪辑,稿定设计都能提供简单、高效的解决方案。该平台以其用户友好的界面和强大的功能集合,帮助用户轻松实现创意设计。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号