| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
…asses Closes prometheus#1163 collector/custom.md: Collector protocol section (collect/describe), value vs labels mutual exclusivity note, full constructor and add_metric tables for GaugeMetricFamily, CounterMetricFamily, SummaryMetricFamily, HistogramMetricFamily, and InfoMetricFamily, plus a runnable real-world example. collector/_index.md: constructor parameter tables for ProcessCollector, PlatformCollector, and GCCollector, with exported metrics listed for each. registry/_index.md (new): CollectorRegistry constructor and all public methods (register, unregister, collect, restricted_registry, get_sample_value, set_target_info, get_target_info), the global REGISTRY instance, and examples for isolated registry usage and registry=None. All code examples verified by running them in Python. Signed-off-by: k1chik <107162115+k1chik@users.noreply.github.com>
- GCCollector does not support registry=None on CPython; remove that claim - Remove unused CONTENT_TYPE_LATEST import from registry example - Fix 'value vs labels' section to correctly describe Summary (count_value/sum_value) and Histogram (buckets) Signed-off-by: k1chik <107162115+k1chik@users.noreply.github.com>
There was a problem hiding this comment.
Thanks!
Sorry, something went wrong.
|
Hey. Thanks for improving on the documentation... that really helps a lot, compared to few years ago when I had to basically fiddle out most of these things from the code :-) But one thing: Why the yields in the collect()? I don’t quite get that. Shouldn't collect() return sequences of *MetricFamily objects? You now return only a single one, and there even alternating ones like in: Or maybe you mean this as two independent examples? client_python/docs/content/collector/custom.md Lines 16 to 21 in 482656c There collect() alternates between returning (well yielding) a Gauge and Counter (also not as sequences)? I generally don't quite understand why one would yield here at all. Isn't the reason for custom collectors to start every time fresh (and get rid of all stale metrics, labels, etc.)? Thanks, |
Sorry, something went wrong.
|
Shouldn't do stuff late night... yield of course makes it an iterator o.O Still I wonder, is there any advantage over using that in the current form rather than return? I mean is Python' GC smart enough that it can already clean the objects that have already been yielded and thus give an advantage by reducing e.g. memory use for very large metric sets? In: yield GaugeMetricFamily('my_gauge', 'Help text', value=7)
c = CounterMetricFamily('my_counter_total', 'Help text', labels=['foo'])
c.add_metric(['bar'], 1.7)
c.add_metric(['baz'], 3.8)
yield cI could imagine that it may release the GaugeMetricFamily object early... but c? It still has a reference? In any case it would be nice to have in the docs why generators are used (if it's memory advantages) and how to use them so that this actually works out. :-) |
Sorry, something went wrong.
|
Hi @calestyo, thanks for the read! glad to see you've found the docs useful. And yes, my bad, the code examples are missing the def collect(self): wrapper which makes it unclear what context they're meant to be in, i'll fix that asap. Your GC read is right too, yield GaugeMetricFamily(...) inline like that can be reclaimed as soon as the caller moves on, but c keeps a reference in the generator frame until it's done. The main reason for yield here isn't memory though, it's just that the registry iterates over whatever collect() returns and a generator is cleaner than building a list. For most collectors you'd never notice the difference anyway. I'll open a follow-up PR with both fixes and add a note explaining why generators are used. Thanks again for your feedback.
|
Sorry, something went wrong.
* docs: clarify collect() generator usage and API Reference snippet context Add a note to the collect() protocol section explaining that yield is idiomatic (generator iterates lazily, no state between scrapes) and a preamble to the API Reference section clarifying that code snippets belong inside a collect() method. Follows up on review feedback in #1169. Signed-off-by: k1chik <kkukdia@gmail.com> * docs: split InfoMetricFamily example into two separate blocks The single block with two yield statements looked like one collect() yielding both patterns. Split into labelled prose + code pairs to make clear they are alternatives, not sequential yields. Signed-off-by: k1chik <kkukdia@gmail.com> --------- Signed-off-by: k1chik <kkukdia@gmail.com>
|
Hmm, but if you say memory isn't the main reason, the real one should perhaps be given? And if memory is at least part of the reason, then it might have made sense to explicitly mention that and also explain to people that ideally they should re-use the same identifier so that the GC can kick in. Even perhaps if they have a case where it's reasonable to first collect a few metrics and only yield all of them afterwards, like in: for loopOver in SomeJSONelements:
metric[0].add_metric()
metric[1].add_metric()
for m in metric:
yield m
#... next metric again uses `metric` var
I.e. telling that it's still good to use only one identifier metric here, so that the GC can work |
Sorry, something went wrong.
|
Hi Chris, thanks for the response. Good point on both counts! I'll add a note that memory is at least part of the reason for using yield, and mention that reusing the same identifier helps the GC kick in sooner. PR coming shortly :) |
Sorry, something went wrong.
Addresses follow-up feedback on prometheus#1169 from @calestyo: the existing yield explanation mentioned lazy iteration but omitted memory as a secondary benefit and gave no guidance on variable reuse for GC efficiency. Added a paragraph explaining that yielding inline lets Python reclaim the object as soon as the registry advances, while a named variable stays alive until rebound. Also added a short loop example showing how reusing the same variable name across iterations gives the GC the opportunity to reclaim each object before the next is allocated. Signed-off-by: k1chik <107162115+k1chik@users.noreply.github.com>
| Back | FazBrowse Home | New Git URL |
Closes #1163
Follows the same pattern as #1021 and #1162.
collector/custom.md: Collector protocol section (collect/describe), value vs labels mutual exclusivity note with correct per-type parameter names, full constructor and add_metric tables for GaugeMetricFamily, CounterMetricFamily, SummaryMetricFamily, HistogramMetricFamily, and InfoMetricFamily, plus a runnable real-world example.
collector/_index.md: constructor parameter tables for ProcessCollector, PlatformCollector, and GCCollector, with exported metrics listed for each.
registry/_index.md (new page): CollectorRegistry constructor and all public methods (register, unregister, collect, restricted_registry, get_sample_value, set_target_info, get_target_info), the global REGISTRY instance, and examples for isolated registry usage and registry=None.
All code examples verified by running them in Python.
cc @csmarchbanks