Skip to content

Commit 54eb404

Browse files
committed
support clearing of metric objects for custom collectors
When not doing “direct instrumentation” but rather collecting metrics and thus using the `*MetricFamily`-classes, the general approach seems to be: • Defining a custom collector (that is: a class which is derived from `prometheus_client.registry.Collector`) and at least a `collect`-method. • Create instances of `*MetricFamily` within `collect`. • Add metrics to these via their `add_metric`-method. • Either `return` or `yield` those, for use by the collector registry. The last two steps will be done for every invocation of `collect`. In many cases however, the `*MetricFamily`-objects themselves (that is: their name, documentation, labels, et cetera – basically all the values set via their respective `__init__`-method) except for any metrics added to them will always stay the same and be needlessly re-defined/created on every call to `collect`. This adds `clear`-method to their base class `prometheus_client.metrics_core.Metric`, which simply clears the instance’s `samples`-attribute, so that the `*MetricFamily`-objects that are static in the above sense, can be defined/created for example in `__init__`, and `collect` would merely need to call `clear` for every metric. That could be done either in the beginning of `clear` or perhaps right after `yield`ing the respective object(s) (which would allow Python to reclaim the memory faster, but might perhaps lead to the clearing not happening if an exception is raised. So perhaps the best practise would to do both, clear all in the beginning of `collect` and – for exporters who have so many metrics that this might be an issue – right after `yield`ing. Another idea was, that the clearing could actually be done by the registry after it has collected the metrics, but this seems to rather just limit the freedom and would possibly also not be backwards compatible. This change of course still allows for the “old” usage (that is: re-defining/ creating the `*MetricFamily`-objects in `collect` on every call. Last but not least, currently, `samples` is cleared via the `list.clear`-method rather than simply assigning a new empty list to it. The former is probably considerably slower (if there are many elements in the list), but chosen for now, as `samples` is (per naming conventions) “public” and thus references to it might be held by users. Signed-off-by: Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>
1 parent 6133347 commit 54eb404

1 file changed

Lines changed: 4 additions & 0 deletions

File tree

prometheus_client/metrics_core.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ def add_sample(self, name: str, labels: Dict[str, str], value: float, timestamp:
3737
3838
Internal-only, do not use."""
3939
self.samples.append(Sample(name, labels, value, timestamp, exemplar, native_histogram))
40+
41+
def clear(self) -> None:
42+
"""Clear all samples."""
43+
self.samples.clear()
4044

4145
def __eq__(self, other: object) -> bool:
4246
return (isinstance(other, Metric)

0 commit comments

Comments
 (0)