diff --git a/collector.go b/collector.go index 9dd181e..a5b855e 100644 --- a/collector.go +++ b/collector.go @@ -15,6 +15,7 @@ package main import ( + "fmt" "net" probing "github.com/prometheus-community/pro-bing" @@ -28,7 +29,7 @@ const ( ) var ( - labelNames = []string{"ip", "host", "source"} + labelNames = []string{"ip", "host", "source", "tos"} pingResponseTTL = promauto.NewGaugeVec( prometheus.GaugeOpts{ @@ -109,20 +110,21 @@ func (s *SmokepingCollector) updatePingers(pingers []*probing.Pinger, pingRespon ipAddr := pinger.IPAddr().String() host := pinger.Addr() source := pinger.Source - pingResponseDuplicates.WithLabelValues(ipAddr, host, source) - pingResponseSeconds.WithLabelValues(ipAddr, host, source) - pingResponseTTL.WithLabelValues(ipAddr, host, source) - pingSendErrors.WithLabelValues(ipAddr, host, source) + tos := fmt.Sprintf("%d", pinger.TrafficClass()) + pingResponseDuplicates.WithLabelValues(ipAddr, host, source, tos) + pingResponseSeconds.WithLabelValues(ipAddr, host, source, tos) + pingResponseTTL.WithLabelValues(ipAddr, host, source, tos) + pingSendErrors.WithLabelValues(ipAddr, host, source, tos) // Setup handler functions. pinger.OnRecv = func(pkt *probing.Packet) { - pingResponseSeconds.WithLabelValues(pkt.IPAddr.String(), host, source).Observe(pkt.Rtt.Seconds()) - pingResponseTTL.WithLabelValues(pkt.IPAddr.String(), host, source).Set(float64(pkt.TTL)) + pingResponseSeconds.WithLabelValues(pkt.IPAddr.String(), host, source, tos).Observe(pkt.Rtt.Seconds()) + pingResponseTTL.WithLabelValues(pkt.IPAddr.String(), host, source, tos).Set(float64(pkt.TTL)) logger.Debug("Echo reply", "ip_addr", pkt.IPAddr, "bytes_received", pkt.Nbytes, "icmp_seq", pkt.Seq, "time", pkt.Rtt, "ttl", pkt.TTL) } pinger.OnDuplicateRecv = func(pkt *probing.Packet) { - pingResponseDuplicates.WithLabelValues(pkt.IPAddr.String(), host, source).Inc() + pingResponseDuplicates.WithLabelValues(pkt.IPAddr.String(), host, source, tos).Inc() logger.Debug("Echo reply (DUP!)", "ip_addr", pkt.IPAddr, "bytes_received", pkt.Nbytes, "icmp_seq", pkt.Seq, "time", pkt.Rtt, "ttl", pkt.TTL) } @@ -144,7 +146,7 @@ func (s *SmokepingCollector) updatePingers(pingers []*probing.Pinger, pingRespon logger.Debug("Error receiving packet", "error", err) } pinger.OnSendError = func(pkt *probing.Packet, err error) { - pingSendErrors.WithLabelValues(pkt.IPAddr.String(), host, source).Inc() + pingSendErrors.WithLabelValues(pkt.IPAddr.String(), host, source, tos).Inc() logger.Debug("Error sending packet", "ip_addr", pkt.IPAddr, "bytes_received", pkt.Nbytes, "icmp_seq", pkt.Seq, "time", pkt.Rtt, "ttl", pkt.TTL, "error", err) } @@ -167,6 +169,7 @@ func (s *SmokepingCollector) Collect(ch chan<- prometheus.Metric) { stats.IPAddr.String(), stats.Addr, pinger.Source, + fmt.Sprintf("%d", pinger.TrafficClass()), ) } } diff --git a/config/config.go b/config/config.go index 9fe8d64..5df6553 100644 --- a/config/config.go +++ b/config/config.go @@ -95,6 +95,7 @@ type TargetGroup struct { Protocol string `yaml:"protocol,omitempty"` Size int `yaml:"size,omitempty"` Source string `yaml:"source,omitempty"` + ToS uint8 `yaml:"tos,omitempty"` // TODO: Needs work to fix MetricFamily consistency. // Labels map[string]string `yaml:"labels,omitempty"` } diff --git a/main.go b/main.go index 8b2ce25..da65ddb 100644 --- a/main.go +++ b/main.go @@ -129,7 +129,7 @@ func (s *smokePingers) stop() error { return nil } -func (s *smokePingers) prepare(hosts *[]string, interval *time.Duration, privileged *bool, sizeBytes *int) error { +func (s *smokePingers) prepare(hosts *[]string, interval *time.Duration, privileged *bool, sizeBytes *int, tosField *uint8) error { pingers := make([]*probing.Pinger, len(*hosts)) var pinger *probing.Pinger var host string @@ -147,6 +147,7 @@ func (s *smokePingers) prepare(hosts *[]string, interval *time.Duration, privile pinger.RecordRtts = false pinger.SetPrivileged(*privileged) pinger.Size = *sizeBytes + pinger.SetTrafficClass(*tosField) pingers[i] = pinger } @@ -168,6 +169,7 @@ func (s *smokePingers) prepare(hosts *[]string, interval *time.Duration, privile pinger.RecordRtts = false pinger.SetNetwork(targetGroup.Network) pinger.Size = packetSize + pinger.SetTrafficClass(targetGroup.ToS) pinger.Source = targetGroup.Source if targetGroup.Protocol == "icmp" { pinger.SetPrivileged(true) @@ -212,6 +214,7 @@ func main() { interval = kingpin.Flag("ping.interval", "Ping interval duration").Short('i').Default("1s").Duration() privileged = kingpin.Flag("privileged", "Run in privileged ICMP mode").Default("true").Bool() sizeBytes = kingpin.Flag("ping.size", "Ping packet size in bytes").Short('s').Default("56").Int() + tosField = kingpin.Flag("ping.tos", "Ping packet ToS field").Short('O').Default("0x00").Uint8() hosts = HostList(kingpin.Arg("hosts", "List of hosts to ping")) ) @@ -257,7 +260,7 @@ func main() { pingResponseSeconds := newPingResponseHistogram(bucketlist, *factor) prometheus.MustRegister(pingResponseSeconds) - err = smokePingers.prepare(hosts, interval, privileged, sizeBytes) + err = smokePingers.prepare(hosts, interval, privileged, sizeBytes, tosField) if err != nil { logger.Error("Unable to create ping", "err", err) os.Exit(1) @@ -296,7 +299,7 @@ func main() { errCallback(err) continue } - err = smokePingers.prepare(hosts, interval, privileged, sizeBytes) + err = smokePingers.prepare(hosts, interval, privileged, sizeBytes, tosField) if err != nil { logger.Error("Unable to create ping from config", "err", err) errCallback(err) diff --git a/smokeping_prober.yml b/smokeping_prober.yml index aa19a20..2ab029e 100644 --- a/smokeping_prober.yml +++ b/smokeping_prober.yml @@ -7,3 +7,4 @@ targets: protocol: icmp # One of icmp, udp. Default: icmp (Requires privileged operation) size: 56 # Packet data size in bytes. Default 56 (Range: 24 - 65535) source: 127.0.1.1 # Souce IP address to use. Default: None (automatic selection) + tos: 0x00 # Packet ToS field in decimal, hexadecimal or binary format. Default: 0 (Range: 0-255)