misc/metrics: Add protocols label to address-specific metrics#2982
Conversation
thomaseizinger
left a comment
There was a problem hiding this comment.
Thanks for working on this!
thomaseizinger
left a comment
There was a problem hiding this comment.
Thanks! A few comments.
This comment was marked as outdated.
This comment was marked as outdated.
Yep, that is almost what we want (see #2758)! :) A leading |
This comment was marked as outdated.
This comment was marked as outdated.
It is actually quite easy. Take a look at the example at the root of the prometheus-client docs: https://docs.rs/prometheus-client/0.18.0/prometheus_client/ If you define a custom Under the hood, prometheus will actually create a separate metric per unique label combination. Labels are just a kind of syntax-sugar on top to allow grouping / filter etc. Plus, (I think) you automatically get a |
Not 100% sure this is what you meant, but here's where I"m at now (this output is from the metrics example). |
Yep that looks correct, thanks! 😊 |
thomaseizinger
left a comment
There was a problem hiding this comment.
A few more comments but otherwise LGTM.
This is almost ready to merge, thank you! :)
thomaseizinger
left a comment
There was a problem hiding this comment.
LGTM!
I'll let @mxinden also have a look as he wrote the original issue!
|
Actually, can you add a changelog entry please? :) |
mxinden
left a comment
There was a problem hiding this comment.
This is already proven useful, see #2289 (comment).
Couple of comments. How about expanding this beyond the two metrics you currently improve?
| pub struct Label { | ||
| address_stack: String, | ||
| } | ||
| impl Label { |
There was a problem hiding this comment.
Why not implement From for Label?
impl From<&Multiaddr> for Label {There was a problem hiding this comment.
I think we had this at some point and I recommended to move away from it. Unless we are actually using From as an abstraction somewhere, using a generic function has downsides in terms of clarity. It also encourages the use of .into at callsites which makes it hard to see, what this is actually being converted into.
There was a problem hiding this comment.
Ah yes, that sounds familiar. I probably resolved & hid the comment when I committed the recommended change, but it's probably still above somewhere.
Personally I think I prefer the From approach in this case - since the struct has such an incredibly narrow usage I don't think there's too much confusion about what into is doing. But of course I'll go with whatever the consensus is.
There was a problem hiding this comment.
From would be nice if we could change the signature of get_or_create to accept an impl Into<S> so you don't have to call .into.
Unfortunately we can't do that without requiring ownership on _every_callsite which would require allocations even though we only need ownership inside the get_or_create function for the first call. Meaning a lot of these allocations would be wasted.
I'd be in favor of not obfuscating what we are converting here:
- Using
.intomakes it hard to find all usages ofLabels. Currently, I have to delete theFromimpl and see where the compiler fails. - I find this:
self.listen_addresses
.get_or_create(&protocol_stack::Labels::new(&listen_addr))
.inc();much clearer to read than this:
self.listen_addresses
.get_or_create(&listen_addr.into())
.inc();The former I can glance over whereas with the latter, my brain stops and is like: "Hang on, into() what?". And I have to recall the function signature of get_or_create, check the type of listen_addr and search for From implementations to understand what is happening here.
- If we ever need more data for the labels,
Fromwould need to be using a tuple at which point we need a constructor anyway. - Out of principle, I think we should not be depending on abstractions (
From), if we don't use them. Traits are only useful in generic code, so unless we can make a function that usesT: Intowhere we can pass a&Multiaddr, I think this doesn't qualify.
| //TODO: remove this trait and tag() and replace with calls to the upstream method | ||
| // once that lands : https://github.com/multiformats/rust-multiaddr/pull/60 | ||
| // In the meantime there is no _ case in the match so one can easily detect mismatch in supported | ||
| // protocols when dependency version changes. | ||
| trait MultiaddrExt { | ||
| fn protocol_stack(&self) -> String; | ||
| } |
There was a problem hiding this comment.
I still need to cut a new release of multiaddr. Sorry for the delay.
thomaseizinger
left a comment
There was a problem hiding this comment.
Lets merge it! Thanks for sticking to this and sorry for the back and forth in the review!
I think clippy still wants to have a word with you, otherwise, I am happy to merge this :)
|
@mxinden Do you want to wait for multiformats/rust-multiaddr#62 and upgrade in this PR right away? |
Yes. I don't think we are in a rush here and thus it's fine to wait. |
mxinden
left a comment
There was a problem hiding this comment.
Thanks for the follow-ups here @John-LittleBearLabs.
Once multiformats/rust-multiaddr#62 is merged, and released and used in this pull request, this is good to go from my end.
|
This pull request has merge conflicts. Could you please resolve them @John-LittleBearLabs? 🙏 |
protocols label to address-specific metrics
The labels are specific to the metric they are used it whereas the `protocol_stack` module is more generic and shouldn't have a dependency on prometheus.
|
I adjusted the PR title and description for a better commit message, plus did some minor tidy up in the code. Based on this comment, I am going ahead in merging this! |
mxinden
left a comment
There was a problem hiding this comment.
Thanks! Good to go from my side.
|
@thomaseizinger in which cases do we manually merge |
|
For those interested, this is now deployed on kademlia-exporter.max-inden.de and the graphs are updated accordingly. |
I am not sure I remember why I merged master in but mergify is only going to update the branch when the PR is already queued for merging. It will only queue it once all checks are passing. One of those is the |
Description
Previously, we would only track the metrics like the number of open connections. With this patch, we extend these metrics with a
protocolslabel that contains a "protocol stack". A protocol stack is a multi-address with all variable parts removed. For example,/ip4/127.0.0.1/tcp/1234turns into/ip4/tcp.Resolves #2758.
Links to any relevant issues
Open Questions
The use of Family appends_totalto the metric name. Is this desirable?Change checklist