From d1d9dee31bf6af03f26da5d9992d0f7ede8966f4 Mon Sep 17 00:00:00 2001 From: Tobias Schmidt Date: Mon, 2 Feb 2015 14:29:00 -0500 Subject: [PATCH] Remove dependency on procfs/cgo in non-procfs systems The procfs package has a cgo dependency (necessary to calculate system times). As procfs is not available under windows, darwin and supposely all newer BSD systems, this change remove the procfs dependency on these systems. --- prometheus/process_collector.go | 84 ++++++-------------------- prometheus/process_collector_procfs.go | 84 ++++++++++++++++++++++++++ prometheus/process_collector_rest.go | 24 ++++++++ 3 files changed, 125 insertions(+), 67 deletions(-) create mode 100644 prometheus/process_collector_procfs.go create mode 100644 prometheus/process_collector_rest.go diff --git a/prometheus/process_collector.go b/prometheus/process_collector.go index ecaab2f..7fd1227 100644 --- a/prometheus/process_collector.go +++ b/prometheus/process_collector.go @@ -1,6 +1,17 @@ -package prometheus +// 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. -import "github.com/prometheus/procfs" +package prometheus type processCollector struct { pid int @@ -33,7 +44,7 @@ func NewProcessCollectorPIDFn( ) *processCollector { c := processCollector{ pidFn: pidFn, - collectFn: noopCollect, + collectFn: func(chan<- Metric) {}, cpuTotal: NewCounter(CounterOpts{ Namespace: namespace, @@ -67,9 +78,9 @@ func NewProcessCollectorPIDFn( }), } - // Use procfs to export metrics if available. - if _, err := procfs.NewStat(); err == nil { - c.collectFn = c.procfsCollect + // Set up process metric collection if supported by the runtime. + if processCollectSupported() { + c.collectFn = c.processCollect } return &c @@ -89,64 +100,3 @@ func (c *processCollector) Describe(ch chan<- *Desc) { func (c *processCollector) Collect(ch chan<- Metric) { c.collectFn(ch) } - -func noopCollect(ch chan<- Metric) {} - -func (c *processCollector) procfsCollect(ch chan<- Metric) { - pid, err := c.pidFn() - if err != nil { - c.reportCollectErrors(ch, err) - return - } - - p, err := procfs.NewProc(pid) - if err != nil { - c.reportCollectErrors(ch, err) - return - } - - if stat, err := p.NewStat(); err != nil { - // Report collect errors for metrics depending on stat. - ch <- NewInvalidMetric(c.vsize.Desc(), err) - ch <- NewInvalidMetric(c.rss.Desc(), err) - ch <- NewInvalidMetric(c.startTime.Desc(), err) - ch <- NewInvalidMetric(c.cpuTotal.Desc(), err) - } else { - c.cpuTotal.Set(stat.CPUTime()) - ch <- c.cpuTotal - c.vsize.Set(float64(stat.VirtualMemory())) - ch <- c.vsize - c.rss.Set(float64(stat.ResidentMemory())) - ch <- c.rss - - if startTime, err := stat.StartTime(); err != nil { - ch <- NewInvalidMetric(c.startTime.Desc(), err) - } else { - c.startTime.Set(startTime) - ch <- c.startTime - } - } - - if fds, err := p.FileDescriptorsLen(); err != nil { - ch <- NewInvalidMetric(c.openFDs.Desc(), err) - } else { - c.openFDs.Set(float64(fds)) - ch <- c.openFDs - } - - if limits, err := p.NewLimits(); err != nil { - ch <- NewInvalidMetric(c.maxFDs.Desc(), err) - } else { - c.maxFDs.Set(float64(limits.OpenFiles)) - ch <- c.maxFDs - } -} - -func (c *processCollector) reportCollectErrors(ch chan<- Metric, err error) { - ch <- NewInvalidMetric(c.cpuTotal.Desc(), err) - ch <- NewInvalidMetric(c.openFDs.Desc(), err) - ch <- NewInvalidMetric(c.maxFDs.Desc(), err) - ch <- NewInvalidMetric(c.vsize.Desc(), err) - ch <- NewInvalidMetric(c.rss.Desc(), err) - ch <- NewInvalidMetric(c.startTime.Desc(), err) -} diff --git a/prometheus/process_collector_procfs.go b/prometheus/process_collector_procfs.go new file mode 100644 index 0000000..2bea3ba --- /dev/null +++ b/prometheus/process_collector_procfs.go @@ -0,0 +1,84 @@ +// 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. + +// +build linux plan9 solaris + +package prometheus + +import "github.com/prometheus/procfs" + +func processCollectSupported() bool { + if _, err := procfs.NewStat(); err == nil { + return true + } + return false +} + +func (c *processCollector) processCollect(ch chan<- Metric) { + pid, err := c.pidFn() + if err != nil { + c.reportCollectErrors(ch, err) + return + } + + p, err := procfs.NewProc(pid) + if err != nil { + c.reportCollectErrors(ch, err) + return + } + + if stat, err := p.NewStat(); err != nil { + // Report collect errors for metrics depending on stat. + ch <- NewInvalidMetric(c.vsize.Desc(), err) + ch <- NewInvalidMetric(c.rss.Desc(), err) + ch <- NewInvalidMetric(c.startTime.Desc(), err) + ch <- NewInvalidMetric(c.cpuTotal.Desc(), err) + } else { + c.cpuTotal.Set(stat.CPUTime()) + ch <- c.cpuTotal + c.vsize.Set(float64(stat.VirtualMemory())) + ch <- c.vsize + c.rss.Set(float64(stat.ResidentMemory())) + ch <- c.rss + + if startTime, err := stat.StartTime(); err != nil { + ch <- NewInvalidMetric(c.startTime.Desc(), err) + } else { + c.startTime.Set(startTime) + ch <- c.startTime + } + } + + if fds, err := p.FileDescriptorsLen(); err != nil { + ch <- NewInvalidMetric(c.openFDs.Desc(), err) + } else { + c.openFDs.Set(float64(fds)) + ch <- c.openFDs + } + + if limits, err := p.NewLimits(); err != nil { + ch <- NewInvalidMetric(c.maxFDs.Desc(), err) + } else { + c.maxFDs.Set(float64(limits.OpenFiles)) + ch <- c.maxFDs + } +} + +func (c *processCollector) reportCollectErrors(ch chan<- Metric, err error) { + ch <- NewInvalidMetric(c.cpuTotal.Desc(), err) + ch <- NewInvalidMetric(c.openFDs.Desc(), err) + ch <- NewInvalidMetric(c.maxFDs.Desc(), err) + ch <- NewInvalidMetric(c.vsize.Desc(), err) + ch <- NewInvalidMetric(c.rss.Desc(), err) + ch <- NewInvalidMetric(c.startTime.Desc(), err) +} diff --git a/prometheus/process_collector_rest.go b/prometheus/process_collector_rest.go new file mode 100644 index 0000000..1b002e8 --- /dev/null +++ b/prometheus/process_collector_rest.go @@ -0,0 +1,24 @@ +// 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. + +// +build !linux,!plan9,!solaris + +package prometheus + +func processCollectSupported() bool { + return false +} + +func (c *processCollector) processCollect(ch chan<- Metric) { + panic("unreachable") +}