|
31 | 31 | Dict, |
32 | 32 | Generic, |
33 | 33 | Iterable, |
| 34 | + List, |
34 | 35 | Mapping, |
35 | 36 | Optional, |
36 | 37 | Sequence, |
|
73 | 74 |
|
74 | 75 | METRICS_PREFIX = "/_synapse/metrics" |
75 | 76 |
|
76 | | -all_gauges: Dict[str, Collector] = {} |
77 | | - |
78 | 77 | HAVE_PROC_SELF_STAT = os.path.exists("/proc/self/stat") |
79 | 78 |
|
80 | 79 | SERVER_NAME_LABEL = "server_name" |
@@ -163,42 +162,47 @@ class LaterGauge(Collector): |
163 | 162 | name: str |
164 | 163 | desc: str |
165 | 164 | labelnames: Optional[StrSequence] = attr.ib(hash=False) |
166 | | - # callback: should either return a value (if there are no labels for this metric), |
167 | | - # or dict mapping from a label tuple to a value |
168 | | - caller: Callable[ |
169 | | - [], Union[Mapping[Tuple[str, ...], Union[int, float]], Union[int, float]] |
170 | | - ] |
| 165 | + # List of callbacks: each callback should either return a value (if there are no |
| 166 | + # labels for this metric), or dict mapping from a label tuple to a value |
| 167 | + _hooks: List[ |
| 168 | + Callable[ |
| 169 | + [], Union[Mapping[Tuple[str, ...], Union[int, float]], Union[int, float]] |
| 170 | + ] |
| 171 | + ] = attr.ib(factory=list, hash=False) |
171 | 172 |
|
172 | 173 | def collect(self) -> Iterable[Metric]: |
173 | 174 | # The decision to add `SERVER_NAME_LABEL` is from the `LaterGauge` usage itself |
174 | 175 | # (we don't enforce it here, one level up). |
175 | 176 | g = GaugeMetricFamily(self.name, self.desc, labels=self.labelnames) # type: ignore[missing-server-name-label] |
176 | 177 |
|
177 | | - try: |
178 | | - calls = self.caller() |
179 | | - except Exception: |
180 | | - logger.exception("Exception running callback for LaterGauge(%s)", self.name) |
181 | | - yield g |
182 | | - return |
| 178 | + for hook in self._hooks: |
| 179 | + try: |
| 180 | + hook_result = hook() |
| 181 | + except Exception: |
| 182 | + logger.exception( |
| 183 | + "Exception running callback for LaterGauge(%s)", self.name |
| 184 | + ) |
| 185 | + yield g |
| 186 | + return |
| 187 | + |
| 188 | + if isinstance(hook_result, (int, float)): |
| 189 | + g.add_metric([], hook_result) |
| 190 | + else: |
| 191 | + for k, v in hook_result.items(): |
| 192 | + g.add_metric(k, v) |
183 | 193 |
|
184 | | - if isinstance(calls, (int, float)): |
185 | | - g.add_metric([], calls) |
186 | | - else: |
187 | | - for k, v in calls.items(): |
188 | | - g.add_metric(k, v) |
| 194 | + yield g |
189 | 195 |
|
190 | | - yield g |
| 196 | + def register_hook( |
| 197 | + self, |
| 198 | + hook: Callable[ |
| 199 | + [], Union[Mapping[Tuple[str, ...], Union[int, float]], Union[int, float]] |
| 200 | + ], |
| 201 | + ) -> None: |
| 202 | + self._hooks.append(hook) |
191 | 203 |
|
192 | 204 | def __attrs_post_init__(self) -> None: |
193 | | - self._register() |
194 | | - |
195 | | - def _register(self) -> None: |
196 | | - if self.name in all_gauges.keys(): |
197 | | - logger.warning("%s already registered, reregistering", self.name) |
198 | | - REGISTRY.unregister(all_gauges.pop(self.name)) |
199 | | - |
200 | 205 | REGISTRY.register(self) |
201 | | - all_gauges[self.name] = self |
202 | 206 |
|
203 | 207 |
|
204 | 208 | # `MetricsEntry` only makes sense when it is a `Protocol`, |
@@ -250,7 +254,7 @@ def __init__( |
250 | 254 | # Protects access to _registrations |
251 | 255 | self._lock = threading.Lock() |
252 | 256 |
|
253 | | - self._register_with_collector() |
| 257 | + REGISTRY.register(self) |
254 | 258 |
|
255 | 259 | def register( |
256 | 260 | self, |
@@ -341,14 +345,6 @@ def collect(self) -> Iterable[Metric]: |
341 | 345 | gauge.add_metric(labels=key, value=getattr(metrics, name)) |
342 | 346 | yield gauge |
343 | 347 |
|
344 | | - def _register_with_collector(self) -> None: |
345 | | - if self.name in all_gauges.keys(): |
346 | | - logger.warning("%s already registered, reregistering", self.name) |
347 | | - REGISTRY.unregister(all_gauges.pop(self.name)) |
348 | | - |
349 | | - REGISTRY.register(self) |
350 | | - all_gauges[self.name] = self |
351 | | - |
352 | 348 |
|
353 | 349 | class GaugeHistogramMetricFamilyWithLabels(GaugeHistogramMetricFamily): |
354 | 350 | """ |
|
0 commit comments