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.
This commit is contained in:
Tobias Schmidt 2015-02-02 14:29:00 -05:00
parent 728064bb68
commit d1d9dee31b
3 changed files with 125 additions and 67 deletions

View File

@ -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 { type processCollector struct {
pid int pid int
@ -33,7 +44,7 @@ func NewProcessCollectorPIDFn(
) *processCollector { ) *processCollector {
c := processCollector{ c := processCollector{
pidFn: pidFn, pidFn: pidFn,
collectFn: noopCollect, collectFn: func(chan<- Metric) {},
cpuTotal: NewCounter(CounterOpts{ cpuTotal: NewCounter(CounterOpts{
Namespace: namespace, Namespace: namespace,
@ -67,9 +78,9 @@ func NewProcessCollectorPIDFn(
}), }),
} }
// Use procfs to export metrics if available. // Set up process metric collection if supported by the runtime.
if _, err := procfs.NewStat(); err == nil { if processCollectSupported() {
c.collectFn = c.procfsCollect c.collectFn = c.processCollect
} }
return &c return &c
@ -89,64 +100,3 @@ func (c *processCollector) Describe(ch chan<- *Desc) {
func (c *processCollector) Collect(ch chan<- Metric) { func (c *processCollector) Collect(ch chan<- Metric) {
c.collectFn(ch) 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)
}

View File

@ -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)
}

View File

@ -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")
}