Skip to content

Add qdisc collector for Linux#580

Merged
SuperQ merged 9 commits intoprometheus:masterfrom
ema:qdisc
May 23, 2017
Merged

Add qdisc collector for Linux#580
SuperQ merged 9 commits intoprometheus:masterfrom
ema:qdisc

Conversation

@ema
Copy link
Contributor

@ema ema commented May 12, 2017

This collector gathers basic queueing discipline metrics via netlink,
similarly to what tc -s qdisc show does.

This collector gathers basic queueing discipline metrics via netlink,
similarly to what `tc -s qdisc show` does.
@SuperQ SuperQ self-requested a review May 12, 2017 11:18

type qdiscStatCollector struct {
bytes typedDesc
pkts typedDesc
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to use shortened names here.

[]string{"iface", "kind"}, nil,
), prometheus.CounterValue},
pkts: typedDesc{prometheus.NewDesc(
prometheus.BuildFQName(Namespace, "qdisc", "pkts"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, no need to shorten packets.

func NewQdiscStatCollector() (Collector, error) {
return &qdiscStatCollector{
bytes: typedDesc{prometheus.NewDesc(
prometheus.BuildFQName(Namespace, "qdisc", "bytes"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If these are really counters, we can call them XXXX_total.

@SuperQ
Copy link
Member

SuperQ commented May 12, 2017

@mdlayher Hey, do we have any way to mock netlink so we can have tests and end-to-end testing here?

@mdlayher
Copy link
Contributor

Yep! https://godoc.org/github.com/mdlayher/netlink/nltest

The tests show how to use it: https://github.com/mdlayher/netlink/blob/master/nltest/nltest_test.go.

The idea is that you check the parameters of the incoming message and pass back a message with whatever data you want via this mechanism.

Copy link
Contributor

@mdlayher mdlayher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very cool, and I'm thrilled to see my netlink package being used. Left a few comments and questions regarding netlink specifics.

}

// See if_indextoname(3)
func ifIndexToName(index uint32) string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be able to avoid Cgo by using: https://golang.org/pkg/net/#InterfaceByIndex.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

// See https://tools.ietf.org/html/rfc3549#section-3.1.3
func parseMessage(msg netlink.Message) (Metric, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you're handling netlink messages and the interesting cases that come with that, it might be worth making a separate package like github.com/ema/qdisc and then importing that for node_exporter. I like to promote code reusability wherever possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Flags: netlink.HeaderFlagsRequest | netlink.HeaderFlagsDump,
Type: 38, // RTM_GETQDISC
},
Data: []byte{0},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any particular reason why you have to pass a one byte payload? IIRC this will get padded up to 4 null bytes too. Wouldn't an empty payload work fine for a message with flags request|dump?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With an empty payload I get no response back.

__u32 tcm_info;
};
*/
m.IfaceIdx = nlenc.Uint32(msg.Data[4:8])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll want to do check if len(msg.Data) < 20 or else any short messages will cause a panic. The attribute parsing routines will do bounds checking for you, so no need to check beyond that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

- netlink-specific parts moved to github.com/ema/qdisc
- avoid using shortened names
- counters renamed into XXX_total
@ema
Copy link
Contributor Author

ema commented May 14, 2017

Tests still TBD. Thanks for the quick reviews!

Copy link
Member

@grobie grobie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please vendor your library with govendor.

Also it looks like you're ignoring the error in https://github.com/ema/qdisc/blob/ba575b63dffebb892b58c35c4124efe0ccb5bbbc/get.go#L205. What's the reason?

}

for _, msg := range msgs {
// Only report root qdisc info
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prometheus comment guide line is to write them in full sentences ending on a period.

), prometheus.CounterValue},
drops: typedDesc{prometheus.NewDesc(
prometheus.BuildFQName(Namespace, "qdisc", "drops_total"),
"Number of packets sent.",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The following help texts are copy&pasted and need to be adjusted. Ideally help texts don't just repeat the metric name, but provide actual additional information.

ch <- c.drops.mustNewConstMetric(float64(msg.Drops), msg.IfaceName, msg.Kind)
ch <- c.requeues.mustNewConstMetric(float64(msg.Requeues), msg.IfaceName, msg.Kind)
ch <- c.overlimits.mustNewConstMetric(float64(msg.Overlimits), msg.IfaceName, msg.Kind)
//fmt.Printf("%+v\n", m)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove.

@ema
Copy link
Contributor Author

ema commented May 15, 2017

@grobie: thanks for your review! The error in ema/qdisc was ignored by mistake, that's fixed now.

@grobie
Copy link
Member

grobie commented May 15, 2017

Cool. As @mdlayher said, it would be great to add a test for this collector. Otherwise this looks good enough for me, but I don't really know qdisc.

bytes: typedDesc{prometheus.NewDesc(
prometheus.BuildFQName(Namespace, "qdisc", "bytes_total"),
"Number of bytes sent.",
[]string{"iface", "kind"}, nil,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like most network collectors use the label "device" instead of "iface". Can I get a confirmation from maintainers?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it looks like node_network_... uses device as the label. I would suggest using that for consistency.

@mdlayher
Copy link
Contributor

Also this would need to be mentioned in the README.

ema added 3 commits May 16, 2017 16:30
Update github.com/ema/qdisc dependency to revision 2c7e72d, which
includes unit testing.
@ema
Copy link
Contributor Author

ema commented May 16, 2017

I've added unit tests for qdisc and end-to-end testing to the collector. Let me know if this looks sane! :)

Copy link
Member

@SuperQ SuperQ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@grobie
Copy link
Member

grobie commented May 17, 2017

I don't like the inclusion of test code in the collector itself. In this case, it's probably better to write tests in qdisc_linux_test.go and not use the e2e tests. I can propose something more specific tomorrow when I have more time.

@ema
Copy link
Contributor Author

ema commented May 18, 2017

@grobie the idea of implementing e2e tests that way came from the wifi collector: https://github.com/prometheus/node_exporter/blob/master/collector/wifi_linux.go#L296

I'm open to alternative suggestions, but I'd like to know why you dislike the approach in this case.

Thanks!

@grobie
Copy link
Member

grobie commented May 18, 2017

@ema thanks for the link. I believe runtime code should not include any test code. It's a smell of bad interfaces if that's necessary. This statement also applies to wifi_linux, I wasn't aware of that collector.

Given we already include such testing style in master, I'm fine merging this PR for now. I'll open a new issue/PR to propose a different test setup.

@mdlayher
Copy link
Contributor

@grobie I agree that the current setup isn't ideal, and would be happy to hear any suggestions you might have in mind. Because the collector constructor functions can't accept any arguments, it can be difficult to test them as of now.

@grobie
Copy link
Member

grobie commented May 18, 2017

The "factories" map expects any func() (Collector, error). The new function could take a wifistater as parameter, and we wrap that for the init call. Easiest will be independent go tests, without using e2e for now.

Let's tackle that in a follow up PR.

👍

@ema
Copy link
Contributor Author

ema commented May 23, 2017

@SuperQ, @grobie: anything else left to do here or can the PR be merged? Thanks!

@SuperQ SuperQ merged commit 047003b into prometheus:master May 23, 2017
oblitorum pushed a commit to shatteredsilicon/node_exporter that referenced this pull request Apr 9, 2024
* 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"
tamcore pushed a commit to gitgrave/node_exporter that referenced this pull request Oct 22, 2024
)

* Add commit_stats statistics

---------

Signed-off-by: dongjiang1989 <dongjiang1989@126.com>
Co-authored-by: Ben Kochie <superq@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants