| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- // Copyright 2015 The Prometheus Authors
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package prometheus
- import "github.com/prometheus/procfs"
- type processCollector struct {
- pid int
- collectFn func(chan<- Metric)
- pidFn func() (int, error)
- cpuTotal *Desc
- openFDs, maxFDs *Desc
- vsize, rss *Desc
- startTime *Desc
- }
- // NewProcessCollector returns a collector which exports the current state of
- // process metrics including cpu, memory and file descriptor usage as well as
- // the process start time for the given process id under the given namespace.
- func NewProcessCollector(pid int, namespace string) Collector {
- return NewProcessCollectorPIDFn(
- func() (int, error) { return pid, nil },
- namespace,
- )
- }
- // NewProcessCollectorPIDFn returns a collector which exports the current state
- // of process metrics including cpu, memory and file descriptor usage as well
- // as the process start time under the given namespace. The given pidFn is
- // called on each collect and is used to determine the process to export
- // metrics for.
- func NewProcessCollectorPIDFn(
- pidFn func() (int, error),
- namespace string,
- ) Collector {
- ns := ""
- if len(namespace) > 0 {
- ns = namespace + "_"
- }
- c := processCollector{
- pidFn: pidFn,
- collectFn: func(chan<- Metric) {},
- cpuTotal: NewDesc(
- ns+"process_cpu_seconds_total",
- "Total user and system CPU time spent in seconds.",
- nil, nil,
- ),
- openFDs: NewDesc(
- ns+"process_open_fds",
- "Number of open file descriptors.",
- nil, nil,
- ),
- maxFDs: NewDesc(
- ns+"process_max_fds",
- "Maximum number of open file descriptors.",
- nil, nil,
- ),
- vsize: NewDesc(
- ns+"process_virtual_memory_bytes",
- "Virtual memory size in bytes.",
- nil, nil,
- ),
- rss: NewDesc(
- ns+"process_resident_memory_bytes",
- "Resident memory size in bytes.",
- nil, nil,
- ),
- startTime: NewDesc(
- ns+"process_start_time_seconds",
- "Start time of the process since unix epoch in seconds.",
- nil, nil,
- ),
- }
- // Set up process metric collection if supported by the runtime.
- if _, err := procfs.NewStat(); err == nil {
- c.collectFn = c.processCollect
- }
- return &c
- }
- // Describe returns all descriptions of the collector.
- func (c *processCollector) Describe(ch chan<- *Desc) {
- ch <- c.cpuTotal
- ch <- c.openFDs
- ch <- c.maxFDs
- ch <- c.vsize
- ch <- c.rss
- ch <- c.startTime
- }
- // Collect returns the current state of all metrics of the collector.
- func (c *processCollector) Collect(ch chan<- Metric) {
- c.collectFn(ch)
- }
- // TODO(ts): Bring back error reporting by reverting 7faf9e7 as soon as the
- // client allows users to configure the error behavior.
- func (c *processCollector) processCollect(ch chan<- Metric) {
- pid, err := c.pidFn()
- if err != nil {
- return
- }
- p, err := procfs.NewProc(pid)
- if err != nil {
- return
- }
- if stat, err := p.NewStat(); err == nil {
- ch <- MustNewConstMetric(c.cpuTotal, CounterValue, stat.CPUTime())
- ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(stat.VirtualMemory()))
- ch <- MustNewConstMetric(c.rss, GaugeValue, float64(stat.ResidentMemory()))
- if startTime, err := stat.StartTime(); err == nil {
- ch <- MustNewConstMetric(c.startTime, GaugeValue, startTime)
- }
- }
- if fds, err := p.FileDescriptorsLen(); err == nil {
- ch <- MustNewConstMetric(c.openFDs, GaugeValue, float64(fds))
- }
- if limits, err := p.NewLimits(); err == nil {
- ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(limits.OpenFiles))
- }
- }
|