Back to the blog
How to use Grafana, Prometheus and Loki in Django for a better debug in your applications using Docker Compose
Integrate Grafana, Prometheus and Loki into Django projects to improve monitoring and debugging, configured in a Docker Compose environment.
With the growing need to monitor and maintain application performance, tools like Grafana, Prometheus, and Loki have become essential for developers. These tools enable the collection, analysis, and visualization of metrics, as well as real-time log management.
In this article, we will explore how to integrate these tools with the Django framework, leveraging the power of Docker Compose to orchestrate the services. The goal is to create a complete environment where you can:
- Monitor performance metrics with Prometheus.
- Analyze structured logs with Loki.
- Visualize data on dynamic dashboards in Grafana.
This integration will not only help with maintaining your application but also serve as a practical introduction to observability tools within the Django ecosystem. Let's get started!
1. Install django-prometheus in your application
Requirements
- Django > 3.2
- Python 3.7 and above.
Installation
Install with:
Terminal
pip install django-prometheusQuickstart
In your settings.py:
./settings.py
INSTALLED_APPS = [...'django_prometheus',...]MIDDLEWARE = ['django_prometheus.middleware.PrometheusBeforeMiddleware',# All your other middlewares go here, including the default# middlewares like SessionMiddleware, CommonMiddleware,# CsrfViewmiddleware, SecurityMiddleware, etc.'django_prometheus.middleware.PrometheusAfterMiddleware',]
In your urls.py:
./urls.py
urlpatterns = [...path('', include('django_prometheus.urls')),]
Monitoring your databases
SQLite, MySQL, and PostgreSQL databases can be monitored. Just replace the ENGINE property of your database, replacing django.db.backends with django_prometheus.db.backends.
./settings.py
DATABASES = {'default': {'ENGINE': 'django_prometheus.db.backends.sqlite3','NAME': os.path.join(BASE_DIR, 'db.sqlite3'),},}
Monitoring your caches
Filebased, memcached, redis caches can be monitored. Just replace the cache backend to use the one provided by django_prometheusdjango.core.cache.backends with django_prometheus.cache.backends.
./settings.py
CACHES = {'default': {'BACKEND': 'django_prometheus.cache.backends.filebased.FileBasedCache','LOCATION': '/var/tmp/django_cache',},}
Monitoring your models
You may want to monitor the creation/deletion/update rate for your model. This can be done by adding a mixin to them. This is safe to do on existing models (it does not require a migration).
If your model is:
./models.py
class Dog(models.Model):name = models.CharField(max_length=100, unique=True)breed = models.CharField(max_length=100, blank=True, null=True)age = models.PositiveIntegerField(blank=True, null=True)
Just add the ExportModelOperationsMixin as such:
./models.py
from django_prometheus.models import ExportModelOperationsMixinclass Dog(ExportModelOperationsMixin('dog'), models.Model):name = models.CharField(max_length=100, unique=True)breed = models.CharField(max_length=100, blank=True, null=True)age = models.PositiveIntegerField(blank=True, null=True)
1. Setup up docker-compose in your application
Logging
- Grafana Loki
- Grafana Promtail
Installation
Loki is a log aggregation and indexing system, developed by Grafana Labs, optimized to function as a database for logs and the Promtail is the log collection agent that sends logs to Loki. It acts as a log shipper.
./docker-compose-dev.yml
loki:image: grafana/loki:2.9.2ports:- "3100:3100"command: -config.file=/etc/loki/local-config.yamlnetworks:- lokipromtail:image: grafana/promtail:2.9.2volumes:- /var/log:/var/log- /var/run/docker.sock:/var/run/docker.sock- ./promtail/config/promtail-config.yml:/etc/promtail/config.ymlcommand: -config.file=/etc/promtail/config.ymlnetworks:- loki
In the Promtail job we can see that we are mounting the ./promtail/config/promtail-config.yml that is the file who will be responsible configurate Promtail and send the logs to Loki. So let's create this file.
./promtail/config/promtail-config.yml
server:http_listen_port: 9080grpc_listen_port: 0positions:filename: /tmp/positions.yamlclients:- url: http://loki:3100/loki/api/v1/pushscrape_configs:- job_name: systemstatic_configs:- targets:- localhostlabels:job: varlogs__path__: /var/log/*log- job_name: dockerdocker_sd_configs:- host: unix:///var/run/docker.sockrelabel_configs:- source_labels: [__meta_docker_container_name]target_label: container- source_labels:[__meta_docker_container_label_com_docker_compose_service]target_label: service- source_labels:[__meta_docker_container_label_com_docker_compose_project]target_label: compose_project- source_labels: [__meta_docker_container_label_com_docker_compose_oneoff]target_label: compose_oneoff- source_labels:[__meta_docker_container_label_com_docker_compose_config_hash]target_label: compose_config_hash- source_labels:[__meta_docker_container_label_com_docker_compose_version]target_label: compose_version
Metrics and Dashboard
- Prometheus
- Grafana
Installation
Grafana is a tool for creating and visualizing dashboards based on data from various sources and Prometheus is a monitoring tool and alert system focused on numerical metrics based on time series.
./docker-compose-dev.yml
grafana:environment:- GF_PATHS_PROVISIONING=/etc/grafana/provisioningentrypoint:- sh- -euc- |mkdir -p /etc/grafana/provisioning/datasourcescat <<EOF > /etc/grafana/provisioning/datasources/ds.yamlapiVersion: 1datasources:- name: Lokitype: lokiaccess: proxyorgId: 1url: http://loki:3100basicAuth: falseisDefault: trueversion: 1editable: false- name: Prometheustype: prometheusaccess: proxyorgId: 1url: http://prometheus:9090basicAuth: falseisDefault: falseversion: 1editable: falseEOF/run.shimage: grafana/grafana:latestvolumes:- grafana_data:/var/lib/grafanaports:- "3060:3000"networks:- lokiprometheus:image: prom/prometheus:latestports:- "9090:9090"entrypoint:- sh- -c- |/bin/prometheus --config.file=/etc/prometheus/prometheus/config/prometheus.yml --web.enable-lifecyclevolumes:- ./prometheus/config/prometheus.yml:/etc/prometheus/prometheus/config/prometheus.yml- prometheus_data:/prometheusnetworks:- loki
In the Prometheus job we can see that we are mounting the ./prometheus/config/prometheus.yml that is the file who will be responsible configurate Prometheus and get the metrics from Django application. So let's create this file.
./prometheus/config/prometheus.yml
global:scrape_interval: 15sscrape_timeout: 10sscrape_protocols:- OpenMetricsText1.0.0- OpenMetricsText0.0.1- PrometheusText0.0.4evaluation_interval: 15sruntime:gogc: 75scrape_configs:- job_name: prometheushonor_timestamps: truetrack_timestamps_staleness: falsescrape_interval: 15sscrape_timeout: 10sscrape_protocols:- OpenMetricsText1.0.0- OpenMetricsText0.0.1- PrometheusText0.0.4metrics_path: /metricsscheme: httpenable_compression: truefollow_redirects: trueenable_http2: truestatic_configs:- targets:- <YOUR IP>:8000
Detail: Replace <YOUR IP> with your IP address in dev ambient.
Final touches
- Volumes
- Network
./docker-compose-dev.yml
networks:loki:volumes:grafana_data:prometheus_data:
Closing Thoughts
Integrating Grafana, Prometheus, and Loki into a Django project using Docker Compose creates a powerful environment for monitoring, metric analysis, and log management. This setup provides a comprehensive view of your application's behavior, making it easier to identify issues and optimize performance.
Throughout this article, we explored how each tool contributes to the observability ecosystem:
- Prometheus collects essential metrics.
- Loki efficiently stores and organizes logs.
- Grafana unifies the data into interactive and dynamic dashboards.
With this stack configured, you're ready to monitor your application professionally, anticipating issues and ensuring a more stable experience for your users. Now it's time to customize and expand this environment to fit your specific needs.
If you found this guide helpful, feel free to share it and if you have any questions or comments just contact me. Your journey to mastering monitoring and observability has just begun! 🚀