process-exporter

process-exporter

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

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

Prometheus进程监控指标收集配置文件性能优化Github开源项目

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/<pid>/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

编辑推荐精选

Spark-TTS

Spark-TTS

一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型

Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。

Trae

Trae

字节跳动发布的AI编程神器IDE

Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。

AI工具TraeAI IDE协作生产力转型热门
咔片PPT

咔片PPT

AI助力,做PPT更简单!

咔片是一款轻量化在线演示设计工具,借助 AI 技术,实现从内容生成到智能设计的一站式 PPT 制作服务。支持多种文档格式导入生成 PPT,提供海量模板、智能美化、素材替换等功能,适用于销售、教师、学生等各类人群,能高效制作出高品质 PPT,满足不同场景演示需求。

讯飞绘文

讯飞绘文

选题、配图、成文,一站式创作,让内容运营更高效

讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。

热门AI辅助写作AI工具讯飞绘文内容运营AI创作个性化文章多平台分发AI助手
材料星

材料星

专业的AI公文写作平台,公文写作神器

AI 材料星,专业的 AI 公文写作辅助平台,为体制内工作人员提供高效的公文写作解决方案。拥有海量公文文库、9 大核心 AI 功能,支持 30 + 文稿类型生成,助力快速完成领导讲话、工作总结、述职报告等材料,提升办公效率,是体制打工人的得力写作神器。

openai-agents-python

openai-agents-python

OpenAI Agents SDK,助力开发者便捷使用 OpenAI 相关功能。

openai-agents-python 是 OpenAI 推出的一款强大 Python SDK,它为开发者提供了与 OpenAI 模型交互的高效工具,支持工具调用、结果处理、追踪等功能,涵盖多种应用场景,如研究助手、财务研究等,能显著提升开发效率,让开发者更轻松地利用 OpenAI 的技术优势。

Hunyuan3D-2

Hunyuan3D-2

高分辨率纹理 3D 资产生成

Hunyuan3D-2 是腾讯开发的用于 3D 资产生成的强大工具,支持从文本描述、单张图片或多视角图片生成 3D 模型,具备快速形状生成能力,可生成带纹理的高质量 3D 模型,适用于多个领域,为 3D 创作提供了高效解决方案。

3FS

3FS

一个具备存储、管理和客户端操作等多种功能的分布式文件系统相关项目。

3FS 是一个功能强大的分布式文件系统项目,涵盖了存储引擎、元数据管理、客户端工具等多个模块。它支持多种文件操作,如创建文件和目录、设置布局等,同时具备高效的事件循环、节点选择和协程池管理等特性。适用于需要大规模数据存储和管理的场景,能够提高系统的性能和可靠性,是分布式存储领域的优质解决方案。

TRELLIS

TRELLIS

用于可扩展和多功能 3D 生成的结构化 3D 潜在表示

TRELLIS 是一个专注于 3D 生成的项目,它利用结构化 3D 潜在表示技术,实现了可扩展且多功能的 3D 生成。项目提供了多种 3D 生成的方法和工具,包括文本到 3D、图像到 3D 等,并且支持多种输出格式,如 3D 高斯、辐射场和网格等。通过 TRELLIS,用户可以根据文本描述或图像输入快速生成高质量的 3D 资产,适用于游戏开发、动画制作、虚拟现实等多个领域。

ai-agents-for-beginners

ai-agents-for-beginners

10 节课教你开启构建 AI 代理所需的一切知识

AI Agents for Beginners 是一个专为初学者打造的课程项目,提供 10 节课程,涵盖构建 AI 代理的必备知识,支持多种语言,包含规划设计、工具使用、多代理等丰富内容,助您快速入门 AI 代理领域。

下拉加载更多