Skip to content

Refactoring and metric wrapper unification (mark 2)#344

Merged
brian-brazil merged 3 commits into
prometheus:masterfrom
valohai:refac3
Nov 21, 2018
Merged

Refactoring and metric wrapper unification (mark 2)#344
brian-brazil merged 3 commits into
prometheus:masterfrom
valohai:refac3

Conversation

@akx

@akx akx commented Nov 13, 2018

Copy link
Copy Markdown
Contributor

This is a rebase of #313 (not my favorite rebase btw; that's why the N refactoring commits in #313 become one big one here) – the comments below are mostly the same.


🔧 This PR refactors the 1200+-line core.py into separate modules for each functionality. This does not affect imports for client code; all the same prometheus_client-provided non-underscored names are re-exported from that file. Some previously underscored names were brought into the light.

✨ Secondly (and this is what prompted me to really do this work), it fixes #210 by removing the factory function magic decorator MetricWrapper; as it was before, say, an invocation Gauge(...) could either return a Gauge object, as you'd expect, or a _LabelWrapper if you'd passed in a list of label names. This tripped up code completion (and tbqh, me :) ) and static analysis.
Instead, the six metric wrappers (Counter, Enum, Gauge, Histogram, Info, Summary) are now plain old classes (though with a slightly arcane diamond-shaped inheritance hierarchy that lets them be used both with and without .labels()).

👓 No significant test code was changed for this (aside from the removal of the __wrapped__ attribute as there is nothing to wrap anymore), so I would say this is backwards API compatible (with the exception of client code that might have done checks like isinstance(x, _LabelWrapper)).


I'm glad to answer any questions and/or modify things as needed! :)

@brian-brazil brian-brazil left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm still not seeing why you need the complex class hierarchy, we only need to support labels() once.

Comment thread prometheus_client/metric_wrappers.py Outdated
Comment thread prometheus_client/metric_wrappers.py Outdated
Comment thread prometheus_client/metric_wrappers.py Outdated
Comment thread prometheus_client/metric_wrappers.py Outdated
Comment thread prometheus_client/metric_wrappers.py Outdated
Comment thread prometheus_client/__init__.py Outdated
Comment thread prometheus_client/values.py Outdated
@nazarewk

Copy link
Copy Markdown

Was about to start a discussion on the topic, then I fount this PR. Absolutely love the initiative and hope this gets merged quickly.

Ease of use is already amazing, but lack of type hints due to decorator functions magic is a nightmare.

@akx

akx commented Nov 16, 2018

Copy link
Copy Markdown
Contributor Author

@brian-brazil:

I'm still not seeing why you need the complex class hierarchy, we only need to support labels() once.

The more complex class hierarchy makes it so that the child metrics don't actually even have a labels() function one might be able to accidentally call.

I can simplify that and raise a runtime error within .labels() if one tries to do x.labels().labels(). Would that be better?

@brian-brazil

Copy link
Copy Markdown
Contributor

I can simplify that and raise a runtime error within .labels() if one tries to do x.labels().labels(). Would that be better?

That sounds good.

akx added 2 commits November 16, 2018 19:38
Signed-off-by: Aarni Koskela <akx@iki.fi>
@akx

akx commented Nov 16, 2018

Copy link
Copy Markdown
Contributor Author

Okay, review comments addressed and the re-refactor pushed as new commits.

I can squash/rebase as needed, but figured this might make reviewing easier.

@akx akx force-pushed the refac3 branch 2 times, most recently from e87bfec to f8b78e8 Compare November 19, 2018 07:20
@brian-brazil

Copy link
Copy Markdown
Contributor

That looks okay. Can you squash sanely?

The LabelWrapper class is also no more. For metric classes where you have set `labelnames`, you can call `.labels()` as before, to acquire a child metric object.

The internal API for child-level metrics did change slightly with this change; if you have a custom metric of some sort, be aware that instead of `_samples`, you should override `_child_samples`.

Fixes prometheus#210

Signed-off-by: Aarni Koskela <akx@iki.fi>
@akx

akx commented Nov 20, 2018

Copy link
Copy Markdown
Contributor Author

@brian-brazil Done deal. Squashed the last 3 commits.

@brian-brazil brian-brazil merged commit 624bb61 into prometheus:master Nov 21, 2018
@brian-brazil

Copy link
Copy Markdown
Contributor

Thanks!

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.

@_MetricWrapper breaks pylint argument checks

3 participants