1
0
mirror of https://github.com/quay/quay.git synced 2025-04-18 10:44:06 +03:00
quay/workers/globalpromstats/globalpromstats.py
Kenny Lee Sin Cheong a839a78eb5
chore: allows Quay to run for account recoveries (PROJQUAY-970) (#793)
Adds ACCOUNT_RECOVERY_MODE to allow Quay to run with some core
features disabled. When this is set, the instance should only be used
in order by existing users who hasn't linked their account to an
external login service, after database authentication has been
disabled.
2021-07-07 12:45:24 -04:00

102 lines
3.1 KiB
Python

import logging
import time
from prometheus_client import Gauge
from app import app
from data import model
from data.database import UseThenDisconnect
from util.locking import GlobalLock, LockNotAcquiredException
from util.log import logfile_path
from workers.worker import Worker
from workers.gunicorn_worker import GunicornWorker
logger = logging.getLogger(__name__)
repository_rows = Gauge("quay_repository_rows", "number of repositories in the database")
user_rows = Gauge("quay_user_rows", "number of users in the database")
org_rows = Gauge("quay_org_rows", "number of organizations in the database")
robot_rows = Gauge("quay_robot_rows", "number of robot accounts in the database")
WORKER_FREQUENCY = app.config.get("GLOBAL_PROMETHEUS_STATS_FREQUENCY", 60 * 60)
def get_repository_count():
return model.repository.get_estimated_repository_count()
def get_active_user_count():
return model.user.get_active_user_count()
def get_active_org_count():
return model.organization.get_active_org_count()
def get_robot_count():
return model.user.get_estimated_robot_count()
class GlobalPrometheusStatsWorker(Worker):
"""
Worker which reports global stats (# of users, orgs, repos, etc) to Prometheus periodically.
"""
def __init__(self):
super(GlobalPrometheusStatsWorker, self).__init__()
self.add_operation(self._try_report_stats, WORKER_FREQUENCY)
def _try_report_stats(self):
logger.debug("Attempting to report stats")
try:
with GlobalLock("GLOBAL_PROM_STATS"):
self._report_stats()
except LockNotAcquiredException:
logger.debug("Could not acquire global lock for global prometheus stats")
def _report_stats(self):
logger.debug("Reporting global stats")
with UseThenDisconnect(app.config):
repository_rows.set(get_repository_count())
user_rows.set(get_active_user_count())
org_rows.set(get_active_org_count())
robot_rows.set(get_robot_count())
def create_gunicorn_worker():
"""
follows the gunicorn application factory pattern, enabling
a quay worker to run as a gunicorn worker thread.
this is useful when utilizing gunicorn's hot reload in local dev.
utilizing this method will enforce a 1:1 quay worker to gunicorn worker ratio.
"""
feature_flag = app.config.get("PROMETHEUS_PUSHGATEWAY_URL") is not None
worker = GunicornWorker(__name__, app, GlobalPrometheusStatsWorker(), feature_flag)
return worker
def main():
logging.config.fileConfig(logfile_path(debug=False), disable_existing_loggers=False)
if app.config.get("ACCOUNT_RECOVERY_MODE", False):
logger.debug("Quay running in account recovery mode")
while True:
time.sleep(100000)
if not app.config.get("PROMETHEUS_PUSHGATEWAY_URL"):
logger.debug("Prometheus not enabled; skipping global stats reporting")
while True:
time.sleep(100000)
GlobalLock.configure(app.config)
worker = GlobalPrometheusStatsWorker()
worker.start()
if __name__ == "__main__":
main()