remove openbsd amd64 cgo

This commit is contained in:
ston1th 2020-06-15 22:46:11 +02:00
commit 625728e2d1
17 changed files with 771 additions and 4 deletions

View file

@ -31,3 +31,4 @@ crossbuild:
- linux/ppc64 - linux/ppc64
- linux/ppc64le - linux/ppc64le
- linux/s390x - linux/s390x
- openbsd/amd64

View file

@ -31,7 +31,7 @@ bcache | Exposes bcache statistics from `/sys/fs/bcache/`. | Linux
bonding | Exposes the number of configured and active slaves of Linux bonding interfaces. | Linux bonding | Exposes the number of configured and active slaves of Linux bonding interfaces. | Linux
boottime | Exposes system boot time derived from the `kern.boottime` sysctl. | Darwin, Dragonfly, FreeBSD, NetBSD, OpenBSD, Solaris boottime | Exposes system boot time derived from the `kern.boottime` sysctl. | Darwin, Dragonfly, FreeBSD, NetBSD, OpenBSD, Solaris
conntrack | Shows conntrack statistics (does nothing if no `/proc/sys/net/netfilter/` present). | Linux conntrack | Shows conntrack statistics (does nothing if no `/proc/sys/net/netfilter/` present). | Linux
cpu | Exposes CPU statistics | Darwin, Dragonfly, FreeBSD, Linux, Solaris cpu | Exposes CPU statistics | Darwin, Dragonfly, FreeBSD, Linux, Solaris, OpenBSD
cpufreq | Exposes CPU frequency statistics | Linux, Solaris cpufreq | Exposes CPU frequency statistics | Linux, Solaris
diskstats | Exposes disk I/O statistics. | Darwin, Linux, OpenBSD diskstats | Exposes disk I/O statistics. | Darwin, Linux, OpenBSD
edac | Exposes error detection and correction statistics. | Linux edac | Exposes error detection and correction statistics. | Linux
@ -120,6 +120,7 @@ qdisc | Exposes [queuing discipline](https://en.wikipedia.org/wiki/Network_sched
runit | Exposes service status from [runit](http://smarden.org/runit/). | _any_ runit | Exposes service status from [runit](http://smarden.org/runit/). | _any_
supervisord | Exposes service status from [supervisord](http://supervisord.org/). | _any_ supervisord | Exposes service status from [supervisord](http://supervisord.org/). | _any_
systemd | Exposes service and system status from [systemd](http://www.freedesktop.org/wiki/Software/systemd/). | Linux systemd | Exposes service and system status from [systemd](http://www.freedesktop.org/wiki/Software/systemd/). | Linux
rcctl | Exposes service status from [rcctl](https://man.openbsd.org/rcctl). | OpenBSD
tcpstat | Exposes TCP connection status information from `/proc/net/tcp` and `/proc/net/tcp6`. (Warning: the current version has potential performance issues in high load situations.) | Linux tcpstat | Exposes TCP connection status information from `/proc/net/tcp` and `/proc/net/tcp6`. (Warning: the current version has potential performance issues in high load situations.) | Linux
wifi | Exposes WiFi device and station statistics. | Linux wifi | Exposes WiFi device and station statistics. | Linux
perf | Exposes perf based metrics (Warning: Metrics are dependent on kernel configuration and settings). | Linux perf | Exposes perf based metrics (Warning: Metrics are dependent on kernel configuration and settings). | Linux

View file

@ -11,7 +11,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// +build freebsd dragonfly openbsd netbsd darwin // +build freebsd dragonfly openbsd,!amd64 netbsd darwin
// +build !noboottime // +build !noboottime
package collector package collector

View file

@ -0,0 +1,61 @@
// Copyright 2018 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 !noboottime
package collector
import (
"github.com/go-kit/kit/log"
"github.com/prometheus/client_golang/prometheus"
"golang.org/x/sys/unix"
"unsafe"
)
type bootTimeCollector struct {
name, description string
logger log.Logger
}
func init() {
registerCollector("boottime", defaultEnabled, newBootTimeCollector)
}
// newBootTimeCollector returns a new Collector exposing system boot time on BSD systems.
func newBootTimeCollector(logger log.Logger) (Collector, error) {
return &bootTimeCollector{
name: "boot_time_seconds",
description: "Unix time of last boot, including microseconds.",
logger: logger,
}, nil
}
// Update pushes boot time onto ch
func (c *bootTimeCollector) Update(ch chan<- prometheus.Metric) error {
raw, err := unix.SysctlRaw("kern.boottime")
if err != nil {
return err
}
tv := *(*unix.Timeval)(unsafe.Pointer(&raw[0]))
v := (float64(tv.Sec) + (float64(tv.Usec) / float64(1000*1000)))
ch <- prometheus.MustNewConstMetric(
prometheus.NewDesc(
prometheus.BuildFQName(namespace, "", c.name),
c.description,
nil, nil,
), prometheus.GaugeValue, v)
return nil
}

24
collector/convert_bsd.go Normal file
View file

@ -0,0 +1,24 @@
// Copyright 2017 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 freebsd dragonfly netbsd darwin openbsd
package collector
func int8ToString(a []int8) string {
b := make([]byte, len(a))
for i, v := range a {
b[i] = byte(v)
}
return string(b)
}

View file

@ -11,6 +11,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// +build openbsd,!amd64
// +build !nocpu // +build !nocpu
package collector package collector

View file

@ -0,0 +1,95 @@
// Copyright 2018 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 !nocpu
package collector
import (
"strconv"
"unsafe"
"github.com/go-kit/kit/log"
"github.com/prometheus/client_golang/prometheus"
"golang.org/x/sys/unix"
)
type clockinfo struct {
hz int32
tick int32
tickadj int32
stathz int32
profhz int32
}
const (
CP_USER = 0
CP_NICE = 1
CP_SYS = 2
CP_SPIN = 3
CP_INTR = 4
CP_IDLE = 5
CPUSTATES = 6
)
type cpuCollector struct {
cpu typedDesc
logger log.Logger
}
func init() {
registerCollector("cpu", defaultEnabled, NewCPUCollector)
}
func NewCPUCollector(logger log.Logger) (Collector, error) {
return &cpuCollector{
cpu: typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue},
logger: logger,
}, nil
}
func (c *cpuCollector) Update(ch chan<- prometheus.Metric) (err error) {
clockb, err := unix.SysctlRaw("kern.clockrate")
if err != nil {
return err
}
clock := *(*clockinfo)(unsafe.Pointer(&clockb[0]))
hz := float64(clock.stathz)
ncpus, err := unix.SysctlUint32("hw.ncpu")
if err != nil {
return err
}
var cpTime [][CPUSTATES]int64
for i := 0; i < int(ncpus); i++ {
cpb, err := unix.SysctlRaw("kern.cp_time2", i)
if err != nil && err != unix.ENODEV {
return err
}
if err != unix.ENODEV {
cpTime = append(cpTime, *(*[CPUSTATES]int64)(unsafe.Pointer(&cpb[0])))
}
}
for cpu, time := range cpTime {
lcpu := strconv.Itoa(cpu)
ch <- c.cpu.mustNewConstMetric(float64(time[CP_USER])/hz, lcpu, "user")
ch <- c.cpu.mustNewConstMetric(float64(time[CP_NICE])/hz, lcpu, "nice")
ch <- c.cpu.mustNewConstMetric(float64(time[CP_SYS])/hz, lcpu, "system")
ch <- c.cpu.mustNewConstMetric(float64(time[CP_SPIN])/hz, lcpu, "spin")
ch <- c.cpu.mustNewConstMetric(float64(time[CP_INTR])/hz, lcpu, "interrupt")
ch <- c.cpu.mustNewConstMetric(float64(time[CP_IDLE])/hz, lcpu, "idle")
}
return err
}

View file

@ -11,6 +11,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// +build openbsd,!amd64
// +build !nodiskstats // +build !nodiskstats
package collector package collector

View file

@ -0,0 +1,89 @@
// Copyright 2019 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 !nodiskstats
package collector
import (
"unsafe"
"github.com/go-kit/kit/log"
"github.com/prometheus/client_golang/prometheus"
"golang.org/x/sys/unix"
)
const (
DS_DISKNAMELEN = 16
)
type DiskStats struct {
Name [DS_DISKNAMELEN]int8
Busy int32
Rxfer uint64
Wxfer uint64
Seek uint64
Rbytes uint64
Wbytes uint64
Attachtime unix.Timeval
Timestamp unix.Timeval
Time unix.Timeval
}
type diskstatsCollector struct {
rxfer typedDesc
rbytes typedDesc
wxfer typedDesc
wbytes typedDesc
time typedDesc
logger log.Logger
}
func init() {
registerCollector("diskstats", defaultEnabled, NewDiskstatsCollector)
}
// NewDiskstatsCollector returns a new Collector exposing disk device stats.
func NewDiskstatsCollector(logger log.Logger) (Collector, error) {
return &diskstatsCollector{
rxfer: typedDesc{readsCompletedDesc, prometheus.CounterValue},
rbytes: typedDesc{readBytesDesc, prometheus.CounterValue},
wxfer: typedDesc{writesCompletedDesc, prometheus.CounterValue},
wbytes: typedDesc{writtenBytesDesc, prometheus.CounterValue},
time: typedDesc{ioTimeSecondsDesc, prometheus.CounterValue},
logger: logger,
}, nil
}
func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) (err error) {
diskstatsb, err := unix.SysctlRaw("hw.diskstats")
if err != nil {
return err
}
ndisks := len(diskstatsb) / int(unsafe.Sizeof(DiskStats{}))
diskstats := *(*[]DiskStats)(unsafe.Pointer(&diskstatsb))
for i := 0; i < ndisks; i++ {
dn := *(*[DS_DISKNAMELEN]int8)(unsafe.Pointer(&diskstats[i].Name[0]))
diskname := int8ToString(dn[:])
ch <- c.rxfer.mustNewConstMetric(float64(diskstats[i].Rxfer), diskname)
ch <- c.rbytes.mustNewConstMetric(float64(diskstats[i].Rbytes), diskname)
ch <- c.wxfer.mustNewConstMetric(float64(diskstats[i].Wxfer), diskname)
ch <- c.wbytes.mustNewConstMetric(float64(diskstats[i].Wbytes), diskname)
time := float64(diskstats[i].Time.Sec) + float64(diskstats[i].Time.Usec)/1000000
ch <- c.time.mustNewConstMetric(time, diskname)
}
return nil
}

View file

@ -11,7 +11,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// +build openbsd darwin,amd64 dragonfly // +build openbsd,!amd64 darwin,amd64 dragonfly
// +build !nofilesystem // +build !nofilesystem
package collector package collector

View file

@ -0,0 +1,77 @@
// 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 openbsd darwin,amd64 dragonfly
// +build !nofilesystem
package collector
import (
"github.com/go-kit/kit/log/level"
"golang.org/x/sys/unix"
)
const (
defIgnoredMountPoints = "^/(dev)($|/)"
defIgnoredFSTypes = "^devfs$"
)
// Expose filesystem fullness.
func (c *filesystemCollector) GetStats() (stats []filesystemStats, err error) {
var mnt []unix.Statfs_t
size, err := unix.Getfsstat(mnt, unix.MNT_NOWAIT)
if err != nil {
return nil, err
}
mnt = make([]unix.Statfs_t, size)
_, err = unix.Getfsstat(mnt, unix.MNT_NOWAIT)
if err != nil {
return nil, err
}
stats = []filesystemStats{}
for _, v := range mnt {
mountpoint := int8ToString(v.F_mntonname[:])
if c.ignoredMountPointsPattern.MatchString(mountpoint) {
level.Debug(c.logger).Log("msg", "Ignoring mount point", "mountpoint", mountpoint)
continue
}
device := int8ToString(v.F_mntfromname[:])
fstype := int8ToString(v.F_fstypename[:])
if c.ignoredFSTypesPattern.MatchString(fstype) {
level.Debug(c.logger).Log("msg", "Ignoring fs type", "type", fstype)
continue
}
var ro float64
if (v.F_flags & unix.MNT_RDONLY) != 0 {
ro = 1
}
stats = append(stats, filesystemStats{
labels: filesystemLabels{
device: device,
mountPoint: mountpoint,
fsType: fstype,
},
size: float64(v.F_blocks) * float64(v.F_bsize),
free: float64(v.F_bfree) * float64(v.F_bsize),
avail: float64(v.F_bavail) * float64(v.F_bsize),
files: float64(v.F_files),
filesFree: float64(v.F_ffree),
ro: ro,
})
}
return stats, nil
}

View file

@ -0,0 +1,113 @@
// 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 !nointerrupts
package collector
import (
"fmt"
"strconv"
"unsafe"
"github.com/prometheus/client_golang/prometheus"
"golang.org/x/sys/unix"
)
const (
KERN_INTRCNT = 63
KERN_INTRCNT_NUM = 1
KERN_INTRCNT_CNT = 2
KERN_INTRCNT_NAME = 3
KERN_INTRCNT_VECTOR = 4
)
func nintr() _C_int {
mib := [3]_C_int{unix.CTL_KERN, KERN_INTRCNT, KERN_INTRCNT_NUM}
buf, err := sysctl(mib[:])
if err != nil {
return 0
}
return *(*_C_int)(unsafe.Pointer(&buf[0]))
}
func intr(idx _C_int) (itr interrupt, err error) {
mib := [4]_C_int{unix.CTL_KERN, KERN_INTRCNT, KERN_INTRCNT_NAME, idx}
buf, err := sysctl(mib[:])
if err != nil {
return
}
dev := *(*[128]byte)(unsafe.Pointer(&buf[0]))
itr.device = string(dev[:])
mib[2] = KERN_INTRCNT_VECTOR
buf, err = sysctl(mib[:])
if err != nil {
return
}
itr.vector = *(*int)(unsafe.Pointer(&buf[0]))
mib[2] = KERN_INTRCNT_CNT
buf, err = sysctl(mib[:])
if err != nil {
return
}
count := *(*uint64)(unsafe.Pointer(&buf[0]))
itr.values = []float64{float64(count)}
return
}
var (
interruptLabelNames = []string{"cpu", "type", "devices"}
)
func (c *interruptsCollector) Update(ch chan<- prometheus.Metric) error {
interrupts, err := getInterrupts()
if err != nil {
return fmt.Errorf("couldn't get interrupts: %s", err)
}
for dev, interrupt := range interrupts {
for cpuNo, value := range interrupt.values {
ch <- c.desc.mustNewConstMetric(
value,
strconv.Itoa(cpuNo),
fmt.Sprintf("%d", interrupt.vector),
dev,
)
}
}
return nil
}
type interrupt struct {
vector int
device string
values []float64
}
func getInterrupts() (map[string]interrupt, error) {
var interrupts = map[string]interrupt{}
n := nintr()
for i := _C_int(0); i < n; i++ {
itr, err := intr(i)
if err != nil {
return nil, err
}
interrupts[itr.device] = itr
}
return interrupts, nil
}

View file

@ -11,7 +11,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// +build openbsd
// +build !nomeminfo // +build !nomeminfo
package collector package collector

View file

@ -0,0 +1,45 @@
// 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 !nomeminfo
package collector
import (
"golang.org/x/sys/unix"
"unsafe"
)
func (c *meminfoCollector) getMemInfo() (map[string]float64, error) {
uvmexpb, err := unix.SysctlRaw("vm.uvmexp")
if err != nil {
return nil, err
}
uvmexp := *(*unix.Uvmexp)(unsafe.Pointer(&uvmexpb[0]))
ps := float64(uvmexp.Pagesize)
// see uvm(9)
return map[string]float64{
"active_bytes": ps * float64(uvmexp.Active),
"cache_bytes": ps * float64(uvmexp.Vnodepages),
"free_bytes": ps * float64(uvmexp.Free),
"inactive_bytes": ps * float64(uvmexp.Inactive),
"size_bytes": ps * float64(uvmexp.Npages),
"swap_size_bytes": ps * float64(uvmexp.Swpages),
"swap_used_bytes": ps * float64(uvmexp.Swpginuse),
"swapped_in_pages_bytes_total": ps * float64(uvmexp.Pgswapin),
"swapped_out_pages_bytes_total": ps * float64(uvmexp.Pgswapout),
"wired_bytes": ps * float64(uvmexp.Wired),
}, nil
}

View file

@ -0,0 +1,79 @@
// 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 !nonetdev
package collector
import (
"github.com/go-kit/kit/log"
"github.com/go-kit/kit/log/level"
"strconv"
"golang.org/x/sys/unix"
"regexp"
"unsafe"
)
func getNetDevStats(ignore *regexp.Regexp, accept *regexp.Regexp, logger log.Logger) (map[string]map[string]string, error) {
netDev := map[string]map[string]string{}
mib := [6]_C_int{unix.CTL_NET, unix.AF_ROUTE, 0, 0, unix.NET_RT_IFLIST, 0}
buf, err := sysctl(mib[:])
if err != nil {
return nil, err
}
n := uintptr(len(buf))
index := uintptr(unsafe.Pointer(&buf[0]))
next := uintptr(0)
var rtm *unix.RtMsghdr
for next = index; next < (index + n); next += uintptr(rtm.Msglen) {
rtm = (*unix.RtMsghdr)(unsafe.Pointer(next))
if rtm.Version != unix.RTM_VERSION || rtm.Type != unix.RTM_IFINFO {
continue
}
ifm := (*unix.IfMsghdr)(unsafe.Pointer(next))
if ifm.Addrs&unix.RTA_IFP == 0 {
continue
}
dl := (*unix.RawSockaddrDatalink)(unsafe.Pointer(next + uintptr(rtm.Hdrlen)))
if dl.Family != unix.AF_LINK {
continue
}
data := ifm.Data
dev := int8ToString(dl.Data[:dl.Nlen])
if ignore != nil && ignore.MatchString(dev) {
level.Debug(logger).Log("msg", "Ignoring device", "device", dev)
continue
}
if accept != nil && !accept.MatchString(dev) {
level.Debug(logger).Log("msg", "Ignoring device", "device", dev)
continue
}
devStats := map[string]string{}
devStats["receive_packets"] = strconv.Itoa(int(data.Ipackets))
devStats["transmit_packets"] = strconv.Itoa(int(data.Opackets))
devStats["receive_errs"] = strconv.Itoa(int(data.Ierrors))
devStats["transmit_errs"] = strconv.Itoa(int(data.Oerrors))
devStats["receive_bytes"] = strconv.Itoa(int(data.Ibytes))
devStats["transmit_bytes"] = strconv.Itoa(int(data.Obytes))
devStats["receive_multicast"] = strconv.Itoa(int(data.Imcasts))
devStats["transmit_multicast"] = strconv.Itoa(int(data.Omcasts))
devStats["receive_drop"] = strconv.Itoa(int(data.Iqdrops))
netDev[dev] = devStats
}
return netDev, nil
}

107
collector/rcctl.go Normal file
View file

@ -0,0 +1,107 @@
// 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 openbsd
// +build !norcctl
package collector
import (
"github.com/go-kit/kit/log"
"github.com/go-kit/kit/log/level"
"github.com/prometheus/client_golang/prometheus"
"os/exec"
"strings"
)
var (
specialSvcs = map[string]struct{}{
"accounting": struct{}{},
"check_quotas": struct{}{},
"ipsec": struct{}{},
"library_aslr": struct{}{},
"multicast": struct{}{},
"pf": struct{}{},
"spamd_black": struct{}{},
}
)
const (
rcctl = "/usr/sbin/rcctl"
rcdir = "/etc/rc.d"
)
type rcctlCollector struct {
state, stateDesired typedDesc
logger log.Logger
}
func init() {
registerCollector("rcctl", defaultDisabled, NewRcctlCollector)
}
// NewRunitCollector returns a new Collector exposing runit statistics.
func NewRcctlCollector(logger log.Logger) (Collector, error) {
var (
subsystem = "service"
constLabels = prometheus.Labels{"supervisor": "rcctl"}
labelNames = []string{"service"}
)
return &rcctlCollector{
state: typedDesc{prometheus.NewDesc(
prometheus.BuildFQName(namespace, subsystem, "state"),
"State of rcctl service.",
labelNames, constLabels,
), prometheus.GaugeValue},
stateDesired: typedDesc{prometheus.NewDesc(
prometheus.BuildFQName(namespace, subsystem, "desired_state"),
"Desired state of rcctl service.",
labelNames, constLabels,
), prometheus.GaugeValue},
logger: logger,
}, nil
}
func (rcctlCollector) check(service string) (status int) {
cmd := exec.Command(rcdir+"/"+service, "check")
err := cmd.Run()
if err != nil {
return
}
if cmd.ProcessState.ExitCode() == 0 {
status = 1
}
return
}
func (c *rcctlCollector) Update(ch chan<- prometheus.Metric) error {
cmd := exec.Command(rcctl, "ls", "on")
on, err := cmd.Output()
if err != nil {
return err
}
for _, s := range strings.Split(string(on), "\n") {
if s == "" {
continue
}
if _, ok := specialSvcs[s]; ok {
continue
}
status := c.check(s)
level.Debug(c.logger).Log("msg", "Current status", "Service", s, "Status", status)
ch <- c.state.mustNewConstMetric(float64(status), s)
ch <- c.stateDesired.mustNewConstMetric(float64(1), s)
}
return nil
}

View file

@ -0,0 +1,74 @@
// 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 collector
import (
"golang.org/x/sys/unix"
"syscall"
"unsafe"
)
// unix._C_int
type _C_int int32
var _zero uintptr
func errnoErr(e syscall.Errno) error {
switch e {
case 0:
return nil
case unix.EAGAIN:
return syscall.EAGAIN
case unix.EINVAL:
return syscall.EINVAL
case unix.ENOENT:
return syscall.ENOENT
}
return e
}
func _sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
var _p0 unsafe.Pointer
if len(mib) > 0 {
_p0 = unsafe.Pointer(&mib[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
for {
_, _, e1 := unix.Syscall6(unix.SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
if e1 != 0 {
err = errnoErr(e1)
}
if err != unix.EINTR {
return
}
}
return
}
func sysctl(mib []_C_int) ([]byte, error) {
n := uintptr(0)
if err := _sysctl(mib, nil, &n, nil, 0); err != nil {
return nil, err
}
if n == 0 {
return nil, nil
}
buf := make([]byte, n)
if err := _sysctl(mib, &buf[0], &n, nil, 0); err != nil {
return nil, err
}
return buf[:n], nil
}