metrics: refactor app context into base class
This commit is contained in:
parent
28c07b7d82
commit
0ff61721d9
1 changed files with 65 additions and 55 deletions
120
app/metrics.py
120
app/metrics.py
|
@ -1,3 +1,4 @@
|
||||||
|
from abc import abstractmethod
|
||||||
from typing import Iterator, Optional
|
from typing import Iterator, Optional
|
||||||
|
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
|
@ -9,72 +10,81 @@ from app.models.automation import Automation, AutomationState
|
||||||
|
|
||||||
|
|
||||||
class FlaskCollector:
|
class FlaskCollector:
|
||||||
def __init__(self, app=None):
|
_app: Optional[Flask]
|
||||||
self.app: Optional[Flask] = None
|
|
||||||
|
|
||||||
def init_app(self, app):
|
def __init__(self, app: Optional[Flask] = None) -> None:
|
||||||
self.app = app
|
self._app = app
|
||||||
|
|
||||||
|
def init_app(self, app: Flask) -> None:
|
||||||
|
self._app = app
|
||||||
|
|
||||||
class DefinedProxiesCollector:
|
|
||||||
def collect(self) -> Iterator[Metric]:
|
def collect(self) -> Iterator[Metric]:
|
||||||
with self.app.app_context():
|
if self._app:
|
||||||
conn = db.engine.connect()
|
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("""
|
result = conn.execute(text("""
|
||||||
SELECT origin.group_id, "group".group_name, proxy.provider, proxy.pool_id, pool.pool_name,
|
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
|
WHERE proxy.origin_id = origin.id
|
||||||
AND origin.group_id = "group".id
|
AND origin.group_id = "group".id
|
||||||
AND proxy.pool_id = pool.id
|
AND proxy.pool_id = pool.id
|
||||||
AND proxy.destroyed IS NULL
|
AND proxy.deprecated IS NOT NULL
|
||||||
GROUP BY origin.group_id, "group".group_name, proxy.provider, proxy.pool_id, pool.pool_name;
|
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",
|
c = CounterMetricFamily("deprecated_proxies",
|
||||||
labels=['group_id', 'group_name', 'provider', 'pool_id',
|
"Number of proxies deprecated",
|
||||||
'pool_name']) # type: ignore[no-untyped-call]
|
labels=['group_id', 'group_name', 'provider', 'pool_id', 'pool_name',
|
||||||
|
'deprecation_reason']) # type: ignore[no-untyped-call]
|
||||||
for row in result:
|
for row in result:
|
||||||
c.add_metric([str(row[0]), row[1], row[2], str(row[3]), row[4]],
|
c.add_metric([str(row[0]), row[1], row[2], str(row[3]), row[4], row[5]],
|
||||||
row[5]) # type: ignore[no-untyped-call]
|
row[6]) # type: ignore[no-untyped-call]
|
||||||
yield c
|
yield c
|
||||||
|
|
||||||
|
|
||||||
class BlockedProxiesCollector:
|
class AutomationCollector(FlaskCollector):
|
||||||
def collect(self) -> Iterator[Metric]:
|
def collect_in_ctx(self, app: Flask) -> Iterator[Metric]:
|
||||||
with self.app.app_context():
|
c = GaugeMetricFamily("automation_state", "The automation state (0: idle, 1: running, 2: error)",
|
||||||
with db.engine.connect() as conn:
|
labels=['automation_name']) # type: ignore[no-untyped-call]
|
||||||
result = conn.execute(text("""
|
automations = Automation.query.all()
|
||||||
SELECT origin.group_id, "group".group_name, proxy.provider, proxy.pool_id, pool.pool_name,
|
for automation in automations:
|
||||||
proxy.deprecation_reason, COUNT(proxy.id) FROM proxy, origin, pool, "group"
|
if automation.short_name in app.config['HIDDEN_AUTOMATIONS']:
|
||||||
WHERE proxy.origin_id = origin.id
|
continue
|
||||||
AND origin.group_id = "group".id
|
if automation.state == AutomationState.IDLE:
|
||||||
AND proxy.pool_id = pool.id
|
c.add_metric([automation.short_name], 0) # type: ignore[no-untyped-call]
|
||||||
AND proxy.deprecated IS NOT NULL
|
elif automation.state == AutomationState.RUNNING:
|
||||||
GROUP BY origin.group_id, "group".group_name, proxy.provider, proxy.pool_id, pool.pool_name,
|
c.add_metric([automation.short_name], 1) # type: ignore[no-untyped-call]
|
||||||
proxy.deprecation_reason;
|
else:
|
||||||
"""))
|
c.add_metric([automation.short_name], 2) # type: ignore[no-untyped-call]
|
||||||
c = CounterMetricFamily("deprecated_proxies",
|
yield c
|
||||||
"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
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue