Skip to content

Feat: Add prometheus metrics #320

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/backend/core/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ class CoreConfig(AppConfig):
def ready(self):
"""Register signal handlers when the app is ready."""
# Import signal handlers to register them
from prometheus_client.core import REGISTRY
from .metrics import CustomDBMetricsCollector
REGISTRY.register(CustomDBMetricsCollector())

# pylint: disable=unused-import, import-outside-toplevel
import core.signals # noqa
25 changes: 25 additions & 0 deletions src/backend/core/metrics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from django.apps import apps
from prometheus_client.core import GaugeMetricFamily
from django.db import ProgrammingError, connection
from .models import MessageRecipient
from .enums import MessageDeliveryStatusChoices
from django.db import models

class CustomDBMetricsCollector:

def get_messages_with_status(self):
messages_statuses_count = MessageRecipient.objects.values('delivery_status').annotate(count=models.Count('id'))
gauges = [GaugeMetricFamily(
f"message_{MessageDeliveryStatusChoices(message_status_count['delivery_status'])._label_}_count",
f"Number of messages with status {MessageDeliveryStatusChoices(message_status_count['delivery_status'])._label_}",
value=message_status_count['count']
) for message_status_count in messages_statuses_count]

yield from gauges

def collect(self):
# Only run if apps are ready and model is migrated
if not apps.ready or not apps.is_installed("core"):
return

yield from self.get_messages_with_status()
10 changes: 10 additions & 0 deletions src/backend/messages/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,8 @@ class Base(Configuration):

ENABLE_DOCKERFLOW = values.BooleanValue(default=True)

ENABLE_PROMETHEUS = values.BooleanValue(default=True)

# AI
AI_API_KEY = values.Value(None, environ_name="AI_API_KEY", environ_prefix=None)
AI_BASE_URL = values.Value(None, environ_name="AI_BASE_URL", environ_prefix=None)
Expand Down Expand Up @@ -622,6 +624,14 @@ def __init__(self, *args, **kwargs):
self.INSTALLED_APPS += ["dockerflow.django"]
self.MIDDLEWARE += ["dockerflow.django.middleware.DockerflowMiddleware"]

if self.ENABLE_PROMETHEUS:
self.INSTALLED_APPS += ["django_prometheus"]
self.MIDDLEWARE = [
"django_prometheus.middleware.PrometheusBeforeMiddleware",
*self.MIDDLEWARE,
"django_prometheus.middleware.PrometheusAfterMiddleware",
]

# pylint: disable=invalid-name
@property
def ENVIRONMENT(self):
Expand Down
8 changes: 8 additions & 0 deletions src/backend/messages/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,11 @@
name="redoc-schema",
),
]

if settings.ENABLE_PROMETHEUS:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should the prometheus metrics endpoint be password-protected ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question, we can either have a password protection or a ip-filter to only allow http calls from inside the same subnet

urlpatterns += [
path(
"",
include("django_prometheus.urls"),
),
]
23 changes: 19 additions & 4 deletions src/backend/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/backend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ dependencies = [
"sentry-sdk[django]==2.27.0",
"url-normalize==1.4.3",
"whitenoise==6.8.2",
"django-prometheus (>=2.4.1,<3.0.0)",
]

[project.urls]
Expand Down
Loading