Logo

dev-resources.site

for different kinds of informations.

Scraping Custom Django Metrics with Prometheus

Published at
1/9/2025
Categories
devops
prometheus
monitoring
Author
thecolossus
Categories
3 categories in total
devops
open
prometheus
open
monitoring
open
Author
11 person written this
thecolossus
open
Scraping Custom Django Metrics with Prometheus

In the previous article, we explored setting up a Prometheus instance to scrape generic data(metrics) from our very basic Django application.

Now, we're taking it a step higher: We're going to send custom metrics to Prometheus so we can visualize the data.

To follow along with this article, you need:

  • To have Prometheus installed

  • To understand the basics of Prometheus. For that, refer to the previous entries in this series

  • A basic Django application set up for you to work with. You can refer to Django's official documentation for this.

Using the Python Logging module

Python already has a module for logging various information in an application. We will build on this module to generate our custom logs, which will be exposed to Prometheus for scraping.

In your settings.py add the following lines:

import os # Add this at the top of the file
.
.
.

# Add this at the bottom of the file
LOGGING = {
    'version': 1,  # Specifies the logging configuration schema version
    'disable_existing_loggers': False,  # Keep default Django loggers active
    'formatters': {
        'verbose': {
            'format': '{levelname} {asctime} {module} {message}',
            'style': '{',  # Use `{}` to format log messages
        },
    },
    'handlers': {
        'file': {  # Write logs to a file
            'level': 'INFO',
            'class': 'logging.FileHandler',
            'filename': os.path.join(BASE_DIR, 'app.log'),  # Log file path
            'formatter': 'verbose',  # Use the verbose format
        },
    },
    'loggers': {
        'django': {
            'handlers': ['file'],
            'level': 'INFO',  # Log everything INFO and above
            'propagate': True,  # Pass log messages to parent loggers
        },
    },
}
Enter fullscreen mode Exit fullscreen mode

This defines a log handler that will write information into an app.log file.

To read more about log levels, refer to this documentation

Create Custom Prometheus Log Handler

In a new customlogger.py file, add the following code:

import logging
from prometheus_client import Counter

# Define Prometheus counters for different log levels
log_counters = {
    'INFO': Counter('django_log_info_total', 'Total number of INFO logs'),
    'WARNING': Counter('django_log_warning_total', 'Total number of WARNING logs'),
    'ERROR': Counter('django_log_error_total', 'Total number of ERROR logs'),
}

class PrometheusLogHandler(logging.Handler):  # Custom log handler
    def emit(self, record):
        log_level = record.levelname  # Get the log level (INFO, WARNING, ERROR)
        if log_level in log_counters:  # Check if we have a counter for this level
            log_counters[log_level].inc()  # Increment the counter
Enter fullscreen mode Exit fullscreen mode

Expose Metrics to Prometheus

We will create a Django endpoint(Django view) for Prometheus to access the data from.

app/views.py:

from prometheus_client import generate_latest
from django.http import HttpResponse

def metrics_view(request):
    """Expose Prometheus metrics, including log counters."""
    metrics = generate_latest()  # Generate all Prometheus metrics
    return HttpResponse(metrics, content_type='text/plain')
Enter fullscreen mode Exit fullscreen mode

yourdjangoproject/urls.py:

from django.contrib import admin
from django.urls import path, include
from demo.views import metrics_view

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('django_prometheus.urls')),
    path('metrics/', metrics_view, name='metrics'),
]
Enter fullscreen mode Exit fullscreen mode

prometheus.yml:

scrape_configs:
  - job_name: 'django_app'  # A name for this job
    static_configs:
      - targets: ['localhost:8000']  # Django app's address
Enter fullscreen mode Exit fullscreen mode

This will configure Prometheus to look for data at the address localhost:8000. Alternatively, you can use 127.0.0.1:8000

Finally, we update our settings.py to include the Custom handler we created:

