Skip to content

Commit

Permalink
Use SysctlTimeval for boottime collector on BSD
Browse files Browse the repository at this point in the history
Use SysctlTimeval from the golang.org/x/sys/unix package to
simplify the implementation of the boottime collector for the BSDs and
allows to build it without cgo.

Tested on macOS 11.6, FreeBSD 13 and OpenBSD 7.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
  • Loading branch information
tklauser authored and discordianfish committed Nov 15, 2021
1 parent 85e2023 commit 58ab014
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 100 deletions.
24 changes: 11 additions & 13 deletions collector/boot_time_bsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@
// See the License for the specific language governing permissions and
// limitations under the License.

//go:build (freebsd || dragonfly || (openbsd && !amd64) || netbsd || darwin) && !noboottime
// +build freebsd dragonfly openbsd,!amd64 netbsd darwin
//go:build (freebsd || dragonfly || openbsd || netbsd || darwin) && !noboottime
// +build freebsd dragonfly openbsd netbsd darwin
// +build !noboottime

package collector

import (
"github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus"
"golang.org/x/sys/unix"
)

type bootTimeCollector struct {
boottime bsdSysctl
logger log.Logger
logger log.Logger
}

func init() {
Expand All @@ -34,27 +34,25 @@ func init() {
// newBootTimeCollector returns a new Collector exposing system boot time on BSD systems.
func newBootTimeCollector(logger log.Logger) (Collector, error) {
return &bootTimeCollector{
boottime: bsdSysctl{
name: "boot_time_seconds",
description: "Unix time of last boot, including microseconds.",
mib: "kern.boottime",
dataType: bsdSysctlTypeStructTimeval,
},
logger: logger,
}, nil
}

// Update pushes boot time onto ch
func (c *bootTimeCollector) Update(ch chan<- prometheus.Metric) error {
v, err := c.boottime.Value()
tv, err := unix.SysctlTimeval("kern.boottime")
if err != nil {
return err
}

// This conversion maintains the usec precision. Using the time
// package did not.
v := float64(tv.Sec) + (float64(tv.Usec) / float64(1000*1000))

ch <- prometheus.MustNewConstMetric(
prometheus.NewDesc(
prometheus.BuildFQName(namespace, "", c.boottime.name),
c.boottime.description,
prometheus.BuildFQName(namespace, "", "boot_time_seconds"),
"Unix time of last boot, including microseconds.",
nil, nil,
), prometheus.GaugeValue, v)

Expand Down
62 changes: 0 additions & 62 deletions collector/boot_time_openbsd_amd64.go

This file was deleted.

25 changes: 0 additions & 25 deletions collector/sysctl_bsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ const (
// Default to uint32.
bsdSysctlTypeUint32 bsdSysctlType = iota
bsdSysctlTypeUint64
bsdSysctlTypeStructTimeval
bsdSysctlTypeCLong
)

Expand Down Expand Up @@ -75,8 +74,6 @@ func (b bsdSysctl) Value() (float64, error) {
case bsdSysctlTypeUint64:
tmp64, err = unix.SysctlUint64(b.mib)
tmpf64 = float64(tmp64)
case bsdSysctlTypeStructTimeval:
tmpf64, err = b.getStructTimeval()
case bsdSysctlTypeCLong:
tmpf64, err = b.getCLong()
}
Expand All @@ -92,28 +89,6 @@ func (b bsdSysctl) Value() (float64, error) {
return tmpf64, nil
}

func (b bsdSysctl) getStructTimeval() (float64, error) {
raw, err := unix.SysctlRaw(b.mib)
if err != nil {
return 0, err
}

if len(raw) != int(unsafe.Sizeof(unix.Timeval{})) {
// Shouldn't get here.
return 0, fmt.Errorf(
"length of bytes received from sysctl (%d) does not match expected bytes (%d)",
len(raw),
unsafe.Sizeof(unix.Timeval{}),
)
}

tv := *(*unix.Timeval)(unsafe.Pointer(&raw[0]))

// This conversion maintains the usec precision. Using the time
// package did not.
return (float64(tv.Sec) + (float64(tv.Usec) / float64(1000*1000))), nil
}

func (b bsdSysctl) getCLong() (float64, error) {
raw, err := unix.SysctlRaw(b.mib)
if err != nil {
Expand Down

0 comments on commit 58ab014

Please sign in to comment.