diff --git a/contrib/common/gunicorn/gunicorn.ini b/contrib/common/gunicorn/gunicorn.ini index ac392e06fe..d78a0e01b2 100644 --- a/contrib/common/gunicorn/gunicorn.ini +++ b/contrib/common/gunicorn/gunicorn.ini @@ -1,6 +1,7 @@ """gunicorn WSGI server configuration.""" import os +from prometheus_client import multiprocess bind = os.environ.get('GUNICORN_BIND', '0.0.0.0:' + os.environ.get('PORT', '8000')) workers = os.environ.get('GUNICORN_WORKERS', 4) @@ -10,3 +11,8 @@ loglevel = os.environ.get('GUNICORN_LOGLEVEL', 'info') user = os.environ.get('GUNICORN_USER', 'root') group = os.environ.get('GUNICORN_GROUP', 'root') timeout = os.environ.get('GUNICORN_TIMEOUT', 30) + + +# Multiprocess mode: https://prometheus.github.io/client_python/multiprocess/ +def child_exit(server, worker): + multiprocess.mark_process_dead(worker.pid) diff --git a/docker/Dockerfile-prod b/docker/Dockerfile-prod index 83f3a817a6..f9617a399a 100644 --- a/docker/Dockerfile-prod +++ b/docker/Dockerfile-prod @@ -22,6 +22,12 @@ RUN apt-get clean && \ apt-get -y install apt-transport-https ca-certificates gnupg2 locales curl && \ rm -rf /var/lib/apt/lists/* + +# Multiprocess mode: https://prometheus.github.io/client_python/multiprocess/ +ENV PROMETHEUS_MULTIPROC_DIR="/tmp/prometheus-metrics" +RUN mkdir -p /tmp/prometheus-metrics + + # set UTF-8 locale RUN locale-gen en_US.UTF-8 ENV LANG en_US.UTF-8 diff --git a/requirements/base.txt b/requirements/base.txt index 123a32a4c1..d4071868bd 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -12,6 +12,7 @@ django-filter==2.0.0 django-import-export==1.2.0 django-money==0.12.3 django-mptt==0.11 +django-prometheus==2.2.0 django-reversion==3.0.5 django-rq==2.0 django-sitetree==1.13.0 diff --git a/src/ralph/settings/prod.py b/src/ralph/settings/prod.py index 33a590ba34..3a55cb4004 100644 --- a/src/ralph/settings/prod.py +++ b/src/ralph/settings/prod.py @@ -68,7 +68,6 @@ 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', } - if bool_from_env('COLLECT_METRICS'): COLLECT_METRICS = True STATSD_HOST = os.environ.get('STATSD_HOST') @@ -86,3 +85,16 @@ STATSD_GRAPHS_PREFIX = os.environ.get( 'STATSD_GRAPHS_PREFIX', 'ralph.graphs' ) + +if bool_from_env('PROMETHEUS_METRICS_ENABLED', True): + PROMETHEUS_METRICS_ENABLED = True + PROMETHEUS_EXPORT_MIGRATIONS = False + MIDDLEWARE = ( + 'django_prometheus.middleware.PrometheusBeforeMiddleware', + ) + MIDDLEWARE + MIDDLEWARE = MIDDLEWARE + ( + 'django_prometheus.middleware.PrometheusAfterMiddleware', + ) + INSTALLED_APPS += ( + 'django_prometheus', + ) diff --git a/src/ralph/settings/test.py b/src/ralph/settings/test.py index 72aa5910ca..950b4e42d2 100644 --- a/src/ralph/settings/test.py +++ b/src/ralph/settings/test.py @@ -82,3 +82,5 @@ def __getitem__(self, item): ENABLE_HERMES_INTEGRATION = True HERMES['ENABLED'] = ENABLE_HERMES_INTEGRATION + +PROMETHEUS_METRICS_ENABLED = False diff --git a/src/ralph/urls/base.py b/src/ralph/urls/base.py index 056a3e72ba..90c8393ed9 100644 --- a/src/ralph/urls/base.py +++ b/src/ralph/urls/base.py @@ -1,5 +1,7 @@ from django.conf import settings from django.conf.urls import include, url +from django.urls import path +from django_prometheus import exports from rest_framework.authtoken import views from sitetree.sitetreeapp import SiteTree # noqa @@ -71,3 +73,12 @@ if getattr(settings, 'ENABLE_HERMES_INTEGRATION', False): urlpatterns += url(r'^hermes/', include('pyhermes.apps.django.urls')), + +if getattr(settings, 'PROMETHEUS_METRICS_ENABLED', False): + urlpatterns += [ + path( + "status/prometheus", + exports.ExportToDjangoView, + name="status-prometheus", + ) + ]