Skip to content

Commit

Permalink
collector: Implement uname collector for FreeBSD (prometheus#1239)
Browse files Browse the repository at this point in the history
* collector: Implement uname collector for FreeBSD

Signed-off-by: David O'Rourke <david.orourke@gmail.com>
  • Loading branch information
phyber authored and SuperQ committed Feb 5, 2019
1 parent 2b81bff commit d442108
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 40 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ The cpufreq metrics now separate the `cpufreq` and `scaling` data based on what
* [ENHANCEMENT] Add Infiniband counters #1120
* [FEATURE] Add a flag to disable exporter metrics #1148
* [FEATURE] Add kstat-based Solaris metrics for boottime, cpu and zfs collectors #1197
* [FEATURE] Add uname collector for FreeBSD #1239

## 0.17.0 / 2018-11-30

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ stat | Exposes various statistics from `/proc/stat`. This includes boot time, fo
textfile | Exposes statistics read from local disk. The `--collector.textfile.directory` flag must be set. | _any_
time | Exposes the current system time. | _any_
timex | Exposes selected adjtimex(2) system call stats. | Linux
uname | Exposes system information as provided by the uname system call. | Linux
uname | Exposes system information as provided by the uname system call. | FreeBSD, Linux
vmstat | Exposes statistics from `/proc/vmstat`. | Linux
xfs | Exposes XFS runtime statistics. | Linux (kernel 4.4+)
zfs | Exposes [ZFS](http://open-zfs.org/) performance statistics. | [Linux](http://zfsonlinux.org/), Solaris
Expand Down
72 changes: 72 additions & 0 deletions collector/uname.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// 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 freebsd linux
// +build !nouname

package collector

import (
"github.com/prometheus/client_golang/prometheus"
)

var unameDesc = prometheus.NewDesc(
prometheus.BuildFQName(namespace, "uname", "info"),
"Labeled system information as provided by the uname system call.",
[]string{
"sysname",
"release",
"version",
"machine",
"nodename",
"domainname",
},
nil,
)

type unameCollector struct{}
type uname struct {
SysName string
Release string
Version string
Machine string
NodeName string
DomainName string
}

func init() {
registerCollector("uname", defaultEnabled, newUnameCollector)
}

// NewUnameCollector returns new unameCollector.
func newUnameCollector() (Collector, error) {
return &unameCollector{}, nil
}

func (c unameCollector) Update(ch chan<- prometheus.Metric) error {
uname, err := getUname()
if err != nil {
return err
}

ch <- prometheus.MustNewConstMetric(unameDesc, prometheus.GaugeValue, 1,
uname.SysName,
uname.Release,
uname.Version,
uname.Machine,
uname.NodeName,
uname.DomainName,
)

return nil
}
57 changes: 57 additions & 0 deletions collector/uname_freebsd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// 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 !nouname

package collector

import (
"bytes"
"strings"

"golang.org/x/sys/unix"
)

func getUname() (uname, error) {
var utsname unix.Utsname
if err := unix.Uname(&utsname); err != nil {
return uname{}, err
}

// We do a little bit of work here to emulate what happens in the Linux
// uname calls since FreeBSD uname doesn't have a Domainname.
nodename := string(utsname.Nodename[:bytes.IndexByte(utsname.Nodename[:], 0)])
split := strings.SplitN(nodename, ".", 2)

// We'll always have at least a single element in the array. We assume this
// is the hostname.
hostname := split[0]

// If we have more than one element, we assume this is the domainname.
// Otherwise leave it to "(none)" like Linux.
domainname := "(none)"
if len(split) > 1 {
domainname = split[1]
}

output := uname{
SysName: string(utsname.Sysname[:bytes.IndexByte(utsname.Sysname[:], 0)]),
Release: string(utsname.Release[:bytes.IndexByte(utsname.Release[:], 0)]),
Version: string(utsname.Version[:bytes.IndexByte(utsname.Version[:], 0)]),
Machine: string(utsname.Machine[:bytes.IndexByte(utsname.Machine[:], 0)]),
NodeName: hostname,
DomainName: domainname,
}

return output, nil
}
52 changes: 13 additions & 39 deletions collector/uname_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,49 +18,23 @@ package collector
import (
"bytes"

"github.com/prometheus/client_golang/prometheus"

"golang.org/x/sys/unix"
)

var unameDesc = prometheus.NewDesc(
prometheus.BuildFQName(namespace, "uname", "info"),
"Labeled system information as provided by the uname system call.",
[]string{
"sysname",
"release",
"version",
"machine",
"nodename",
"domainname",
},
nil,
)

type unameCollector struct{}

func init() {
registerCollector("uname", defaultEnabled, newUnameCollector)
}

// NewUnameCollector returns new unameCollector.
func newUnameCollector() (Collector, error) {
return &unameCollector{}, nil
}
func getUname() (uname, error) {
var utsname unix.Utsname
if err := unix.Uname(&utsname); err != nil {
return uname{}, err
}

func (c unameCollector) Update(ch chan<- prometheus.Metric) error {
var uname unix.Utsname
if err := unix.Uname(&uname); err != nil {
return err
output := uname{
SysName: string(utsname.Sysname[:bytes.IndexByte(utsname.Sysname[:], 0)]),
Release: string(utsname.Release[:bytes.IndexByte(utsname.Release[:], 0)]),
Version: string(utsname.Version[:bytes.IndexByte(utsname.Version[:], 0)]),
Machine: string(utsname.Machine[:bytes.IndexByte(utsname.Machine[:], 0)]),
NodeName: string(utsname.Nodename[:bytes.IndexByte(utsname.Nodename[:], 0)]),
DomainName: string(utsname.Domainname[:bytes.IndexByte(utsname.Domainname[:], 0)]),
}

ch <- prometheus.MustNewConstMetric(unameDesc, prometheus.GaugeValue, 1,
string(uname.Sysname[:bytes.IndexByte(uname.Sysname[:], 0)]),
string(uname.Release[:bytes.IndexByte(uname.Release[:], 0)]),
string(uname.Version[:bytes.IndexByte(uname.Version[:], 0)]),
string(uname.Machine[:bytes.IndexByte(uname.Machine[:], 0)]),
string(uname.Nodename[:bytes.IndexByte(uname.Nodename[:], 0)]),
string(uname.Domainname[:bytes.IndexByte(uname.Domainname[:], 0)]),
)
return nil
return output, nil
}

0 comments on commit d442108

Please sign in to comment.