mirror of
https://github.com/prometheus/node_exporter.git
synced 2024-11-09 23:24:09 -08:00
Apply v2.0.0 deprecations
* Remove deprecated collectors. * Remove deprecated flags. * Flip rapl label feature flag to true. Signed-off-by: Ben Kochie <superq@gmail.com>
This commit is contained in:
parent
090957658e
commit
a678362345
|
@ -40,10 +40,6 @@ var (
|
|||
diskstatsDeviceExcludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
oldDiskstatsDeviceExclude = kingpin.Flag(
|
||||
"collector.diskstats.ignored-devices",
|
||||
"DEPRECATED: Use collector.diskstats.device-exclude",
|
||||
).Hidden().String()
|
||||
|
||||
diskstatsDeviceInclude = kingpin.Flag("collector.diskstats.device-include", "Regexp of diskstats devices to include (mutually exclusive to device-exclude).").String()
|
||||
|
||||
|
@ -93,15 +89,6 @@ var (
|
|||
)
|
||||
|
||||
func newDiskstatsDeviceFilter(logger *slog.Logger) (deviceFilter, error) {
|
||||
if *oldDiskstatsDeviceExclude != "" {
|
||||
if !diskstatsDeviceExcludeSet {
|
||||
logger.Warn("--collector.diskstats.ignored-devices is DEPRECATED and will be removed in 2.0.0, use --collector.diskstats.device-exclude")
|
||||
*diskstatsDeviceExclude = *oldDiskstatsDeviceExclude
|
||||
} else {
|
||||
return deviceFilter{}, errors.New("--collector.diskstats.ignored-devices and --collector.diskstats.device-exclude are mutually exclusive")
|
||||
}
|
||||
}
|
||||
|
||||
if *diskstatsDeviceExclude != "" && *diskstatsDeviceInclude != "" {
|
||||
return deviceFilter{}, errors.New("device-exclude & device-include are mutually exclusive")
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
package collector
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log/slog"
|
||||
"regexp"
|
||||
|
||||
|
@ -41,10 +40,6 @@ var (
|
|||
mountPointsExcludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
oldMountPointsExcluded = kingpin.Flag(
|
||||
"collector.filesystem.ignored-mount-points",
|
||||
"Regexp of mount points to ignore for filesystem collector.",
|
||||
).Hidden().String()
|
||||
|
||||
fsTypesExcludeSet bool
|
||||
fsTypesExclude = kingpin.Flag(
|
||||
|
@ -54,10 +49,6 @@ var (
|
|||
fsTypesExcludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
oldFSTypesExcluded = kingpin.Flag(
|
||||
"collector.filesystem.ignored-fs-types",
|
||||
"Regexp of filesystem types to ignore for filesystem collector.",
|
||||
).Hidden().String()
|
||||
|
||||
filesystemLabelNames = []string{"device", "mountpoint", "fstype", "device_error"}
|
||||
)
|
||||
|
@ -89,24 +80,6 @@ func init() {
|
|||
|
||||
// NewFilesystemCollector returns a new Collector exposing filesystems stats.
|
||||
func NewFilesystemCollector(logger *slog.Logger) (Collector, error) {
|
||||
if *oldMountPointsExcluded != "" {
|
||||
if !mountPointsExcludeSet {
|
||||
logger.Warn("--collector.filesystem.ignored-mount-points is DEPRECATED and will be removed in 2.0.0, use --collector.filesystem.mount-points-exclude")
|
||||
*mountPointsExclude = *oldMountPointsExcluded
|
||||
} else {
|
||||
return nil, errors.New("--collector.filesystem.ignored-mount-points and --collector.filesystem.mount-points-exclude are mutually exclusive")
|
||||
}
|
||||
}
|
||||
|
||||
if *oldFSTypesExcluded != "" {
|
||||
if !fsTypesExcludeSet {
|
||||
logger.Warn("--collector.filesystem.ignored-fs-types is DEPRECATED and will be removed in 2.0.0, use --collector.filesystem.fs-types-exclude")
|
||||
*fsTypesExclude = *oldFSTypesExcluded
|
||||
} else {
|
||||
return nil, errors.New("--collector.filesystem.ignored-fs-types and --collector.filesystem.fs-types-exclude are mutually exclusive")
|
||||
}
|
||||
}
|
||||
|
||||
subsystem := "filesystem"
|
||||
logger.Info("Parsed flag --collector.filesystem.mount-points-exclude", "flag", *mountPointsExclude)
|
||||
mountPointPattern := regexp.MustCompile(*mountPointsExclude)
|
||||
|
|
|
@ -2912,12 +2912,10 @@ node_qdisc_packets_total{device="wlan0",kind="fq"} 42
|
|||
# TYPE node_qdisc_requeues_total counter
|
||||
node_qdisc_requeues_total{device="eth0",kind="pfifo_fast"} 2
|
||||
node_qdisc_requeues_total{device="wlan0",kind="fq"} 1
|
||||
# HELP node_rapl_core_joules_total Current RAPL core value in joules
|
||||
# TYPE node_rapl_core_joules_total counter
|
||||
node_rapl_core_joules_total{index="0",path="collector/fixtures/sys/class/powercap/intel-rapl:0:0"} 118821.284256
|
||||
# HELP node_rapl_package_joules_total Current RAPL package value in joules
|
||||
# TYPE node_rapl_package_joules_total counter
|
||||
node_rapl_package_joules_total{index="0",path="collector/fixtures/sys/class/powercap/intel-rapl:0"} 240422.366267
|
||||
# HELP node_rapl_joules_total Current RAPL value in joules
|
||||
# TYPE node_rapl_joules_total counter
|
||||
node_rapl_joules_total{index="0",path="collector/fixtures/sys/class/powercap/intel-rapl:0",rapl_zone="package"} 240422.366267
|
||||
node_rapl_joules_total{index="0",path="collector/fixtures/sys/class/powercap/intel-rapl:0:0",rapl_zone="core"} 118821.284256
|
||||
# HELP node_schedstat_running_seconds_total Number of seconds CPU spent running a process.
|
||||
# TYPE node_schedstat_running_seconds_total counter
|
||||
node_schedstat_running_seconds_total{cpu="0"} 2.045936778163039e+06
|
||||
|
|
|
@ -2934,12 +2934,10 @@ node_qdisc_packets_total{device="wlan0",kind="fq"} 42
|
|||
# TYPE node_qdisc_requeues_total counter
|
||||
node_qdisc_requeues_total{device="eth0",kind="pfifo_fast"} 2
|
||||
node_qdisc_requeues_total{device="wlan0",kind="fq"} 1
|
||||
# HELP node_rapl_core_joules_total Current RAPL core value in joules
|
||||
# TYPE node_rapl_core_joules_total counter
|
||||
node_rapl_core_joules_total{index="0",path="collector/fixtures/sys/class/powercap/intel-rapl:0:0"} 118821.284256
|
||||
# HELP node_rapl_package_joules_total Current RAPL package value in joules
|
||||
# TYPE node_rapl_package_joules_total counter
|
||||
node_rapl_package_joules_total{index="0",path="collector/fixtures/sys/class/powercap/intel-rapl:0"} 240422.366267
|
||||
# HELP node_rapl_joules_total Current RAPL value in joules
|
||||
# TYPE node_rapl_joules_total counter
|
||||
node_rapl_joules_total{index="0",path="collector/fixtures/sys/class/powercap/intel-rapl:0",rapl_zone="package"} 240422.366267
|
||||
node_rapl_joules_total{index="0",path="collector/fixtures/sys/class/powercap/intel-rapl:0:0",rapl_zone="core"} 118821.284256
|
||||
# HELP node_schedstat_running_seconds_total Number of seconds CPU spent running a process.
|
||||
# TYPE node_schedstat_running_seconds_total counter
|
||||
node_schedstat_running_seconds_total{cpu="0"} 2.045936778163039e+06
|
||||
|
|
|
@ -31,9 +31,7 @@ import (
|
|||
|
||||
var (
|
||||
netdevDeviceInclude = kingpin.Flag("collector.netdev.device-include", "Regexp of net devices to include (mutually exclusive to device-exclude).").String()
|
||||
oldNetdevDeviceInclude = kingpin.Flag("collector.netdev.device-whitelist", "DEPRECATED: Use collector.netdev.device-include").Hidden().String()
|
||||
netdevDeviceExclude = kingpin.Flag("collector.netdev.device-exclude", "Regexp of net devices to exclude (mutually exclusive to device-include).").String()
|
||||
oldNetdevDeviceExclude = kingpin.Flag("collector.netdev.device-blacklist", "DEPRECATED: Use collector.netdev.device-exclude").Hidden().String()
|
||||
netdevAddressInfo = kingpin.Flag("collector.netdev.address-info", "Collect address-info for every device").Bool()
|
||||
netdevDetailedMetrics = kingpin.Flag("collector.netdev.enable-detailed-metrics", "Use (incompatible) metric names that provide more detailed stats on Linux").Bool()
|
||||
)
|
||||
|
@ -54,24 +52,6 @@ func init() {
|
|||
|
||||
// NewNetDevCollector returns a new Collector exposing network device stats.
|
||||
func NewNetDevCollector(logger *slog.Logger) (Collector, error) {
|
||||
if *oldNetdevDeviceInclude != "" {
|
||||
if *netdevDeviceInclude == "" {
|
||||
logger.Warn("--collector.netdev.device-whitelist is DEPRECATED and will be removed in 2.0.0, use --collector.netdev.device-include")
|
||||
*netdevDeviceInclude = *oldNetdevDeviceInclude
|
||||
} else {
|
||||
return nil, errors.New("--collector.netdev.device-whitelist and --collector.netdev.device-include are mutually exclusive")
|
||||
}
|
||||
}
|
||||
|
||||
if *oldNetdevDeviceExclude != "" {
|
||||
if *netdevDeviceExclude == "" {
|
||||
logger.Warn("--collector.netdev.device-blacklist is DEPRECATED and will be removed in 2.0.0, use --collector.netdev.device-exclude")
|
||||
*netdevDeviceExclude = *oldNetdevDeviceExclude
|
||||
} else {
|
||||
return nil, errors.New("--collector.netdev.device-blacklist and --collector.netdev.device-exclude are mutually exclusive")
|
||||
}
|
||||
}
|
||||
|
||||
if *netdevDeviceExclude != "" && *netdevDeviceInclude != "" {
|
||||
return nil, errors.New("device-exclude & device-include are mutually exclusive")
|
||||
}
|
||||
|
|
177
collector/ntp.go
177
collector/ntp.go
|
@ -1,177 +0,0 @@
|
|||
// 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.
|
||||
|
||||
//go:build !nontp
|
||||
// +build !nontp
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/beevik/ntp"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
hour24 = 24 * time.Hour // `time` does not export `Day` as Day != 24h because of DST
|
||||
ntpSubsystem = "ntp"
|
||||
)
|
||||
|
||||
var (
|
||||
ntpServer = kingpin.Flag("collector.ntp.server", "NTP server to use for ntp collector").Default("127.0.0.1").String()
|
||||
ntpServerPort = kingpin.Flag("collector.ntp.server-port", "UDP port number to connect to on NTP server").Default("123").Int()
|
||||
ntpProtocolVersion = kingpin.Flag("collector.ntp.protocol-version", "NTP protocol version").Default("4").Int()
|
||||
ntpServerIsLocal = kingpin.Flag("collector.ntp.server-is-local", "Certify that collector.ntp.server address is not a public ntp server").Default("false").Bool()
|
||||
ntpIPTTL = kingpin.Flag("collector.ntp.ip-ttl", "IP TTL to use while sending NTP query").Default("1").Int()
|
||||
// 3.46608s ~ 1.5s + PHI * (1 << maxPoll), where 1.5s is MAXDIST from ntp.org, it is 1.0 in RFC5905
|
||||
// max-distance option is used as-is without phi*(1<<poll)
|
||||
ntpMaxDistance = kingpin.Flag("collector.ntp.max-distance", "Max accumulated distance to the root").Default("3.46608s").Duration()
|
||||
ntpOffsetTolerance = kingpin.Flag("collector.ntp.local-offset-tolerance", "Offset between local clock and local ntpd time to tolerate").Default("1ms").Duration()
|
||||
|
||||
leapMidnight time.Time
|
||||
leapMidnightMutex = &sync.Mutex{}
|
||||
)
|
||||
|
||||
type ntpCollector struct {
|
||||
stratum, leap, rtt, offset, reftime, rootDelay, rootDispersion, sanity typedDesc
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func init() {
|
||||
registerCollector("ntp", defaultDisabled, NewNtpCollector)
|
||||
}
|
||||
|
||||
// NewNtpCollector returns a new Collector exposing sanity of local NTP server.
|
||||
// Default definition of "local" is:
|
||||
// - collector.ntp.server address is a loopback address (or collector.ntp.server-is-mine flag is turned on)
|
||||
// - the server is reachable with outgoin IP_TTL = 1
|
||||
func NewNtpCollector(logger *slog.Logger) (Collector, error) {
|
||||
ipaddr := net.ParseIP(*ntpServer)
|
||||
if !*ntpServerIsLocal && (ipaddr == nil || !ipaddr.IsLoopback()) {
|
||||
return nil, fmt.Errorf("only IP address of local NTP server is valid for --collector.ntp.server")
|
||||
}
|
||||
|
||||
if *ntpProtocolVersion < 2 || *ntpProtocolVersion > 4 {
|
||||
return nil, fmt.Errorf("invalid NTP protocol version %d; must be 2, 3, or 4", *ntpProtocolVersion)
|
||||
}
|
||||
|
||||
if *ntpOffsetTolerance < 0 {
|
||||
return nil, fmt.Errorf("offset tolerance must be non-negative")
|
||||
}
|
||||
|
||||
if *ntpServerPort < 1 || *ntpServerPort > 65535 {
|
||||
return nil, fmt.Errorf("invalid NTP port number %d; must be between 1 and 65535 inclusive", *ntpServerPort)
|
||||
}
|
||||
|
||||
logger.Warn("This collector is deprecated and will be removed in the next major version release.")
|
||||
return &ntpCollector{
|
||||
stratum: typedDesc{prometheus.NewDesc(
|
||||
prometheus.BuildFQName(namespace, ntpSubsystem, "stratum"),
|
||||
"NTPD stratum.",
|
||||
nil, nil,
|
||||
), prometheus.GaugeValue},
|
||||
leap: typedDesc{prometheus.NewDesc(
|
||||
prometheus.BuildFQName(namespace, ntpSubsystem, "leap"),
|
||||
"NTPD leap second indicator, 2 bits.",
|
||||
nil, nil,
|
||||
), prometheus.GaugeValue},
|
||||
rtt: typedDesc{prometheus.NewDesc(
|
||||
prometheus.BuildFQName(namespace, ntpSubsystem, "rtt_seconds"),
|
||||
"RTT to NTPD.",
|
||||
nil, nil,
|
||||
), prometheus.GaugeValue},
|
||||
offset: typedDesc{prometheus.NewDesc(
|
||||
prometheus.BuildFQName(namespace, ntpSubsystem, "offset_seconds"),
|
||||
"ClockOffset between NTP and local clock.",
|
||||
nil, nil,
|
||||
), prometheus.GaugeValue},
|
||||
reftime: typedDesc{prometheus.NewDesc(
|
||||
prometheus.BuildFQName(namespace, ntpSubsystem, "reference_timestamp_seconds"),
|
||||
"NTPD ReferenceTime, UNIX timestamp.",
|
||||
nil, nil,
|
||||
), prometheus.GaugeValue},
|
||||
rootDelay: typedDesc{prometheus.NewDesc(
|
||||
prometheus.BuildFQName(namespace, ntpSubsystem, "root_delay_seconds"),
|
||||
"NTPD RootDelay.",
|
||||
nil, nil,
|
||||
), prometheus.GaugeValue},
|
||||
rootDispersion: typedDesc{prometheus.NewDesc(
|
||||
prometheus.BuildFQName(namespace, ntpSubsystem, "root_dispersion_seconds"),
|
||||
"NTPD RootDispersion.",
|
||||
nil, nil,
|
||||
), prometheus.GaugeValue},
|
||||
sanity: typedDesc{prometheus.NewDesc(
|
||||
prometheus.BuildFQName(namespace, ntpSubsystem, "sanity"),
|
||||
"NTPD sanity according to RFC5905 heuristics and configured limits.",
|
||||
nil, nil,
|
||||
), prometheus.GaugeValue},
|
||||
logger: logger,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *ntpCollector) Update(ch chan<- prometheus.Metric) error {
|
||||
resp, err := ntp.QueryWithOptions(*ntpServer, ntp.QueryOptions{
|
||||
Version: *ntpProtocolVersion,
|
||||
TTL: *ntpIPTTL,
|
||||
Timeout: time.Second, // default `ntpdate` timeout
|
||||
Port: *ntpServerPort,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't get SNTP reply: %w", err)
|
||||
}
|
||||
|
||||
ch <- c.stratum.mustNewConstMetric(float64(resp.Stratum))
|
||||
ch <- c.leap.mustNewConstMetric(float64(resp.Leap))
|
||||
ch <- c.rtt.mustNewConstMetric(resp.RTT.Seconds())
|
||||
ch <- c.offset.mustNewConstMetric(resp.ClockOffset.Seconds())
|
||||
if resp.ReferenceTime.Unix() > 0 {
|
||||
// Go Zero is 0001-01-01 00:00:00 UTC
|
||||
// NTP Zero is 1900-01-01 00:00:00 UTC
|
||||
// UNIX Zero is 1970-01-01 00:00:00 UTC
|
||||
// so let's keep ALL ancient `reftime` values as zero
|
||||
ch <- c.reftime.mustNewConstMetric(float64(resp.ReferenceTime.UnixNano()) / 1e9)
|
||||
} else {
|
||||
ch <- c.reftime.mustNewConstMetric(0)
|
||||
}
|
||||
ch <- c.rootDelay.mustNewConstMetric(resp.RootDelay.Seconds())
|
||||
ch <- c.rootDispersion.mustNewConstMetric(resp.RootDispersion.Seconds())
|
||||
|
||||
// Here is SNTP packet sanity check that is exposed to move burden of
|
||||
// configuration from node_exporter user to the developer.
|
||||
|
||||
maxerr := *ntpOffsetTolerance
|
||||
leapMidnightMutex.Lock()
|
||||
if resp.Leap == ntp.LeapAddSecond || resp.Leap == ntp.LeapDelSecond {
|
||||
// state of leapMidnight is cached as leap flag is dropped right after midnight
|
||||
leapMidnight = resp.Time.Truncate(hour24).Add(hour24)
|
||||
}
|
||||
if leapMidnight.Add(-hour24).Before(resp.Time) && resp.Time.Before(leapMidnight.Add(hour24)) {
|
||||
// tolerate leap smearing
|
||||
maxerr += time.Second
|
||||
}
|
||||
leapMidnightMutex.Unlock()
|
||||
|
||||
if resp.Validate() == nil && resp.RootDistance <= *ntpMaxDistance && resp.MinError <= maxerr {
|
||||
ch <- c.sanity.mustNewConstMetric(1)
|
||||
} else {
|
||||
ch <- c.sanity.mustNewConstMetric(0)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -43,9 +43,7 @@ type qdiscStatCollector struct {
|
|||
var (
|
||||
collectorQdisc = kingpin.Flag("collector.qdisc.fixtures", "test fixtures to use for qdisc collector end-to-end testing").Default("").String()
|
||||
collectorQdiscDeviceInclude = kingpin.Flag("collector.qdisc.device-include", "Regexp of qdisc devices to include (mutually exclusive to device-exclude).").String()
|
||||
oldCollectorQdiskDeviceInclude = kingpin.Flag("collector.qdisk.device-include", "DEPRECATED: Use collector.qdisc.device-include").Hidden().String()
|
||||
collectorQdiscDeviceExclude = kingpin.Flag("collector.qdisc.device-exclude", "Regexp of qdisc devices to exclude (mutually exclusive to device-include).").String()
|
||||
oldCollectorQdiskDeviceExclude = kingpin.Flag("collector.qdisk.device-exclude", "DEPRECATED: Use collector.qdisc.device-exclude").Hidden().String()
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -54,24 +52,6 @@ func init() {
|
|||
|
||||
// NewQdiscStatCollector returns a new Collector exposing queuing discipline statistics.
|
||||
func NewQdiscStatCollector(logger *slog.Logger) (Collector, error) {
|
||||
if *oldCollectorQdiskDeviceInclude != "" {
|
||||
if *collectorQdiscDeviceInclude == "" {
|
||||
logger.Warn("--collector.qdisk.device-include is DEPRECATED and will be removed in 2.0.0, use --collector.qdisc.device-include")
|
||||
*collectorQdiscDeviceInclude = *oldCollectorQdiskDeviceInclude
|
||||
} else {
|
||||
return nil, fmt.Errorf("--collector.qdisk.device-include and --collector.qdisc.device-include are mutually exclusive")
|
||||
}
|
||||
}
|
||||
|
||||
if *oldCollectorQdiskDeviceExclude != "" {
|
||||
if *collectorQdiscDeviceExclude == "" {
|
||||
logger.Warn("--collector.qdisk.device-exclude is DEPRECATED and will be removed in 2.0.0, use --collector.qdisc.device-exclude")
|
||||
*collectorQdiscDeviceExclude = *oldCollectorQdiskDeviceExclude
|
||||
} else {
|
||||
return nil, fmt.Errorf("--collector.qdisk.device-exclude and --collector.qdisc.device-exclude are mutually exclusive")
|
||||
}
|
||||
}
|
||||
|
||||
if *collectorQdiscDeviceExclude != "" && *collectorQdiscDeviceInclude != "" {
|
||||
return nil, fmt.Errorf("collector.qdisc.device-include and collector.qdisc.device-exclude are mutaly exclusive")
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ func init() {
|
|||
}
|
||||
|
||||
var (
|
||||
raplZoneLabel = kingpin.Flag("collector.rapl.enable-zone-label", "Enables service unit metric unit_start_time_seconds").Bool()
|
||||
raplZoneLabel = kingpin.Flag("collector.rapl.enable-zone-label", "Enables service unit metric unit_start_time_seconds").Default("true").Bool()
|
||||
)
|
||||
|
||||
// NewRaplCollector returns a new Collector exposing RAPL metrics.
|
||||
|
|
|
@ -1,99 +0,0 @@
|
|||
// 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.
|
||||
|
||||
//go:build !norunit
|
||||
// +build !norunit
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/prometheus-community/go-runit/runit"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"log/slog"
|
||||
)
|
||||
|
||||
var runitServiceDir = kingpin.Flag("collector.runit.servicedir", "Path to runit service directory.").Default("/etc/service").String()
|
||||
|
||||
type runitCollector struct {
|
||||
state typedDesc
|
||||
stateDesired typedDesc
|
||||
stateNormal typedDesc
|
||||
stateTimestamp typedDesc
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func init() {
|
||||
registerCollector("runit", defaultDisabled, NewRunitCollector)
|
||||
}
|
||||
|
||||
// NewRunitCollector returns a new Collector exposing runit statistics.
|
||||
func NewRunitCollector(logger *slog.Logger) (Collector, error) {
|
||||
var (
|
||||
subsystem = "service"
|
||||
constLabels = prometheus.Labels{"supervisor": "runit"}
|
||||
labelNames = []string{"service"}
|
||||
)
|
||||
|
||||
logger.Warn("This collector is deprecated and will be removed in the next major version release.")
|
||||
|
||||
return &runitCollector{
|
||||
state: typedDesc{prometheus.NewDesc(
|
||||
prometheus.BuildFQName(namespace, subsystem, "state"),
|
||||
"State of runit service.",
|
||||
labelNames, constLabels,
|
||||
), prometheus.GaugeValue},
|
||||
stateDesired: typedDesc{prometheus.NewDesc(
|
||||
prometheus.BuildFQName(namespace, subsystem, "desired_state"),
|
||||
"Desired state of runit service.",
|
||||
labelNames, constLabels,
|
||||
), prometheus.GaugeValue},
|
||||
stateNormal: typedDesc{prometheus.NewDesc(
|
||||
prometheus.BuildFQName(namespace, subsystem, "normal_state"),
|
||||
"Normal state of runit service.",
|
||||
labelNames, constLabels,
|
||||
), prometheus.GaugeValue},
|
||||
stateTimestamp: typedDesc{prometheus.NewDesc(
|
||||
prometheus.BuildFQName(namespace, subsystem, "state_last_change_timestamp_seconds"),
|
||||
"Unix timestamp of the last runit service state change.",
|
||||
labelNames, constLabels,
|
||||
), prometheus.GaugeValue},
|
||||
logger: logger,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *runitCollector) Update(ch chan<- prometheus.Metric) error {
|
||||
services, err := runit.GetServices(*runitServiceDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, service := range services {
|
||||
status, err := service.Status()
|
||||
if err != nil {
|
||||
c.logger.Debug("Couldn't get status", "service", service.Name, "err", err)
|
||||
continue
|
||||
}
|
||||
|
||||
c.logger.Debug("duration", "service", service.Name, "status", status.State, "pid", status.Pid, "duration_seconds", status.Duration)
|
||||
ch <- c.state.mustNewConstMetric(float64(status.State), service.Name)
|
||||
ch <- c.stateDesired.mustNewConstMetric(float64(status.Want), service.Name)
|
||||
ch <- c.stateTimestamp.mustNewConstMetric(float64(status.Timestamp.Unix()), service.Name)
|
||||
if status.NormallyUp {
|
||||
ch <- c.stateNormal.mustNewConstMetric(1, service.Name)
|
||||
} else {
|
||||
ch <- c.stateNormal.mustNewConstMetric(0, service.Name)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -1,180 +0,0 @@
|
|||
// 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.
|
||||
|
||||
//go:build !nosupervisord
|
||||
// +build !nosupervisord
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/mattn/go-xmlrpc"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
var (
|
||||
supervisordURL = kingpin.Flag("collector.supervisord.url", "XML RPC endpoint.").Default("http://localhost:9001/RPC2").Envar("SUPERVISORD_URL").String()
|
||||
xrpc *xmlrpc.Client
|
||||
)
|
||||
|
||||
type supervisordCollector struct {
|
||||
upDesc *prometheus.Desc
|
||||
stateDesc *prometheus.Desc
|
||||
exitStatusDesc *prometheus.Desc
|
||||
startTimeDesc *prometheus.Desc
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
func init() {
|
||||
registerCollector("supervisord", defaultDisabled, NewSupervisordCollector)
|
||||
}
|
||||
|
||||
// NewSupervisordCollector returns a new Collector exposing supervisord statistics.
|
||||
func NewSupervisordCollector(logger *slog.Logger) (Collector, error) {
|
||||
var (
|
||||
subsystem = "supervisord"
|
||||
labelNames = []string{"name", "group"}
|
||||
)
|
||||
|
||||
if u, err := url.Parse(*supervisordURL); err == nil && u.Scheme == "unix" {
|
||||
// Fake the URI scheme as http, since net/http.*Transport.roundTrip will complain
|
||||
// about a non-http(s) transport.
|
||||
xrpc = xmlrpc.NewClient("http://unix/RPC2")
|
||||
xrpc.HttpClient.Transport = &http.Transport{
|
||||
DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) {
|
||||
d := net.Dialer{Timeout: 10 * time.Second}
|
||||
return d.DialContext(ctx, "unix", u.Path)
|
||||
},
|
||||
}
|
||||
} else {
|
||||
xrpc = xmlrpc.NewClient(*supervisordURL)
|
||||
}
|
||||
|
||||
logger.Warn("This collector is deprecated and will be removed in the next major version release.")
|
||||
|
||||
return &supervisordCollector{
|
||||
upDesc: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(namespace, subsystem, "up"),
|
||||
"Process Up",
|
||||
labelNames,
|
||||
nil,
|
||||
),
|
||||
stateDesc: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(namespace, subsystem, "state"),
|
||||
"Process State",
|
||||
labelNames,
|
||||
nil,
|
||||
),
|
||||
exitStatusDesc: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(namespace, subsystem, "exit_status"),
|
||||
"Process Exit Status",
|
||||
labelNames,
|
||||
nil,
|
||||
),
|
||||
startTimeDesc: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(namespace, subsystem, "start_time_seconds"),
|
||||
"Process start time",
|
||||
labelNames,
|
||||
nil,
|
||||
),
|
||||
logger: logger,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *supervisordCollector) isRunning(state int) bool {
|
||||
// http://supervisord.org/subprocess.html#process-states
|
||||
const (
|
||||
// STOPPED = 0
|
||||
STARTING = 10
|
||||
RUNNING = 20
|
||||
// BACKOFF = 30
|
||||
STOPPING = 40
|
||||
// EXITED = 100
|
||||
// FATAL = 200
|
||||
// UNKNOWN = 1000
|
||||
)
|
||||
switch state {
|
||||
case STARTING, RUNNING, STOPPING:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *supervisordCollector) Update(ch chan<- prometheus.Metric) error {
|
||||
var info struct {
|
||||
Name string `xmlrpc:"name"`
|
||||
Group string `xmlrpc:"group"`
|
||||
Start int `xmlrpc:"start"`
|
||||
Stop int `xmlrpc:"stop"`
|
||||
Now int `xmlrpc:"now"`
|
||||
State int `xmlrpc:"state"`
|
||||
StateName string `xmlrpc:"statename"`
|
||||
SpawnErr string `xmlrpc:"spanerr"`
|
||||
ExitStatus int `xmlrpc:"exitstatus"`
|
||||
StdoutLogfile string `xmlrcp:"stdout_logfile"`
|
||||
StderrLogfile string `xmlrcp:"stderr_logfile"`
|
||||
PID int `xmlrpc:"pid"`
|
||||
}
|
||||
|
||||
res, err := xrpc.Call("supervisor.getAllProcessInfo")
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to call supervisord: %w", err)
|
||||
}
|
||||
|
||||
for _, p := range res.(xmlrpc.Array) {
|
||||
for k, v := range p.(xmlrpc.Struct) {
|
||||
switch k {
|
||||
case "name":
|
||||
info.Name = v.(string)
|
||||
case "group":
|
||||
info.Group = v.(string)
|
||||
case "start":
|
||||
info.Start = v.(int)
|
||||
case "stop":
|
||||
info.Stop = v.(int)
|
||||
case "now":
|
||||
info.Now = v.(int)
|
||||
case "state":
|
||||
info.State = v.(int)
|
||||
case "statename":
|
||||
info.StateName = v.(string)
|
||||
case "exitstatus":
|
||||
info.ExitStatus = v.(int)
|
||||
case "pid":
|
||||
info.PID = v.(int)
|
||||
}
|
||||
}
|
||||
labels := []string{info.Name, info.Group}
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(c.stateDesc, prometheus.GaugeValue, float64(info.State), labels...)
|
||||
ch <- prometheus.MustNewConstMetric(c.exitStatusDesc, prometheus.GaugeValue, float64(info.ExitStatus), labels...)
|
||||
|
||||
if c.isRunning(info.State) {
|
||||
ch <- prometheus.MustNewConstMetric(c.upDesc, prometheus.GaugeValue, 1, labels...)
|
||||
ch <- prometheus.MustNewConstMetric(c.startTimeDesc, prometheus.CounterValue, float64(info.Start), labels...)
|
||||
} else {
|
||||
ch <- prometheus.MustNewConstMetric(c.upDesc, prometheus.GaugeValue, 0, labels...)
|
||||
}
|
||||
c.logger.Debug("process info", "group", info.Group, "name", info.Name, "state", info.StateName, "pid", info.PID)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -18,7 +18,6 @@ package collector
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"math"
|
||||
|
@ -46,13 +45,11 @@ var (
|
|||
systemdUnitIncludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
oldSystemdUnitInclude = kingpin.Flag("collector.systemd.unit-whitelist", "DEPRECATED: Use --collector.systemd.unit-include").Hidden().String()
|
||||
systemdUnitExcludeSet bool
|
||||
systemdUnitExclude = kingpin.Flag("collector.systemd.unit-exclude", "Regexp of systemd units to exclude. Units must both match include and not match exclude to be included.").Default(".+\\.(automount|device|mount|scope|slice)").PreAction(func(c *kingpin.ParseContext) error {
|
||||
systemdUnitExcludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
oldSystemdUnitExclude = kingpin.Flag("collector.systemd.unit-blacklist", "DEPRECATED: Use collector.systemd.unit-exclude").Hidden().String()
|
||||
systemdPrivate = kingpin.Flag("collector.systemd.private", "Establish a private, direct connection to systemd without dbus (Strongly discouraged since it requires root. For testing purposes only).").Hidden().Bool()
|
||||
enableTaskMetrics = kingpin.Flag("collector.systemd.enable-task-metrics", "Enables service unit tasks metrics unit_tasks_current and unit_tasks_max").Bool()
|
||||
enableRestartsMetrics = kingpin.Flag("collector.systemd.enable-restarts-metrics", "Enables service unit metric service_restart_total").Bool()
|
||||
|
@ -133,22 +130,6 @@ func NewSystemdCollector(logger *slog.Logger) (Collector, error) {
|
|||
prometheus.BuildFQName(namespace, subsystem, "version"),
|
||||
"Detected systemd version", []string{"version"}, nil)
|
||||
|
||||
if *oldSystemdUnitExclude != "" {
|
||||
if !systemdUnitExcludeSet {
|
||||
logger.Warn("--collector.systemd.unit-blacklist is DEPRECATED and will be removed in 2.0.0, use --collector.systemd.unit-exclude")
|
||||
*systemdUnitExclude = *oldSystemdUnitExclude
|
||||
} else {
|
||||
return nil, errors.New("--collector.systemd.unit-blacklist and --collector.systemd.unit-exclude are mutually exclusive")
|
||||
}
|
||||
}
|
||||
if *oldSystemdUnitInclude != "" {
|
||||
if !systemdUnitIncludeSet {
|
||||
logger.Warn("--collector.systemd.unit-whitelist is DEPRECATED and will be removed in 2.0.0, use --collector.systemd.unit-include")
|
||||
*systemdUnitInclude = *oldSystemdUnitInclude
|
||||
} else {
|
||||
return nil, errors.New("--collector.systemd.unit-whitelist and --collector.systemd.unit-include are mutually exclusive")
|
||||
}
|
||||
}
|
||||
logger.Info("Parsed flag --collector.systemd.unit-include", "flag", *systemdUnitInclude)
|
||||
systemdUnitIncludePattern := regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *systemdUnitInclude))
|
||||
logger.Info("Parsed flag --collector.systemd.unit-exclude", "flag", *systemdUnitExclude)
|
||||
|
|
3
go.mod
3
go.mod
|
@ -4,7 +4,6 @@ go 1.22.0
|
|||
|
||||
require (
|
||||
github.com/alecthomas/kingpin/v2 v2.4.0
|
||||
github.com/beevik/ntp v1.4.3
|
||||
github.com/coreos/go-systemd/v22 v22.5.0
|
||||
github.com/dennwc/btrfs v0.0.0-20240418142341-0167142bde7a
|
||||
github.com/ema/qdisc v1.0.0
|
||||
|
@ -15,12 +14,10 @@ require (
|
|||
github.com/josharian/native v1.1.0
|
||||
github.com/jsimonetti/rtnetlink v1.4.2
|
||||
github.com/lufia/iostat v1.2.1
|
||||
github.com/mattn/go-xmlrpc v0.0.3
|
||||
github.com/mdlayher/ethtool v0.2.0
|
||||
github.com/mdlayher/netlink v1.7.2
|
||||
github.com/mdlayher/wifi v0.2.0
|
||||
github.com/opencontainers/selinux v1.11.0
|
||||
github.com/prometheus-community/go-runit v0.1.0
|
||||
github.com/prometheus/client_golang v1.20.3
|
||||
github.com/prometheus/client_model v0.6.1
|
||||
github.com/prometheus/common v0.59.1
|
||||
|
|
6
go.sum
6
go.sum
|
@ -2,8 +2,6 @@ github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjH
|
|||
github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE=
|
||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc=
|
||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
|
||||
github.com/beevik/ntp v1.4.3 h1:PlbTvE5NNy4QHmA4Mg57n7mcFTmr1W1j3gcK7L1lqho=
|
||||
github.com/beevik/ntp v1.4.3/go.mod h1:Unr8Zg+2dRn7d8bHFuehIMSvvUYssHMxW3Q5Nx4RW5Q=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
|
@ -49,8 +47,6 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0
|
|||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/lufia/iostat v1.2.1 h1:tnCdZBIglgxD47RyD55kfWQcJMGzO+1QBziSQfesf2k=
|
||||
github.com/lufia/iostat v1.2.1/go.mod h1:rEPNA0xXgjHQjuI5Cy05sLlS2oRcSlWHRLrvh/AQ+Pg=
|
||||
github.com/mattn/go-xmlrpc v0.0.3 h1:Y6WEMLEsqs3RviBrAa1/7qmbGB7DVD3brZIbqMbQdGY=
|
||||
github.com/mattn/go-xmlrpc v0.0.3/go.mod h1:mqc2dz7tP5x5BKlCahN/n+hs7OSZKJkS9JsHNBRlrxA=
|
||||
github.com/mdlayher/ethtool v0.2.0 h1:akcA4WZVWozzirPASeMq8qgLkxpF3ykftVXwnrMKrhY=
|
||||
github.com/mdlayher/ethtool v0.2.0/go.mod h1:W0pIBrNPK1TslIN4Z9wt1EVbay66Kbvek2z2f29VBfw=
|
||||
github.com/mdlayher/genetlink v1.3.2 h1:KdrNKe+CTu+IbZnm/GVUMXSqBBLqcGpRDa0xkQy56gw=
|
||||
|
@ -71,8 +67,6 @@ github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaL
|
|||
github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus-community/go-runit v0.1.0 h1:uTWEj/Fn2RoLdfg/etSqwzgYNOYPrARx1BHUN052tGA=
|
||||
github.com/prometheus-community/go-runit v0.1.0/go.mod h1:AvJ9Jo3gAFu2lbM4+qfjdpq30FfiLDJZKbQ015u08IQ=
|
||||
github.com/prometheus/client_golang v1.20.3 h1:oPksm4K8B+Vt35tUhw6GbSNSgVlVSBH0qELP/7u83l4=
|
||||
github.com/prometheus/client_golang v1.20.3/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
|
|
Loading…
Reference in a new issue