{"id":13582225,"url":"https://github.com/ncabatoff/process-exporter","last_synced_at":"2025-05-14T22:03:07.038Z","repository":{"id":10009069,"uuid":"64079945","full_name":"ncabatoff/process-exporter","owner":"ncabatoff","description":"Prometheus exporter that mines /proc to report on selected processes ","archived":false,"fork":false,"pushed_at":"2025-04-21T13:30:37.000Z","size":2376,"stargazers_count":1887,"open_issues_count":121,"forks_count":290,"subscribers_count":29,"default_branch":"master","last_synced_at":"2025-05-07T21:12:31.340Z","etag":null,"topics":["go","process-metrics","prometheus-exporter"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ncabatoff.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-07-24T18:34:44.000Z","updated_at":"2025-05-07T16:12:53.000Z","dependencies_parsed_at":"2023-01-13T15:41:27.344Z","dependency_job_id":"b567ec73-4dde-4967-aead-8244f083c07a","html_url":"https://github.com/ncabatoff/process-exporter","commit_stats":{"total_commits":202,"total_committers":26,"mean_commits":7.769230769230769,"dds":0.2376237623762376,"last_synced_commit":"7ef0b73940787bfd7fcc6a633c9c632093df6d35"},"previous_names":[],"tags_count":53,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ncabatoff%2Fprocess-exporter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ncabatoff%2Fprocess-exporter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ncabatoff%2Fprocess-exporter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ncabatoff%2Fprocess-exporter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ncabatoff","download_url":"https://codeload.github.com/ncabatoff/process-exporter/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254235685,"owners_count":22036962,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","process-metrics","prometheus-exporter"],"created_at":"2024-08-01T15:02:30.416Z","updated_at":"2025-05-14T22:03:06.990Z","avatar_url":"https://github.com/ncabatoff.png","language":"Go","funding_links":[],"categories":["Go","go","其他_安全与渗透","Prometheus-Exporter","Repositories"],"sub_categories":["网络服务_其他"],"readme":"# process-exporter\nPrometheus exporter that mines /proc to report on selected processes.\n\n[release]: https://github.com/ncabatoff/process-exporter/releases/latest\n\n[![Release](https://img.shields.io/github/release/ncabatoff/process-exporter.svg?style=flat-square\")][release]\n[![Powered By: GoReleaser](https://img.shields.io/badge/powered%20by-goreleaser-green.svg?branch=master)](https://github.com/goreleaser)\n![Build](https://github.com/ncabatoff/process-exporter/actions/workflows/build.yml/badge.svg)\n\nSome apps are impractical to instrument directly, either because you\ndon't control the code or they're written in a language that isn't easy to\ninstrument with Prometheus.  We must instead resort to mining /proc.\n\n## Installation\n\nEither grab a package for your OS from the [Releases][release] page, or\ninstall via [docker](https://hub.docker.com/r/ncabatoff/process-exporter/).\n\n## Running\n\nUsage:\n\n```\n  process-exporter [options] -config.path filename.yml\n```\n\nor via docker:\n\n```\n  docker run -d --rm -p 9256:9256 --privileged -v /proc:/host/proc -v `pwd`:/config ncabatoff/process-exporter --procfs /host/proc -config.path /config/filename.yml\n\n```\n\nImportant options (run process-exporter --help for full list):\n\n-children (default:true) makes it so that any process that otherwise\nisn't part of its own group becomes part of the first group found (if any) when\nwalking the process tree upwards.  In other words, resource usage of\nsubprocesses is added to their parent's usage unless the subprocess identifies\nas a different group name.\n\n-threads (default:true) means that metrics will be broken down by thread name\nas well as group name.\n\n-recheck (default:false) means that on each scrape the process names are\nre-evaluated. This is disabled by default as an optimization, but since\nprocesses can choose to change their names, this may result in a process\nfalling into the wrong group if we happen to see it for the first time before\nit's assumed its proper name. You can use -recheck-with-time-limit to enable this\nfeature only for a specific duration after process starts.\n\n-procnames is intended as a quick alternative to using a config file.  Details\nin the following section.\n\n-remove-empty-groups (default:false) forget process groups with no processes.\nThis is particularly useful if you have some process groups that you expect will \nnever return (e.g. if you have process groups named \"scan-\u003cscan-id\u003e\", and once \nthe scan is completed no more process will ever run for that scan again).\n\nTo disable any of these options, use the `-option=false`.\n\n## Configuration and group naming\n\nTo select and group the processes to monitor, either provide command-line\narguments or use a YAML configuration file.\n\nThe recommended option is to use a config file via -config.path, but for\nconvenience and backwards compatibility the -procnames/-namemapping options\nexist as an alternative.\n\n### Using a config file\n\nThe general format of the -config.path YAML file is a top-level\n`process_names` section, containing a list of name matchers:\n\n```\nprocess_names:\n  - matcher1\n  - matcher2\n  ...\n  - matcherN\n```\n\nThe default config shipped with the deb/rpm packages is:\n\n```\nprocess_names:\n  - name: \"{{.Comm}}\"\n    cmdline:\n    - '.+'\n```\n\nA process may only belong to one group: even if multiple items would match, the\nfirst one listed in the file wins.\n\n(Side note: to avoid confusion with the cmdline YAML element, we'll refer to\nthe command-line arguments of a process `/proc/\u003cpid\u003e/cmdline` as the array\n`argv[]`.)\n\n#### Using a config file: group name\n\nEach item in `process_names` gives a recipe for identifying and naming\nprocesses.  The optional `name` tag defines a template to use to name\nmatching processes; if not specified, `name` defaults to `{{.ExeBase}}`.\n\nTemplate variables available:\n- `{{.Comm}}` contains the basename of the original executable, i.e. 2nd field in `/proc/\u003cpid\u003e/stat`\n- `{{.ExeBase}}` contains the basename of the executable\n- `{{.ExeFull}}` contains the fully qualified path of the executable\n- `{{.Username}}` contains the username of the effective user\n- `{{.Matches}}` map contains all the matches resulting from applying cmdline regexps\n- `{{.PID}}` contains the PID of the process.  Note that using PID means the group\n  will only contain a single process.\n- `{{.StartTime}}` contains the start time of the process.  This can be useful\n  in conjunction with PID because PIDs get reused over time.\n- `{{.Cgroups}}` contains (if supported) the cgroups of the process\n  (`/proc/self/cgroup`). This is particularly useful for identifying to which container\n  a process belongs.\n\nUsing `PID` or `StartTime` is discouraged: this is almost never what you want,\nand is likely to result in high cardinality metrics which Prometheus will have\ntrouble with.\n\n#### Using a config file: process selectors\n\nEach item in `process_names` must contain one or more selectors (`comm`, `exe`\nor `cmdline`); if more than one selector is present, they must all match.  Each\nselector is a list of strings to match against a process's `comm`, `argv[0]`,\nor in the case of `cmdline`, a regexp to apply to the command line.  The cmdline\nregexp uses the [Go syntax](https://golang.org/pkg/regexp).\n\nFor `comm` and `exe`, the list of strings is an OR, meaning any process\nmatching any of the strings will be added to the item's group.\n\nFor `cmdline`, the list of regexes is an AND, meaning they all must match.  Any\ncapturing groups in a regexp must use the `?P\u003cname\u003e` option to assign a name to\nthe capture, which is used to populate `.Matches`.\n\nPerformance tip: give an exe or comm clause in addition to any cmdline\nclause, so you avoid executing the regexp when the executable name doesn't\nmatch.\n\n```\n\nprocess_names:\n  # comm is the second field of /proc/\u003cpid\u003e/stat minus parens.\n  # It is the base executable name, truncated at 15 chars.\n  # It cannot be modified by the program, unlike exe.\n  - comm:\n    - bash\n\n  # exe is argv[0]. If no slashes, only basename of argv[0] need match.\n  # If exe contains slashes, argv[0] must match exactly.\n  - exe:\n    - postgres\n    - /usr/local/bin/prometheus\n\n  # cmdline is a list of regexps applied to argv.\n  # Each must match, and any captures are added to the .Matches map.\n  - name: \"{{.ExeFull}}:{{.Matches.Cfgfile}}\"\n    exe:\n    - /usr/local/bin/process-exporter\n    cmdline:\n    - -config.path\\s+(?P\u003cCfgfile\u003e\\S+)\n\n```\n\nHere's the config I use on my home machine:\n\n```\n\nprocess_names:\n  - comm:\n    - chromium-browse\n    - bash\n    - prometheus\n    - gvim\n  - exe:\n    - /sbin/upstart\n    cmdline:\n    - --user\n    name: upstart:-user\n\n```\n\n### Using -procnames/-namemapping instead of config.path\n\nEvery name in the procnames list becomes a process group. The default name of\na process is the value found in the second field of /proc/\u003cpid\u003e/stat\n(\"comm\"), which is truncated at 15 chars.  Usually this is the same as the\nname of the executable.\n\nIf -namemapping isn't provided, every process with a comm value present\nin -procnames is assigned to a group based on that name, and any other\nprocesses are ignored.\n\nThe -namemapping option is a comma-separated list of alternating\nname,regexp values. It allows assigning a name to a process based on a\ncombination of the process name and command line. For example, using\n\n  -namemapping \"python2,([^/]+)\\.py,java,-jar\\s+([^/]+).jar\"\n\nwill make it so that each different python2 and java -jar invocation will be\ntracked with distinct metrics. Processes whose remapped name is absent from\nthe procnames list will be ignored. On a Ubuntu Xenian machine being used as\na workstation, here's a good way of tracking resource usage for a few\ndifferent key user apps:\n\n  process-exporter -namemapping \"upstart,(--user)\" \\\n    -procnames chromium-browse,bash,gvim,prometheus,process-exporter,upstart:-user\n\nSince upstart --user is the parent process of the X11 session, this will\nmake all apps started by the user fall into the group named \"upstart:-user\",\nunless they're one of the others named explicitly with -procnames, like gvim.\n\n## Group Metrics\n\nThere's no meaningful way to name a process that will only ever name a single process, so process-exporter assumes that every metric will be attached\nto a group of processes - not a\n[process group](https://en.wikipedia.org/wiki/Process_group) in the technical\nsense, just one or more processes that meet a configuration's specification\nof what should be monitored and how to name it.\n\nAll these metrics start with `namedprocess_namegroup_` and have at minimum\nthe label `groupname`.\n\n### num_procs gauge\n\nNumber of processes in this group.\n\n### cpu_seconds_total counter\n\nCPU usage based on /proc/[pid]/stat fields utime(14) and stime(15) i.e. user and system time. This is similar to the node\\_exporter's `node_cpu_seconds_total`.\n\n### read_bytes_total counter\n\nBytes read based on /proc/[pid]/io field read_bytes.  The man page\nsays\n\n\u003e Attempt to count the number of bytes which this process really did cause to be fetched from the storage layer.  This is accurate for block-backed filesystems.\n\nbut I would take it with a grain of salt.\n\nAs `/proc/[pid]/io` are set by the kernel as read only to the process' user (see #137), to get these values you should run `process-exporter` either as that user or as `root`. Otherwise, we can't read these values and you'll get a constant 0 in the metric.\n\n### write_bytes_total counter\n\nBytes written based on /proc/[pid]/io field write_bytes.  As with\nread_bytes, somewhat dubious.  May be useful for isolating which processes\nare doing the most I/O, but probably not measuring just how much I/O is happening.\n\n### major_page_faults_total counter\n\nNumber of major page faults based on /proc/[pid]/stat field majflt(12).\n\n### minor_page_faults_total counter\n\nNumber of minor page faults based on /proc/[pid]/stat field minflt(10).\n\n### context_switches_total counter\n\nNumber of context switches based on /proc/[pid]/status fields voluntary_ctxt_switches\nand nonvoluntary_ctxt_switches.  The extra label `ctxswitchtype` can have two values:\n`voluntary` and `nonvoluntary`.\n\n### memory_bytes gauge\n\nNumber of bytes of memory used.  The extra label `memtype` can have three values:\n\n*resident*: Field rss(24) from /proc/[pid]/stat, whose doc says:\n\n\u003e This is just the pages which count toward text, data, or stack space.  This does not include pages which have not been demand-loaded in, or which are swapped out.\n\n*virtual*: Field vsize(23) from /proc/[pid]/stat, virtual memory size.\n\n*swapped*: Field VmSwap from /proc/[pid]/status, translated from KB to bytes.\n\nIf gathering smaps file is enabled, two additional values for `memtype` are added:\n\n*proportionalResident*: Sum of \"Pss\" fields from /proc/[pid]/smaps, whose doc says:\n\n\u003e The \"proportional set size\" (PSS) of a process is the count of pages it has\n\u003e in memory, where each page is divided by the number of processes sharing it.\n\n*proportionalSwapped*: Sum of \"SwapPss\" fields from /proc/[pid]/smaps\n\n### open_filedesc gauge\n\nNumber of file descriptors, based on counting how many entries are in the directory\n/proc/[pid]/fd.\n\n### worst_fd_ratio gauge\n\nWorst ratio of open filedescs to filedesc limit, amongst all the procs in the\ngroup. The limit is the fd soft limit based on /proc/[pid]/limits.\n\nNormally Prometheus metrics ought to be as \"basic\" as possible (i.e. the raw\nvalues rather than a derived ratio), but we use a ratio here because nothing\nelse makes sense. Suppose there are 10 procs in a given group, each with a\nsoft limit of 4096, and one of them has 4000 open fds and the others all have\n40, their total fdcount is 4360 and total soft limit is 40960, so the ratio\nis 1:10, but in fact one of the procs is about to run out of fds. With\nworst_fd_ratio we're able to know this: in the above example it would be\n0.97, rather than the 0.10 you'd see if you computed sum(open_filedesc) /\nsum(limit_filedesc).\n\n### oldest_start_time_seconds gauge\n\nEpoch time (seconds since 1970/1/1) at which the oldest process in the group\nstarted.  This is derived from field starttime(22) from /proc/[pid]/stat, added\nto boot time to make it relative to epoch.\n\n### num_threads gauge\n\nSum of number of threads of all process in the group.  Based on field num_threads(20)\nfrom /proc/[pid]/stat.\n\n### states gauge\n\nNumber of threads in the group in each of various states, based on the field\nstate(3) from /proc/[pid]/stat.\n\nThe extra label `state` can have these values: `Running`, `Sleeping`, `Waiting`, `Zombie`, `Other`.\n\n## Group Thread Metrics\n\nSince publishing thread metrics adds a lot of overhead, use the `-threads` command-line argument to disable them, \nif necessary.\n\nAll these metrics start with `namedprocess_namegroup_` and have at minimum\nthe labels `groupname` and `threadname`.  `threadname` is field comm(2) from\n/proc/[pid]/stat.  Just as groupname breaks the set of processes down into\ngroups, threadname breaks a given process group down into subgroups.\n\n### thread_count gauge\n\nNumber of threads in this thread subgroup.\n\n### thread_cpu_seconds_total counter\n\nSame as cpu_user_seconds_total and cpu_system_seconds_total, but broken down\nper-thread subgroup.  Unlike cpu_user_seconds_total/cpu_system_seconds_total,\nthe label `cpumode` is used to distinguish between `user` and `system` time.\n\n### thread_io_bytes_total counter\n\nSame as read_bytes_total and write_bytes_total, but broken down\nper-thread subgroup.  Unlike read_bytes_total/write_bytes_total,\nthe label `iomode` is used to distinguish between `read` and `write` bytes.\n\n### thread_major_page_faults_total counter\n\nSame as major_page_faults_total, but broken down per-thread subgroup.\n\n### thread_minor_page_faults_total counter\n\nSame as minor_page_faults_total, but broken down per-thread subgroup.\n\n### thread_context_switches_total counter\n\nSame as context_switches_total, but broken down per-thread subgroup.\n\n## Instrumentation cost\n\nprocess-exporter will consume CPU in proportion to the number of processes in\nthe system and the rate at which new ones are created.  The most expensive\nparts - applying regexps and executing templates - are only applied once per\nprocess seen, unless the command-line option -recheck is provided.\n\nIf you have mostly long-running processes process-exporter overhead should be\nminimal: each time a scrape occurs, it will parse of /proc/$pid/stat and\n/proc/$pid/cmdline for every process being monitored and add a few numbers.\n\n## Dashboards\n\nAn example Grafana dashboard to view the metrics is available at https://grafana.net/dashboards/249\n\n## Building\n\nRequires Go 1.21 (at least) installed.\n```\nmake\n```\n\n## Exposing metrics through HTTPS\n\nweb-config.yml\n```\n# Minimal TLS configuration example. Additionally, a certificate and a key file\n# are needed.\ntls_server_config:\n  cert_file: server.crt\n  key_file: server.key\n```\nRunning\n```\n$ ./process-exporter -web.config.file web-config.yml \u0026\n$ curl -sk https://localhost:9256/metrics | grep process\n\n# HELP namedprocess_scrape_errors general scrape errors: no proc metrics collected during a cycle\n# TYPE namedprocess_scrape_errors counter\nnamedprocess_scrape_errors 0\n# HELP namedprocess_scrape_partial_errors incremented each time a tracked proc's metrics collection fails partially, e.g. unreadable I/O stats\n# TYPE namedprocess_scrape_partial_errors counter\nnamedprocess_scrape_partial_errors 0\n# HELP namedprocess_scrape_procread_errors incremented each time a proc's metrics collection fails\n# TYPE namedprocess_scrape_procread_errors counter\nnamedprocess_scrape_procread_errors 0\n# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.\n# TYPE process_cpu_seconds_total counter\nprocess_cpu_seconds_total 0.21\n# HELP process_exporter_build_info A metric with a constant '1' value labeled by version, revision, branch, and goversion from which process_exporter was built.\n# TYPE process_exporter_build_info gauge\nprocess_exporter_build_info{branch=\"\",goversion=\"go1.17.3\",revision=\"\",version=\"\"} 1\n# HELP process_max_fds Maximum number of open file descriptors.\n# TYPE process_max_fds gauge\nprocess_max_fds 1.048576e+06\n# HELP process_open_fds Number of open file descriptors.\n# TYPE process_open_fds gauge\nprocess_open_fds 10\n```\n\nFor further information about TLS configuration, please visit: [exporter-toolkit](https://github.com/prometheus/exporter-toolkit/blob/master/docs/web-configuration.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fncabatoff%2Fprocess-exporter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fncabatoff%2Fprocess-exporter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fncabatoff%2Fprocess-exporter/lists"}