From 0ff61721d9ded794f3052735912d60a331b9451e Mon Sep 17 00:00:00 2001 From: Iain Learmonth Date: Wed, 2 Nov 2022 13:46:39 +0000 Subject: [PATCH] metrics: refactor app context into base class --- app/metrics.py | 120 ++++++++++++++++++++++++++----------------------- 1 file changed, 65 insertions(+), 55 deletions(-) diff --git a/app/metrics.py b/app/metrics.py index a4c9d72..289373c 100644 --- a/app/metrics.py +++ b/app/metrics.py @@ -1,3 +1,4 @@ +from abc import abstractmethod from typing import Iterator, Optional from flask import Flask @@ -9,72 +10,81 @@ from app.models.automation import Automation, AutomationState class FlaskCollector: - def __init__(self, app=None): - self.app: Optional[Flask] = None + _app: Optional[Flask] - def init_app(self, app): - self.app = app + def __init__(self, app: Optional[Flask] = None) -> None: + self._app = app + def init_app(self, app: Flask) -> None: + self._app = app -class DefinedProxiesCollector: def collect(self) -> Iterator[Metric]: - with self.app.app_context(): - conn = db.engine.connect() + if self._app: + with self._app.app_context(): + return self.collect_in_ctx(self._app) + raise RuntimeError("Flask collector was not initialised with app") + + @abstractmethod + def collect_in_ctx(self, app: Flask) -> Iterator[Metric]: + raise NotImplementedError() + + +class DefinedProxiesCollector(FlaskCollector): + def collect_in_ctx(self, app: Flask) -> Iterator[Metric]: + conn = db.engine.connect() + result = conn.execute(text(""" + SELECT origin.group_id, "group".group_name, proxy.provider, proxy.pool_id, pool.pool_name, + COUNT(proxy.id) FROM proxy, origin, pool, "group" + WHERE proxy.origin_id = origin.id + AND origin.group_id = "group".id + AND proxy.pool_id = pool.id + AND proxy.destroyed IS NULL + GROUP BY origin.group_id, "group".group_name, proxy.provider, proxy.pool_id, pool.pool_name; + """)) + c = GaugeMetricFamily("defined_proxies", "Number of proxies currently defined for deployment", + labels=['group_id', 'group_name', 'provider', 'pool_id', + 'pool_name']) # type: ignore[no-untyped-call] + for row in result: + c.add_metric([str(row[0]), row[1], row[2], str(row[3]), row[4]], + row[5]) # type: ignore[no-untyped-call] + yield c + + +class BlockedProxiesCollector(FlaskCollector): + def collect_in_ctx(self, app: Flask) -> Iterator[Metric]: + with db.engine.connect() as conn: result = conn.execute(text(""" SELECT origin.group_id, "group".group_name, proxy.provider, proxy.pool_id, pool.pool_name, - COUNT(proxy.id) FROM proxy, origin, pool, "group" + proxy.deprecation_reason, COUNT(proxy.id) FROM proxy, origin, pool, "group" WHERE proxy.origin_id = origin.id AND origin.group_id = "group".id AND proxy.pool_id = pool.id - AND proxy.destroyed IS NULL - GROUP BY origin.group_id, "group".group_name, proxy.provider, proxy.pool_id, pool.pool_name; + AND proxy.deprecated IS NOT NULL + GROUP BY origin.group_id, "group".group_name, proxy.provider, proxy.pool_id, pool.pool_name, + proxy.deprecation_reason; """)) - c = GaugeMetricFamily("defined_proxies", "Number of proxies currently defined for deployment", - labels=['group_id', 'group_name', 'provider', 'pool_id', - 'pool_name']) # type: ignore[no-untyped-call] + c = CounterMetricFamily("deprecated_proxies", + "Number of proxies deprecated", + labels=['group_id', 'group_name', 'provider', 'pool_id', 'pool_name', + 'deprecation_reason']) # type: ignore[no-untyped-call] for row in result: - c.add_metric([str(row[0]), row[1], row[2], str(row[3]), row[4]], - row[5]) # type: ignore[no-untyped-call] + c.add_metric([str(row[0]), row[1], row[2], str(row[3]), row[4], row[5]], + row[6]) # type: ignore[no-untyped-call] yield c -class BlockedProxiesCollector: - def collect(self) -> Iterator[Metric]: - with self.app.app_context(): - with db.engine.connect() as conn: - result = conn.execute(text(""" - SELECT origin.group_id, "group".group_name, proxy.provider, proxy.pool_id, pool.pool_name, - proxy.deprecation_reason, COUNT(proxy.id) FROM proxy, origin, pool, "group" - WHERE proxy.origin_id = origin.id - AND origin.group_id = "group".id - AND proxy.pool_id = pool.id - AND proxy.deprecated IS NOT NULL - GROUP BY origin.group_id, "group".group_name, proxy.provider, proxy.pool_id, pool.pool_name, - proxy.deprecation_reason; - """)) - c = CounterMetricFamily("deprecated_proxies", - "Number of proxies deprecated", - labels=['group_id', 'group_name', 'provider', 'pool_id', 'pool_name', - 'deprecation_reason']) # type: ignore[no-untyped-call] - for row in result: - c.add_metric([str(row[0]), row[1], row[2], str(row[3]), row[4], row[5]], - row[6]) # type: ignore[no-untyped-call] - yield c - - -class AutomationCollector: - def collect(self) -> Iterator[Metric]: - with self.app.app_context(): - c = GaugeMetricFamily("automation_state", "The automation state (0: idle, 1: running, 2: error)", - labels=['automation_name']) # type: ignore[no-untyped-call] - automations = Automation.query.all() - for automation in automations: - if automation.short_name in app.config['HIDDEN_AUTOMATIONS']: - continue - if automation.state == AutomationState.IDLE: - c.add_metric([automation.short_name], 0) # type: ignore[no-untyped-call] - elif automation.state == AutomationState.RUNNING: - c.add_metric([automation.short_name], 1) # type: ignore[no-untyped-call] - else: - c.add_metric([automation.short_name], 2) # type: ignore[no-untyped-call] - yield c +class AutomationCollector(FlaskCollector): + def collect_in_ctx(self, app: Flask) -> Iterator[Metric]: + c = GaugeMetricFamily("automation_state", "The automation state (0: idle, 1: running, 2: error)", + labels=['automation_name']) # type: ignore[no-untyped-call] + automations = Automation.query.all() + for automation in automations: + if automation.short_name in app.config['HIDDEN_AUTOMATIONS']: + continue + if automation.state == AutomationState.IDLE: + c.add_metric([automation.short_name], 0) # type: ignore[no-untyped-call] + elif automation.state == AutomationState.RUNNING: + c.add_metric([automation.short_name], 1) # type: ignore[no-untyped-call] + else: + c.add_metric([automation.short_name], 2) # type: ignore[no-untyped-call] + yield c