Skip to content

Commit 8e16308

Browse files
emaoblitorum
authored andcommitted
Add qdisc collector for Linux (prometheus#580)
* Add qdisc collector for Linux This collector gathers basic queueing discipline metrics via netlink, similarly to what `tc -s qdisc show` does. * qdisc collector: nl-specific code moved, names fixed - netlink-specific parts moved to github.com/ema/qdisc - avoid using shortened names - counters renamed into XXX_total * Get rid of parseMessage error checking leftover * Add github.com/ema/qdisc to vendored packages * Update help texts and comments * Add qdisc collector to README file * qdisc collector end-to-end testing * Update qdisc dependency to latest version Update github.com/ema/qdisc dependency to revision 2c7e72d, which includes unit testing. * qdisc collector: rename "iface" label into "device"
1 parent 75f314b commit 8e16308

10 files changed

Lines changed: 440 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ logind | Exposes session counts from [logind](http://www.freedesktop.org/wiki/So
6060
meminfo\_numa | Exposes memory statistics from `/proc/meminfo_numa`. | Linux
6161
mountstats | Exposes filesystem statistics from `/proc/self/mountstats`. Exposes detailed NFS client statistics. | Linux
6262
nfs | Exposes NFS client statistics from `/proc/net/rpc/nfs`. This is the same information as `nfsstat -c`. | Linux
63+
qdisc | Exposes [queuing discipline](https://en.wikipedia.org/wiki/Network_scheduler#Linux_kernel) statistics | Linux
6364
runit | Exposes service status from [runit](http://smarden.org/runit/). | _any_
6465
supervisord | Exposes service status from [supervisord](http://supervisord.org/). | _any_
6566
systemd | Exposes service and system status from [systemd](http://www.freedesktop.org/wiki/Software/systemd/). | Linux

collector/fixtures/e2e-output.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2137,6 +2137,26 @@ node_procs_blocked 0
21372137
# HELP node_procs_running Number of processes in runnable state.
21382138
# TYPE node_procs_running gauge
21392139
node_procs_running 2
2140+
# HELP node_qdisc_bytes_total Number of bytes sent.
2141+
# TYPE node_qdisc_bytes_total counter
2142+
node_qdisc_bytes_total{device="eth0",kind="pfifo_fast"} 83
2143+
node_qdisc_bytes_total{device="wlan0",kind="fq"} 42
2144+
# HELP node_qdisc_drops_total Number of packets dropped.
2145+
# TYPE node_qdisc_drops_total counter
2146+
node_qdisc_drops_total{device="eth0",kind="pfifo_fast"} 0
2147+
node_qdisc_drops_total{device="wlan0",kind="fq"} 1
2148+
# HELP node_qdisc_overlimits_total Number of overlimit packets.
2149+
# TYPE node_qdisc_overlimits_total counter
2150+
node_qdisc_overlimits_total{device="eth0",kind="pfifo_fast"} 0
2151+
node_qdisc_overlimits_total{device="wlan0",kind="fq"} 0
2152+
# HELP node_qdisc_packets_total Number of packets sent.
2153+
# TYPE node_qdisc_packets_total counter
2154+
node_qdisc_packets_total{device="eth0",kind="pfifo_fast"} 83
2155+
node_qdisc_packets_total{device="wlan0",kind="fq"} 42
2156+
# HELP node_qdisc_requeues_total Number of packets dequeued, not transmitted, and requeued.
2157+
# TYPE node_qdisc_requeues_total counter
2158+
node_qdisc_requeues_total{device="eth0",kind="pfifo_fast"} 2
2159+
node_qdisc_requeues_total{device="wlan0",kind="fq"} 1
21402160
# HELP node_scrape_collector_duration_seconds node_exporter: Duration of a collector scrape.
21412161
# TYPE node_scrape_collector_duration_seconds gauge
21422162
# HELP node_scrape_collector_success node_exporter: Whether a collector succeeded.
@@ -2162,6 +2182,7 @@ node_scrape_collector_success{collector="mountstats"} 1
21622182
node_scrape_collector_success{collector="netdev"} 1
21632183
node_scrape_collector_success{collector="netstat"} 1
21642184
node_scrape_collector_success{collector="nfs"} 1
2185+
node_scrape_collector_success{collector="qdisc"} 1
21652186
node_scrape_collector_success{collector="sockstat"} 1
21662187
node_scrape_collector_success{collector="stat"} 1
21672188
node_scrape_collector_success{collector="textfile"} 1
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[
2+
{
3+
"IfaceName": "wlan0",
4+
"Bytes": 42,
5+
"Packets": 42,
6+
"Requeues": 1,
7+
"Kind": "fq",
8+
"Drops": 1
9+
},
10+
{
11+
"IfaceName": "eth0",
12+
"Bytes": 83,
13+
"Packets": 83,
14+
"Requeues": 2,
15+
"Kind": "pfifo_fast"
16+
}
17+
]

collector/qdisc_linux.go

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// Copyright 2017 The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
// +build !noqdisc
15+
16+
package collector
17+
18+
import (
19+
"encoding/json"
20+
"flag"
21+
"io/ioutil"
22+
"path/filepath"
23+
24+
"github.com/ema/qdisc"
25+
"github.com/prometheus/client_golang/prometheus"
26+
)
27+
28+
type qdiscStatCollector struct {
29+
bytes typedDesc
30+
packets typedDesc
31+
drops typedDesc
32+
requeues typedDesc
33+
overlimits typedDesc
34+
}
35+
36+
var (
37+
collectorQdisc = flag.String("collector.qdisc", "", "test fixtures to use for qdisc collector end-to-end testing")
38+
)
39+
40+
func init() {
41+
Factories["qdisc"] = NewQdiscStatCollector
42+
}
43+
44+
func NewQdiscStatCollector() (Collector, error) {
45+
return &qdiscStatCollector{
46+
bytes: typedDesc{prometheus.NewDesc(
47+
prometheus.BuildFQName(Namespace, "qdisc", "bytes_total"),
48+
"Number of bytes sent.",
49+
[]string{"device", "kind"}, nil,
50+
), prometheus.CounterValue},
51+
packets: typedDesc{prometheus.NewDesc(
52+
prometheus.BuildFQName(Namespace, "qdisc", "packets_total"),
53+
"Number of packets sent.",
54+
[]string{"device", "kind"}, nil,
55+
), prometheus.CounterValue},
56+
drops: typedDesc{prometheus.NewDesc(
57+
prometheus.BuildFQName(Namespace, "qdisc", "drops_total"),
58+
"Number of packets dropped.",
59+
[]string{"device", "kind"}, nil,
60+
), prometheus.CounterValue},
61+
requeues: typedDesc{prometheus.NewDesc(
62+
prometheus.BuildFQName(Namespace, "qdisc", "requeues_total"),
63+
"Number of packets dequeued, not transmitted, and requeued.",
64+
[]string{"device", "kind"}, nil,
65+
), prometheus.CounterValue},
66+
overlimits: typedDesc{prometheus.NewDesc(
67+
prometheus.BuildFQName(Namespace, "qdisc", "overlimits_total"),
68+
"Number of overlimit packets.",
69+
[]string{"device", "kind"}, nil,
70+
), prometheus.CounterValue},
71+
}, nil
72+
}
73+
74+
func testQdiscGet(fixtures string) ([]qdisc.QdiscInfo, error) {
75+
var res []qdisc.QdiscInfo
76+
77+
b, err := ioutil.ReadFile(filepath.Join(fixtures, "results.json"))
78+
if err != nil {
79+
return res, err
80+
}
81+
82+
err = json.Unmarshal(b, &res)
83+
return res, err
84+
}
85+
86+
func (c *qdiscStatCollector) Update(ch chan<- prometheus.Metric) error {
87+
var msgs []qdisc.QdiscInfo
88+
var err error
89+
90+
fixtures := *collectorQdisc
91+
92+
if fixtures == "" {
93+
msgs, err = qdisc.Get()
94+
} else {
95+
msgs, err = testQdiscGet(fixtures)
96+
}
97+
98+
if err != nil {
99+
return err
100+
}
101+
102+
for _, msg := range msgs {
103+
// Only report root qdisc information.
104+
if msg.Parent != 0 {
105+
continue
106+
}
107+
108+
ch <- c.bytes.mustNewConstMetric(float64(msg.Bytes), msg.IfaceName, msg.Kind)
109+
ch <- c.packets.mustNewConstMetric(float64(msg.Packets), msg.IfaceName, msg.Kind)
110+
ch <- c.drops.mustNewConstMetric(float64(msg.Drops), msg.IfaceName, msg.Kind)
111+
ch <- c.requeues.mustNewConstMetric(float64(msg.Requeues), msg.IfaceName, msg.Kind)
112+
ch <- c.overlimits.mustNewConstMetric(float64(msg.Overlimits), msg.IfaceName, msg.Kind)
113+
}
114+
115+
return nil
116+
}

end-to-end-test.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ collectors=$(cat << COLLECTORS
2222
netdev
2323
netstat
2424
nfs
25+
qdisc
2526
sockstat
2627
stat
2728
textfile
@@ -76,6 +77,7 @@ fi
7677
-collector.textfile.directory="collector/fixtures/textfile/two_metric_files/" \
7778
-collector.megacli.command="collector/fixtures/megacli" \
7879
-collector.wifi="collector/fixtures/wifi" \
80+
-collector.qdisc="collector/fixtures/qdisc/" \
7981
-web.listen-address "127.0.0.1:${port}" \
8082
-log.level="debug" > "${tmpdir}/node_exporter.log" 2>&1 &
8183

vendor/github.com/ema/qdisc/LICENSE.md

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/ema/qdisc/Makefile

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/ema/qdisc/README.md

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)