from demo.customlogger import PrometheusLogHandler
.
.
LOGGING = {
    'version': 1,  # Specifies the logging configuration schema version
    'disable_existing_loggers': False,  # Keep default Django loggers active
    'formatters': {
        'verbose': {
            'format': '{levelname} {asctime} {module} {message}',
            'style': '{',  # Use `{}` to format log messages
        },
    },
    'handlers': {
        'file': {  # Write logs to a file
            'level': 'INFO',
            'class': 'logging.FileHandler',
            'filename': os.path.join(BASE_DIR, 'app.log'),  # Log file path
            'formatter': 'verbose',  # Use the verbose format
        },
        'prometheus': {  # Send logs to Prometheus (custom handler)
            'level': 'INFO',
            'class': 'my_app.log_handlers.PrometheusLogHandler',  # Our custom handler
        },
    },
    'loggers': {
        'django': {
            'handlers': ['file', 'prometheus'],  # Use both file and Prometheus handlers
            'level': 'INFO',  # Log everything INFO and above
            'propagate': True,  # Pass log messages to parent loggers
        },
    },
}
Enter fullscreen mode Exit fullscreen mode

Putting it all together

Now we test what we have:

python manage.py runserver
Enter fullscreen mode Exit fullscreen mode

Inside the Prometheus directory:

./prometheus --config.file=prometheus.yml 
Enter fullscreen mode Exit fullscreen mode

On your browser, open 127.0.0.1:8000/metrics to confirm that the metrics are being generated.

Navigate to the Prometheus UI at 127.0.0.1:9090. Query the log metrics by searching for django_log_info_total and click on the Graph view.

Prometheus UI

What we've done so far

  1. Enabled logging in our Django application using the logging module

  2. Created a Custom logging handler to increment the Prometheus counter whenever a log is recorded

  3. Exposed the Django logs to Prometheus and visualized it in Prometheus UI

For the full implementation, you can check out my repository

prometheus Article's
30 articles in total
Favicon
Monitoring AWS Infrastructure: Building a Real-Time Observability Dashboard with Amazon CloudWatch and Prometheus
Favicon
Monitor Your Static App memory usage EC2 Instances with Prometheus and Grafana
Favicon
Scraping Custom Django Metrics with Prometheus
Favicon
Prometheus
Favicon
[HANDS ON] Service Discovery in Prometheus
Favicon
CloudOps Challenge - Real-Time Projects
Favicon
Prometheus Instance Exposed
Favicon
Deploying Prometheus With Docker
Favicon
Prometheus json_exporter: Monitor any JSON API endpoint with Prometheus
Favicon
Prometheus for Absolute Beginners
Favicon
Dockerized Deployment of a Full Stack Application with Reverse Proxy, Monitoring & Observability
Favicon
Monitoring Containerized Applications with Kubernetes Tools: A Comprehensive Guide
Favicon
What is Observability?
Favicon
Kubernetes Metrics and Monitoring with Prometheus and Grafana
Favicon
Monitoring Modbus via Prometheus and Grafana
Favicon
RabbitMQ Monitoring with Prometheus and Grafana
Favicon
Docker with Prometheus and Grafana: Real-Time Monitoring Simplified
Favicon
How to Configure a Remote Data Store for Prometheus
Favicon
EKS & NGINX Load Balancer Monitor with Prometheus, Grafana, and Alerts
Favicon
[Open Source] Simplify Metrics Reporting in NestJS with a Zero-Dependency-Injection Global Reporter
Favicon
Docker to the Rescue: Deploying React And FastAPI App With Monitoring
Favicon
A Beginner's Guide To Service Discovery in Prometheus
Favicon
Usando stack de monitoria opensource no Kubernetes (sem Prometheus)
Favicon
Prometheus - How it's work
Favicon
Prometheus 3.0: A Quantum Leap in Monitoring
Favicon
Observability - 3(Prometheus Explanation)
Favicon
Observability - 2(Metrics, Monitoring & Prometheus)
Favicon
Golang com Opentelemetry, prometheus, Grafana tempo OSS e Grafana padrão
Favicon
Prometheus vs CloudWatch for Cloud Native Applications (Updated in 2024)
Favicon
Prometheus Stack Components Usage in K8 Cluster using Helm

Featured ones: