blob: 9b809794212d2cc0ed0022aef9d603e5b3ed482e [file] [log] [blame]
khenaidooab1f7bd2019-11-14 14:00:27 -05001// Copyright 2015 The Prometheus Authors
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14package prometheus
15
16import (
17 "errors"
18 "os"
19)
20
21type processCollector struct {
22 collectFn func(chan<- Metric)
23 pidFn func() (int, error)
24 reportErrors bool
25 cpuTotal *Desc
26 openFDs, maxFDs *Desc
27 vsize, maxVsize *Desc
28 rss *Desc
29 startTime *Desc
30}
31
32// ProcessCollectorOpts defines the behavior of a process metrics collector
33// created with NewProcessCollector.
34type ProcessCollectorOpts struct {
35 // PidFn returns the PID of the process the collector collects metrics
36 // for. It is called upon each collection. By default, the PID of the
37 // current process is used, as determined on construction time by
38 // calling os.Getpid().
39 PidFn func() (int, error)
40 // If non-empty, each of the collected metrics is prefixed by the
41 // provided string and an underscore ("_").
42 Namespace string
43 // If true, any error encountered during collection is reported as an
44 // invalid metric (see NewInvalidMetric). Otherwise, errors are ignored
45 // and the collected metrics will be incomplete. (Possibly, no metrics
46 // will be collected at all.) While that's usually not desired, it is
47 // appropriate for the common "mix-in" of process metrics, where process
48 // metrics are nice to have, but failing to collect them should not
49 // disrupt the collection of the remaining metrics.
50 ReportErrors bool
51}
52
53// NewProcessCollector returns a collector which exports the current state of
54// process metrics including CPU, memory and file descriptor usage as well as
55// the process start time. The detailed behavior is defined by the provided
56// ProcessCollectorOpts. The zero value of ProcessCollectorOpts creates a
57// collector for the current process with an empty namespace string and no error
58// reporting.
59//
60// The collector only works on operating systems with a Linux-style proc
61// filesystem and on Microsoft Windows. On other operating systems, it will not
62// collect any metrics.
63func NewProcessCollector(opts ProcessCollectorOpts) Collector {
64 ns := ""
65 if len(opts.Namespace) > 0 {
66 ns = opts.Namespace + "_"
67 }
68
69 c := &processCollector{
70 reportErrors: opts.ReportErrors,
71 cpuTotal: NewDesc(
72 ns+"process_cpu_seconds_total",
73 "Total user and system CPU time spent in seconds.",
74 nil, nil,
75 ),
76 openFDs: NewDesc(
77 ns+"process_open_fds",
78 "Number of open file descriptors.",
79 nil, nil,
80 ),
81 maxFDs: NewDesc(
82 ns+"process_max_fds",
83 "Maximum number of open file descriptors.",
84 nil, nil,
85 ),
86 vsize: NewDesc(
87 ns+"process_virtual_memory_bytes",
88 "Virtual memory size in bytes.",
89 nil, nil,
90 ),
91 maxVsize: NewDesc(
92 ns+"process_virtual_memory_max_bytes",
93 "Maximum amount of virtual memory available in bytes.",
94 nil, nil,
95 ),
96 rss: NewDesc(
97 ns+"process_resident_memory_bytes",
98 "Resident memory size in bytes.",
99 nil, nil,
100 ),
101 startTime: NewDesc(
102 ns+"process_start_time_seconds",
103 "Start time of the process since unix epoch in seconds.",
104 nil, nil,
105 ),
106 }
107
108 if opts.PidFn == nil {
109 pid := os.Getpid()
110 c.pidFn = func() (int, error) { return pid, nil }
111 } else {
112 c.pidFn = opts.PidFn
113 }
114
115 // Set up process metric collection if supported by the runtime.
116 if canCollectProcess() {
117 c.collectFn = c.processCollect
118 } else {
119 c.collectFn = func(ch chan<- Metric) {
120 c.reportError(ch, nil, errors.New("process metrics not supported on this platform"))
121 }
122 }
123
124 return c
125}
126
127// Describe returns all descriptions of the collector.
128func (c *processCollector) Describe(ch chan<- *Desc) {
129 ch <- c.cpuTotal
130 ch <- c.openFDs
131 ch <- c.maxFDs
132 ch <- c.vsize
133 ch <- c.maxVsize
134 ch <- c.rss
135 ch <- c.startTime
136}
137
138// Collect returns the current state of all metrics of the collector.
139func (c *processCollector) Collect(ch chan<- Metric) {
140 c.collectFn(ch)
141}
142
143func (c *processCollector) reportError(ch chan<- Metric, desc *Desc, err error) {
144 if !c.reportErrors {
145 return
146 }
147 if desc == nil {
148 desc = NewInvalidDesc(err)
149 }
150 ch <- NewInvalidMetric(desc, err)
151}