Logging Setup
This document describes the logging configuration for the Junqo platform monitoring stack using Loki, Grafana, Prometheus, and Promtail.
Architecture Overview
The logging system follows containerization best practices by using Docker’s native logging capabilities:
- Docker Logging Driver: All containers log to stdout/stderr with json-file driver
- Promtail: Collects logs directly from Docker containers
- Loki: Stores and indexes logs
- Grafana: Visualizes logs and metrics
- Prometheus: Collects metrics
sequenceDiagram
autonumber
participant Containers as Services
participant Docker as Docker json-file
participant Promtail
participant Loki
participant Grafana
participant Prometheus
Containers->>Docker: stdout/stderr → JSON logs
Docker-->>Promtail: Read *-json.log
Promtail->>Loki: Push parsed streams
Grafana->>Loki: Query logs
Prometheus->>Prometheus: Scrape metrics
Grafana->>Prometheus: Query metrics
Note: The diagram above illustrates the flow of logs and metrics from services to visualization.
Logging Strategy
Container-Native Logging
All services are configured to log to stdout/stderr instead of log files, following the 12-Factor App principles:
- No volume mounts for log files
- Automatic log rotation via Docker’s json-file driver
- Centralized collection through Docker’s logging system
- Better orchestration compatibility (Kubernetes, Docker Swarm)
Docker Logging Configuration
Each service uses the following logging configuration:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
This provides:
- Maximum log file size of 10MB per container
- Keep 3 rotated log files
- Automatic cleanup of old logs
Log Sources
1. Backend Service (junqo_back)
- Location: Container stdout/stderr
- Format: Structured JSON logs with timestamps
- Content: Application logs, errors, API requests
- Collection: Docker containers at
/var/lib/docker/containers/*/*-json.log
2. Frontend Service (junqo_front)
- Access Logs: Nginx stdout (
access_log /dev/stdout main) - Error Logs: Nginx stderr (
error_log /dev/stderr warn) - Format: Nginx access log format
- Content: HTTP requests, responses, errors
3. Database Service (junqo_db)
- Location: PostgreSQL stdout/stderr
- Format: PostgreSQL log format
- Content: Database connections, queries, errors
- Configuration: Logs to Docker logging system
4. Reverse Proxy Service (junqo_rproxy)
- Access Logs: Nginx stdout
- Error Logs: Nginx stderr
- Format: Nginx access log format
- Content: Incoming requests, SSL info, proxy errors
Configuration Files
Promtail Configuration (promtail-config.yaml)
The configuration includes multiple scraping methods:
- Docker Service Discovery: Automatically discovers containers
- Static Container Logs: Reads Docker’s JSON log files directly
- Service-Specific Jobs: Targeted collection for each Junqo service
Key features:
- Automatic container name extraction
- Service labeling for easy filtering
- JSON log parsing for Docker format
- Stream separation (stdout/stderr)
Loki Configuration (loki-config.yaml)
- Configures log storage and indexing
- Sets up retention policies
- Defines ingestion endpoints
Container Log Locations
Docker stores container logs at:
/var/lib/docker/containers/<container-id>/<container-id>-json.log
Promtail reads these files directly with the pattern:
/var/lib/docker/containers/*/*-json.log
Service Access
- Grafana: http://localhost:3000
- Loki: http://localhost:3100
- Prometheus: http://localhost:9090
- Adminer: http://localhost:8080
Grafana Security Setup
Grafana’s admin password is managed securely using Docker secrets. The password is stored in a file and mounted as a secret:
-
Create a
grafana_password.conffile at the root of the project:echo "your_secure_password" > grafana_password.conf -
The password file location can be customized using the
GRAFANA_PASSWORD_FILEenvironment variable:export GRAFANA_PASSWORD_FILE=/path/to/custom/grafana_password.conf -
Access Grafana at http://localhost:3000 using:
- Username: admin
- Password: (password from grafana_password.conf)
Grafana Dashboard Setup
- Access Grafana at http://localhost:3000
- Add Loki as a data source:
- URL:
http://loki:3100
- URL:
- Import or create dashboards for:
- Application logs by service
- Error rate monitoring
- Request volume analysis
- Performance metrics
Log Queries Examples
View Backend Logs
{container_name="junqo_back"}
View Frontend Logs
{container_name="junqo_front"}
View Database Logs
{container_name="junqo_db"}
View Reverse Proxy Logs
{container_name="junqo_rproxy"}
View Error Logs Only
{container_name="junqo_back"} |~ "ERROR|error|Error"
View Nginx Access Logs
{container_name="junqo_rproxy"} | json | line_format ""
Filter by Log Stream
{container_name="junqo_back", stream="stderr"}
Troubleshooting
Common Issues
- Logs not appearing in Grafana
- Check if Promtail container is running:
docker logs junqo_promtail - Verify Docker socket is mounted:
/var/run/docker.sock:/var/run/docker.sock:ro - Check Promtail configuration syntax
- Ensure containers are actually logging to stdout/stderr
- Check if Promtail container is running:
- High disk usage
- Docker automatically rotates logs based on the json-file driver settings
- Check Docker log settings:
docker system df - Clean Docker logs:
docker system prune --volumes
- Container logs not being collected
- Verify Promtail has access to Docker containers directory
- Check container log format:
docker logs junqo_back - Ensure logging driver is set to “json-file”
Debug Commands
# Check container logs directly
docker logs junqo_back
docker logs junqo_front
docker logs junqo_db
# Check Docker log files
sudo ls -la /var/lib/docker/containers/*/
# View Promtail logs
docker logs junqo_promtail
# View Loki logs
docker logs junqo_loki
# Check log driver configuration
docker inspect junqo_back | grep -A 10 "LogConfig"
# Test Docker logging
docker exec junqo_back echo "Test log message"
Verify Log Collection
# Check if logs are being written
docker logs --tail 10 junqo_back
# Monitor live logs
docker logs -f junqo_back
# Check log file sizes
docker exec junqo_promtail ls -la /var/lib/docker/containers/*/*-json.log
Advantages of Docker Native Logging
Benefits
- No Permission Issues: No need to manage file permissions
- Automatic Rotation: Built-in log rotation and cleanup
- Better Portability: Works consistently across environments
- Simplified Configuration: No volume mounts for logs
- Orchestration Ready: Compatible with Kubernetes and Docker Swarm
- Resource Efficient: Less overhead than file-based logging
Best Practices
- Application Code: Ensure applications log to stdout/stderr
- Log Levels: Use appropriate log levels to avoid excessive logging
- Structured Logging: Use JSON format for better parsing
- Log Rotation: Configure appropriate rotation settings
- Monitoring: Monitor Docker disk usage regularly
Maintenance
- Logs are automatically rotated by Docker when they exceed 10MB
- Maximum of 3 rotated files are kept per container
- Old logs are automatically cleaned up by Docker
- No manual log rotation scripts needed
- Monitor Docker system disk usage:
docker system df
Future Enhancements
- Add metrics collection with Prometheus exporters
- Implement log alerting rules in Grafana
- Add log aggregation dashboards
- Configure log-based alerting
- Add structured logging with correlation IDs
- Implement distributed tracing integration