From 1ddd12ef4db128330d36ede9697474249b3f469b Mon Sep 17 00:00:00 2001 From: Jan David Mol <mol@astron.nl> Date: Wed, 31 Jul 2024 06:14:39 +0000 Subject: [PATCH] Add django prometheus plugin --- Docker/lofar-ci/Dockerfile_ci_tmss | 2 +- SAS/TMSS/backend/src/CMakeLists.txt | 1 + SAS/TMSS/backend/src/tmss/settings.py | 9 ++++-- .../backend/src/tmss/tmssapp/models/common.py | 29 ++++++++++++++++++- SAS/TMSS/backend/src/tmss/urls.py | 3 +- 5 files changed, 39 insertions(+), 5 deletions(-) diff --git a/Docker/lofar-ci/Dockerfile_ci_tmss b/Docker/lofar-ci/Dockerfile_ci_tmss index baeacab91c6..536de340546 100644 --- a/Docker/lofar-ci/Dockerfile_ci_tmss +++ b/Docker/lofar-ci/Dockerfile_ci_tmss @@ -30,7 +30,7 @@ COPY SAS/TMSS/backend/services/tuna/requirements.txt tmss_tuna.txt RUN pip3 install "setuptools>=62.6" "wheel>=0.40" "pip>=23.1.2" RUN pip3 install astroplan cachetools comet coreapi coverage cx_Oracle cython django-auth-ldap \ django-debug-toolbar django-filter django-json-widget django-jsoneditor django-jsonforms \ - django-material django-property-filter django-viewflow djangorestframework-xml \ + django-material django-property-filter django-prometheus django-viewflow djangorestframework-xml \ drf-flex-fields drf-yasg fabric flask flex gevent graphviz gunicorn h5py isodate \ jsonschema kombu ldap3 lxml Markdown matplotlib mozilla-django-oidc \ mysql-connector-python numpy orjson packaging psycopg2 pygcn pymysql python-dateutil \ diff --git a/SAS/TMSS/backend/src/CMakeLists.txt b/SAS/TMSS/backend/src/CMakeLists.txt index 66279e7a412..5cc606a9831 100644 --- a/SAS/TMSS/backend/src/CMakeLists.txt +++ b/SAS/TMSS/backend/src/CMakeLists.txt @@ -11,6 +11,7 @@ find_python_module(django REQUIRED) find_python_module(rest_framework REQUIRED) # pip3 install djangorestframework find_python_module(ldap REQUIRED) find_python_module(django_filters REQUIRED) # pip3 install django-filter +find_python_module(django_prometheus REQUIRED) # pip3 install django-prometheus find_python_module(django_property_filter REQUIRED) # pip3 install django-property-filter find_python_module(django_auth_ldap REQUIRED) # sudo apt-get install python3-django-python3-ldap python3-django-auth-ldap find_python_module(django_jsonforms REQUIRED) # pip3 install django-jsonforms diff --git a/SAS/TMSS/backend/src/tmss/settings.py b/SAS/TMSS/backend/src/tmss/settings.py index 696e889fdb6..1dda9915872 100644 --- a/SAS/TMSS/backend/src/tmss/settings.py +++ b/SAS/TMSS/backend/src/tmss/settings.py @@ -97,7 +97,8 @@ INSTALLED_APPS = [ 'jsoneditor', 'drf_yasg', 'django_filters', - 'django_property_filter' + 'django_property_filter', + 'django_prometheus', ] try: @@ -111,6 +112,8 @@ except ImportError as e: logger.warning(str(e)) MIDDLEWARE = [ + 'django_prometheus.middleware.PrometheusBeforeMiddleware', + 'django.middleware.gzip.GZipMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', @@ -118,7 +121,9 @@ MIDDLEWARE = [ 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware' + 'django.middleware.clickjacking.XFrameOptionsMiddleware', + + 'django_prometheus.middleware.PrometheusAfterMiddleware', ] def show_debug_toolbar(*args, **kwargs): diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/models/common.py b/SAS/TMSS/backend/src/tmss/tmssapp/models/common.py index 19a1b2f6dc7..d3bb47a627e 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/models/common.py +++ b/SAS/TMSS/backend/src/tmss/tmssapp/models/common.py @@ -11,6 +11,7 @@ from django.db.models import Model, CharField, DateTimeField, IntegerField, Uniq from django.contrib.postgres.fields import ArrayField, JSONField from django.contrib.postgres.indexes import GinIndex from django.db import transaction +from django_prometheus.models import model_inserts, model_updates, model_deletes from lofar.common.json_utils import validate_json_against_its_schema, validate_json_against_schema, add_defaults_to_json_object_for_schema, get_default_json_object_for_schema, raise_on_self_refs, resolved_remote_refs, ref_resolved_url, get_refs, remove_from_schema_cache from lofar.sas.tmss.tmss.exceptions import SchemaValidationException, ObsoleteValidationException, ObsoleteTemplateException from django.urls import reverse as reverse_url @@ -36,6 +37,32 @@ class RefreshFromDbInvalidatesCachedPropertiesMixin: self.__dict__.pop(key, None) +class PrometheusModelOperationsMixin: + """Returns a mixin for models to export counters for lifecycle operations. + + Mimics django_prometheus.models.ExportModelOperationsMixin but auto-derives + the model name from the class.""" + + def __init_subclass__(cls): + # Force create the labels for this model in the counters. This + # is not necessary but it avoids gaps in the aggregated data. + model_inserts.labels(cls.__name__) + model_updates.labels(cls.__name__) + model_deletes.labels(cls.__name__) + + def _do_insert(self, *args, **kwargs): + model_inserts.labels(self.__class__.__name__).inc() + return super()._do_insert(*args, **kwargs) + + def _do_update(self, *args, **kwargs): + model_updates.labels(self.__class__.__name__).inc() + return super()._do_update(*args, **kwargs) + + def delete(self, *args, **kwargs): + model_deletes.labels(self.__class__.__name__).inc() + return super().delete(*args, **kwargs) + + class ProjectPropertyMixin: @cached_property def project(self): # -> Project: @@ -57,7 +84,7 @@ class ProjectPropertyMixin: return None -class BasicCommon(Model): +class BasicCommon(PrometheusModelOperationsMixin, Model): # todo: we cannot use foreign keys in the array here, so we have to keep the Tags table up to date by trigger or so. # todo: we could switch to a manytomany field instead? tags = ArrayField(CharField(max_length=128), size=8, blank=True, help_text='User-defined search keywords for object.', default=list) diff --git a/SAS/TMSS/backend/src/tmss/urls.py b/SAS/TMSS/backend/src/tmss/urls.py index 346e884c185..95090c40355 100644 --- a/SAS/TMSS/backend/src/tmss/urls.py +++ b/SAS/TMSS/backend/src/tmss/urls.py @@ -275,6 +275,7 @@ urlpatterns = [url(r'^api$', RedirectView.as_view(url='/api/')), url(r'^past_schedule', views.public_past_schedule), url(r'', include(frontend_urls)), url(r'^.*', include(frontend_urlpatterns)), + path('', include('django_prometheus.urls')), ] @@ -306,4 +307,4 @@ if isViewflowEnabled(): # Custom error handlers -handler500 = 'lofar.sas.tmss.tmss.tmssapp.views.response500' \ No newline at end of file +handler500 = 'lofar.sas.tmss.tmss.tmssapp.views.response500' -- GitLab