Enhance Docker setup with logging and monitoring features

- Added logging configuration to WSGI for persistent log collection.
- Updated Docker Compose files for local and development environments, including Redis, PostgreSQL, and Grafana services.
- Introduced Promtail configuration for log scraping and integration with Loki.
- Created application log directory in Dockerfile for log persistence.
This commit is contained in:
Ross
2025-12-01 16:43:40 +00:00
parent 590e0b76ed
commit 517c30ba0e
5 changed files with 99 additions and 0 deletions
+45
View File
@@ -15,10 +15,55 @@ services:
command: [] command: []
volumes: volumes:
- ../:/usr/src/app:cached - ../:/usr/src/app:cached
# Mount the app log directory so logs are visible on the host at ./logs
- ../logs:/var/log/rad
nginx: nginx:
# Development nginx override: mount a simplified config that does not # Development nginx override: mount a simplified config that does not
# reference LetsEncrypt certs so the container can start without real # reference LetsEncrypt certs so the container can start without real
# certificates present on the host. # certificates present on the host.
image: nginx:1.25-alpine
volumes: volumes:
- ../deploy/nginx/dev.conf:/etc/nginx/conf.d/default.conf:ro - ../deploy/nginx/dev.conf:/etc/nginx/conf.d/default.conf:ro
loki:
image: grafana/loki:2.8.2
command: -config.file=/etc/loki/local-config.yaml
ports:
- "3100:3100"
volumes:
- ./loki-config/local-config.yaml:/etc/loki/local-config.yaml:ro
- ./loki-data:/loki
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost:3100/ready || exit 1"]
interval: 5s
timeout: 3s
retries: 6
promtail:
image: grafana/promtail:2.8.2
volumes:
- ../logs:/var/log/rad:ro
- ./promtail-config.yml:/etc/promtail/promtail-config.yml:ro
command: -config.file=/etc/promtail/promtail-config.yml
depends_on:
- loki
restart: unless-stopped
grafana:
image: grafana/grafana:10.2.0
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana-data:/var/lib/grafana
depends_on:
loki:
condition: service_healthy
restart: unless-stopped
volumes:
grafana-data:
loki-data:
+18
View File
@@ -0,0 +1,18 @@
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: rad_app_logs
static_configs:
- targets:
- localhost
labels:
job: rad_app
__path__: /var/log/rad/*.log
+6
View File
@@ -57,6 +57,12 @@ ENV PATH="/opt/venv/bin:$PATH"
# `--chown` flag during COPY and avoid an expensive recursive `chown -R`. # `--chown` flag during COPY and avoid an expensive recursive `chown -R`.
RUN useradd -m appuser RUN useradd -m appuser
# Create directory for application logs and ensure ownership is correct.
# Do this as root before switching to `appuser` so the directory exists
# and can be mounted by the dev compose override.
RUN mkdir -p /var/log/rad \
&& chown -R appuser:appuser /var/log/rad
# Copy project files into image and set ownership during copy (faster than # Copy project files into image and set ownership during copy (faster than
# a separate `chown -R` step). This keeps layer reuse efficient. # a separate `chown -R` step). This keeps layer reuse efficient.
COPY --chown=appuser:appuser . /usr/src/app COPY --chown=appuser:appuser . /usr/src/app
+30
View File
@@ -10,6 +10,36 @@ https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/
import os import os
from django.core.wsgi import get_wsgi_application from django.core.wsgi import get_wsgi_application
from loguru import logger
import sys
from pathlib import Path
# Configure Loguru sinks early so app imports see consistent logging.
# Log to stdout (so `docker logs` shows messages) and to a file at
# `/var/log/rad/app.log` for persistent collection / host tailing.
try:
# ensure directory exists
log_dir = Path("/var/log/rad")
log_dir.mkdir(parents=True, exist_ok=True)
# Add stdout sink (if not already added by other code)
logger.remove() # remove default handlers to avoid duplicate lines
logger.add(sys.stdout, level="INFO", enqueue=True, backtrace=False, diagnose=False)
# Add rotating file sink for persistence in container. Use JSON lines
# (serialize=True) to make logs easy to query in Loki/Grafana.
logger.add(
str(log_dir / "app.log"),
rotation="10 MB",
retention="10 days",
level="DEBUG",
enqueue=True,
serialize=True,
)
except Exception:
# Best-effort only — don't crash WSGI startup if logging can't be configured
try:
logger.add(sys.stderr)
except Exception:
pass
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "rad.settings") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "rad.settings")