A comprehensive analytics platform for Traefik access logs with three deployment options: a Go-based API agent, a modern Next.js web dashboard, and a beautiful terminal-based CLI.
- Overview
- Architecture
- Features
- Quick Start
- Multi-Agent Setup
- Agent Database Management
- GeoIP Database Setup
- Dashboard Cards Explained
- Filter Logs & API Usage
- Configuration
- Performance
- Troubleshooting
** MIGRATION GUIDE from V1 to V2**: ./docs/MigrationV1toV2.md
Traefik Log Dashboard is a powerful analytics platform that provides real-time insights into your Traefik reverse proxy traffic. It consists of three components that work together:
- Agent - Go-based backend API that parses logs and exposes metrics
- Dashboard - Next.js web UI with interactive charts and real-time updates
- CLI - Beautiful terminal-based dashboard (optional)
---
---
---
---
---
- ✅ Multi-Agent Architecture - Manage multiple Traefik instances from a single dashboard
- ✅ Persistent Agent Database - SQLite-based storage for agent configurations
- ✅ Environment-Protected Agents - Agents defined in docker-compose.yml cannot be deleted from UI
- ✅ Enhanced Error Handling - Better error messages and user feedback
- ✅ Improved Performance - Parallel fetching and optimized state management
- ✅ Fixed Date Handling - Proper ISO string and Date object conversion
- ✅ Better Agent Status Tracking - lastSeen timestamp with proper persistence
The platform supports a multi-agent architecture where you can deploy multiple agent instances across different Traefik installations and aggregate their data through a single dashboard.
┌─────────────────────────────────────────────────────────────┐
│ Dashboard (Next.js) │
│ SQLite DB for Agent Configuration │
└─────────────────────────────────────────────────────────────┘
│
│ HTTP + Token Auth
│
┌───────────┴───────────┬──────────────┬──────────────┐
│ │ │ │
▼ ▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Agent #1 │ │ Agent #2 │ │ Agent #3 │ │ Agent #N │
│ (Datacenter) │ │ (Cloud) │ │ (Edge) │ │ ... │
└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘
│ │ │ │
▼ ▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Traefik │ │ Traefik │ │ Traefik │ │ Traefik │
│ access.log │ │ access.log │ │ access.log │ │ access.log │
└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘
Key Architectural Components:
- Dashboard - Centralized web UI that communicates with multiple agents
- Agents - Deployed alongside each Traefik instance to parse local logs
- SQLite Database - Stores agent configurations, status, and metadata
- Token Authentication - Secures communication between dashboard and agents
- Real-time analytics and metrics visualization
- GeoIP integration with country and city mapping
- Request rate, response time, and error tracking
- Advanced filtering by status code, method, service, router
- Responsive design for desktop and mobile
- Modern UI with dark mode support
- Auto-refresh with configurable intervals
- Persistent agent configuration with SQLite
- Manage unlimited agent connections
- Organize agents by location (on-site/off-site)
- Real-time status monitoring with health checks
- Tag and categorize agents
- Individual authentication tokens per agent
- Aggregate or individual agent views
- Protected environment agents (cannot delete from UI)
- High-performance Go-based log parser
- JSON and Common Log Format support
- Position tracking for efficient log reading
- MaxMind GeoIP database integration
- System resource monitoring
- Bearer token authentication
- RESTful API with comprehensive endpoints
- Docker and Docker Compose
- Traefik configured with JSON access logs
- (Optional) MaxMind GeoIP databases for geolocation
- Create directory structure:
mkdir -p traefik-dashboard/{data/{logs,geoip,positions,dashboard}}
cd traefik-dashboard- Create
docker-compose.yml:
services:
# Traefik Log Dashboard Agent
traefik-agent:
image: hhftechnology/traefik-log-dashboard-agent:dev-dashboard
container_name: traefik-log-dashboard-agent
restart: unless-stopped
ports:
- "5000:5000"
volumes:
- ./data/logs:/logs:ro
- ./data/geoip:/geoip:ro # MaxMind GeoIP databases
- ./data/positions:/data
environment:
# Log Paths
- TRAEFIK_LOG_DASHBOARD_ACCESS_PATH=/logs/access.log
- TRAEFIK_LOG_DASHBOARD_ERROR_PATH=/logs/access.log
# Authentication
- TRAEFIK_LOG_DASHBOARD_AUTH_TOKEN=d41d8cd98f00b204e9800998ecf8427e
# System Monitoring
- TRAEFIK_LOG_DASHBOARD_SYSTEM_MONITORING=true
# GeoIP Configuration
- TRAEFIK_LOG_DASHBOARD_GEOIP_ENABLED=true
- TRAEFIK_LOG_DASHBOARD_GEOIP_CITY_DB=/geoip/GeoLite2-City.mmdb
- TRAEFIK_LOG_DASHBOARD_GEOIP_COUNTRY_DB=/geoip/GeoLite2-Country.mmdb
# Log Format
- TRAEFIK_LOG_DASHBOARD_LOG_FORMAT=json
# Server Port
- PORT=5000
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:5000/api/logs/status"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
networks:
- traefik-network
# Traefik Log Dashboard - Next.js web UI
traefik-dashboard:
image: hhftechnology/traefik-log-dashboard:dev-dashboard
container_name: traefik-log-dashboard
restart: unless-stopped
user: "1001:1001"
ports:
- "3000:3000"
volumes:
- ./data/dashboard:/app/data
environment:
# Agent Configuration (Default/Environment Agent)
- AGENT_API_URL=http://traefik-agent:5000
- AGENT_API_TOKEN=d41d8cd98f00b204e9800998ecf8427e
- AGENT_NAME=Default Agent # Optional: Name for environment agent
# Node Environment
- NODE_ENV=production
- PORT=3000
depends_on:
traefik-agent:
condition: service_healthy
networks:
- traefik-network
networks:
traefik-network:
external: true- Generate secure authentication token:
# Generate a strong token
openssl rand -hex 32
# Update both TRAEFIK_LOG_DASHBOARD_AUTH_TOKEN and AGENT_API_TOKEN with this value- Start the services:
docker compose up -d- Access the dashboard:
Open your browser to http://localhost:3000
To monitor multiple Traefik instances, deploy additional agents and register them in the dashboard.
Add more agent services to your docker-compose.yml:
services:
traefik-agent-2:
image: hhftechnology/traefik-log-dashboard-agent:dev-dashboard
container_name: traefik-log-dashboard-agent-2
restart: unless-stopped
ports:
- "5001:5000"
volumes:
- ./data/logs2:/logs:ro
- ./data/geoip:/geoip:ro
- ./data/positions2:/data
environment:
- TRAEFIK_LOG_DASHBOARD_ACCESS_PATH=/logs/access.log
- TRAEFIK_LOG_DASHBOARD_ERROR_PATH=/logs/access.log
- TRAEFIK_LOG_DASHBOARD_AUTH_TOKEN=your_token_for_agent_2
- TRAEFIK_LOG_DASHBOARD_SYSTEM_MONITORING=true
- TRAEFIK_LOG_DASHBOARD_GEOIP_ENABLED=true
- TRAEFIK_LOG_DASHBOARD_GEOIP_CITY_DB=/geoip/GeoLite2-City.mmdb
- TRAEFIK_LOG_DASHBOARD_GEOIP_COUNTRY_DB=/geoip/GeoLite2-Country.mmdb
- TRAEFIK_LOG_DASHBOARD_LOG_FORMAT=json
- PORT=5000
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:5000/api/logs/status"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
networks:
- traefik-network
traefik-agent-3:
image: hhftechnology/traefik-log-dashboard-agent:dev-dashboard
container_name: traefik-log-dashboard-agent-3
restart: unless-stopped
ports:
- "5002:5000"
volumes:
- ./data/logs3:/logs:ro
- ./data/geoip:/geoip:ro
- ./data/positions3:/data
environment:
- TRAEFIK_LOG_DASHBOARD_ACCESS_PATH=/logs/access.log
- TRAEFIK_LOG_DASHBOARD_ERROR_PATH=/logs/access.log
- TRAEFIK_LOG_DASHBOARD_AUTH_TOKEN=your_token_for_agent_3
- TRAEFIK_LOG_DASHBOARD_SYSTEM_MONITORING=true
- TRAEFIK_LOG_DASHBOARD_GEOIP_ENABLED=true
- TRAEFIK_LOG_DASHBOARD_GEOIP_CITY_DB=/geoip/GeoLite2-City.mmdb
- TRAEFIK_LOG_DASHBOARD_GEOIP_COUNTRY_DB=/geoip/GeoLite2-Country.mmdb
- TRAEFIK_LOG_DASHBOARD_LOG_FORMAT=json
- PORT=5000
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:5000/api/logs/status"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
networks:
- traefik-network-
Navigate to Settings → Agents in the dashboard
-
Click Add Agent
-
Fill in agent details:
- Name: Descriptive name (e.g., "Production Datacenter")
- URL: Agent API endpoint (e.g., "http://agent-host:5000")
- Token: Authentication token for this agent
- Location: on-site or off-site
- Description: Optional notes
- Tags: Optional labels for organization
-
Click Save to register the agent
Deploy agents on different servers:
On Remote Server:
docker run -d \
--name traefik-agent \
-p 5000:5000 \
-v /path/to/traefik/logs:/logs:ro \
-v /path/to/geoip:/geoip:ro \
-v /path/to/positions:/data \
-e TRAEFIK_LOG_DASHBOARD_ACCESS_PATH=/logs/access.log \
-e TRAEFIK_LOG_DASHBOARD_AUTH_TOKEN=your_secure_token \
-e TRAEFIK_LOG_DASHBOARD_GEOIP_ENABLED=true \
-e TRAEFIK_LOG_DASHBOARD_GEOIP_CITY_DB=/geoip/GeoLite2-City.mmdb \
-e TRAEFIK_LOG_DASHBOARD_GEOIP_COUNTRY_DB=/geoip/GeoLite2-Country.mmdb \
hhftechnology/traefik-log-dashboard-agent:dev-dashboardRegister in Dashboard:
- URL:
http://remote-server-ip:5000 - Token:
your_secure_token
The dashboard uses SQLite to persist agent configurations:
CREATE TABLE agents (
id TEXT PRIMARY KEY, -- Auto-generated: agent-001, agent-002, etc.
name TEXT NOT NULL, -- Display name
url TEXT NOT NULL, -- Agent API URL
token TEXT NOT NULL, -- Authentication token
location TEXT NOT NULL, -- 'on-site' or 'off-site'
number INTEGER NOT NULL, -- Sequential number
status TEXT, -- 'online', 'offline', 'checking'
last_seen TEXT, -- ISO timestamp of last successful check
description TEXT, -- Optional description
tags TEXT, -- JSON array of tags
source TEXT NOT NULL DEFAULT 'manual', -- 'env' or 'manual'
created_at TEXT NOT NULL, -- Creation timestamp
updated_at TEXT NOT NULL -- Last update timestamp
);
CREATE TABLE selected_agent (
id INTEGER PRIMARY KEY CHECK(id = 1), -- Singleton table
agent_id TEXT NOT NULL, -- Currently selected agent
updated_at TEXT NOT NULL -- Selection timestamp
);Environment Agents (source='env'):
- Automatically synced from docker-compose.yml environment variables
- Cannot be deleted from the dashboard UI
- Displayed with a 🔒 lock icon
- Updated on dashboard restart if environment changes
Manual Agents (source='manual'):
- Added through the dashboard UI
- Fully editable and deletable
- Stored persistently in SQLite database
Define agents in docker-compose.yml:
traefik-dashboard:
environment:
# This creates a protected environment agent
- AGENT_API_URL=http://traefik-agent:5000
- AGENT_API_TOKEN=your_secure_token
- AGENT_NAME=Production Agent # Optional, defaults to "Environment Agent"The dashboard will automatically:
- Create/update agent with ID
agent-env-001 - Mark it as
source='env' - Protect it from UI deletion
- Sync changes on restart
By default: ./data/dashboard/agents.db
Custom path:
traefik-dashboard:
environment:
- DATABASE_PATH=/custom/path/agents.dbBackup:
# Copy the database file
cp ./data/dashboard/agents.db ./backups/agents-$(date +%Y%m%d).dbRestore:
# Stop dashboard
docker compose stop traefik-dashboard
# Restore database
cp ./backups/agents-20250101.db ./data/dashboard/agents.db
# Start dashboard
docker compose start traefik-dashboard-
Sign up for MaxMind account (free): https://www.maxmind.com/en/geolite2/signup
-
Generate license key:
- Login → Account → Manage License Keys
- Create new license key
-
Download databases manually:
cd data/geoip # Download GeoLite2-City wget "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key=YOUR_LICENSE_KEY&suffix=tar.gz" -O GeoLite2-City.tar.gz # Download GeoLite2-Country wget "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country&license_key=YOUR_LICENSE_KEY&suffix=tar.gz" -O GeoLite2-Country.tar.gz # Extract tar -xzf GeoLite2-City.tar.gz --strip-components=1 tar -xzf GeoLite2-Country.tar.gz --strip-components=1 # Clean up rm *.tar.gz
-
Automated Updates (using geoipupdate):
docker run -d \ --name geoipupdate \ -v ./data/geoip:/usr/share/GeoIP \ -e GEOIPUPDATE_ACCOUNT_ID=your_account_id \ -e GEOIPUPDATE_LICENSE_KEY=your_license_key \ -e GEOIPUPDATE_EDITION_IDS="GeoLite2-City GeoLite2-Country" \ -e GEOIPUPDATE_FREQUENCY=168 # Update weekly maxmindinc/geoipupdate
# Check files exist
ls -lh data/geoip/
# Should show:
# GeoLite2-City.mmdb
# GeoLite2-Country.mmdb
# Test agent GeoIP endpoint
curl -H "Authorization: Bearer your_token" \
http://localhost:5000/api/location/statusTotal Requests: Aggregate count of all HTTP requests processed
Average Response Time: Mean response time across all requests (in milliseconds)
Error Rate: Percentage of requests with 4xx or 5xx status codes
Active Services: Number of unique Traefik services handling traffic
Top Countries: Requests grouped by country (requires GeoIP)
Top Cities: Requests grouped by city (requires GeoIP)
Interactive Map: Geographic heatmap visualization
Requests by Status Code: Distribution of 2xx, 3xx, 4xx, 5xx responses
Top Services: Most active Traefik services by request count
Top Routers: Most active Traefik routers by request count
Methods Distribution: HTTP methods (GET, POST, PUT, DELETE, etc.)
Response Time Chart: Time-series graph of response times
Request Rate: Requests per second/minute/hour
Slowest Endpoints: Top 10 slowest routes by average response time
Error Timeline: Time-series of error occurrences
Available in the top toolbar:
- Time Range: Last 1h, 6h, 24h, 7d, 30d, or custom range
- Status Codes: Filter by 2xx, 3xx, 4xx, 5xx
- HTTP Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS
- Services: Filter by Traefik service name
- Routers: Filter by Traefik router name
- Search: Free-text search across all fields
Get Logs:
curl -H "Authorization: Bearer YOUR_TOKEN" \
"http://localhost:5000/api/logs/access?lines=100&status=200&method=GET"Get Status:
curl -H "Authorization: Bearer YOUR_TOKEN" \
"http://localhost:5000/api/logs/status"Get Metrics:
curl -H "Authorization: Bearer YOUR_TOKEN" \
"http://localhost:5000/api/logs/metrics?period=1h"GeoIP Lookup:
curl -H "Authorization: Bearer YOUR_TOKEN" \
"http://localhost:5000/api/location/lookup?ip=8.8.8.8"System Stats:
curl -H "Authorization: Bearer YOUR_TOKEN" \
"http://localhost:5000/api/system/stats"| Variable | Description | Default | Required |
|---|---|---|---|
TRAEFIK_LOG_DASHBOARD_ACCESS_PATH |
Path to Traefik access log | /logs/access.log |
Yes |
TRAEFIK_LOG_DASHBOARD_ERROR_PATH |
Path to Traefik error log | - | No |
TRAEFIK_LOG_DASHBOARD_AUTH_TOKEN |
Bearer token for authentication | - | Yes |
TRAEFIK_LOG_DASHBOARD_LOG_FORMAT |
Log format (json/common) | json |
No |
TRAEFIK_LOG_DASHBOARD_SYSTEM_MONITORING |
Enable system monitoring | true |
No |
TRAEFIK_LOG_DASHBOARD_GEOIP_ENABLED |
Enable GeoIP lookups | false |
No |
TRAEFIK_LOG_DASHBOARD_GEOIP_CITY_DB |
Path to GeoLite2-City.mmdb | - | If GeoIP enabled |
TRAEFIK_LOG_DASHBOARD_GEOIP_COUNTRY_DB |
Path to GeoLite2-Country.mmdb | - | If GeoIP enabled |
PORT |
Agent listen port | 5000 |
No |
| Variable | Description | Default | Required |
|---|---|---|---|
AGENT_API_URL |
Default agent URL (for env agent) | - | Yes (for env agent) |
AGENT_API_TOKEN |
Default agent token (for env agent) | - | Yes (for env agent) |
AGENT_NAME |
Name for environment agent | Environment Agent |
No |
NODE_ENV |
Node environment | production |
No |
PORT |
Dashboard listen port | 3000 |
No |
DATABASE_PATH |
SQLite database location | ./data/agents.db |
No |
Configure Traefik to output JSON access logs:
# traefik.yml
accessLog:
filePath: "/logs/access.log"
format: json
bufferingSize: 100
fields:
defaultMode: keep
names:
ClientUsername: drop
headers:
defaultMode: keep
names:
Authorization: drop
Cookie: drop- Parallel Fetching: Dashboard fetches agents and selected agent in parallel
- Optimized State Management: Direct state updates instead of full refreshes
- Position Tracking: Agents only read new log entries, not entire file
- Database Indexing: Indexes on
sourceandstatuscolumns - Efficient Date Handling: Proper ISO string and Date object conversion
Agent:
- CPU: ~5-10% (idle) / ~20-30% (heavy traffic)
- Memory: ~50-100 MB
- Disk: Minimal (position files < 1 KB)
Dashboard:
- CPU: ~5% (idle) / ~15% (active)
- Memory: ~150-200 MB
- Database: ~1-10 MB (depending on agent count)
- < 1000 req/sec: Single agent sufficient
- 1000-10,000 req/sec: Single agent with optimized log rotation
- > 10,000 req/sec: Consider multiple agents with load balancing
- Multiple Locations: Deploy agent per location for better latency
Symptoms:
- Red connection error banner
- No data displayed
Solutions:
# Check agent is running
docker ps | grep traefik-agent
# Check agent logs
docker logs traefik-log-dashboard-agent
# Verify agent is accessible from dashboard
docker exec traefik-log-dashboard wget -O- http://traefik-agent:5000/api/logs/status
# Check authentication token matches
docker exec traefik-agent env | grep AUTH_TOKEN
docker exec traefik-dashboard env | grep AGENT_API_TOKENSymptoms:
- Delete button disabled or shows error
- Error: "Cannot delete environment-sourced agents"
Cause: Agent is defined in docker-compose.yml environment variables
Solution:
# Environment agents (source='env') are protected
# They can only be removed by:
# 1. Removing environment variables from docker-compose.yml
# 2. Restarting the dashboard
docker compose down
# Edit docker-compose.yml - remove AGENT_API_URL and AGENT_API_TOKEN
docker compose up -dSymptoms:
- Geographic cards show "No data"
- Countries show as empty
Solutions:
# Verify databases exist
ls -lh ./data/geoip/
# Check agent logs for GeoIP errors
docker logs traefik-log-dashboard-agent | grep -i geoip
# Verify environment variables
docker exec traefik-agent env | grep GEOIP
# Test GeoIP lookup
curl -H "Authorization: Bearer YOUR_TOKEN" \
"http://localhost:5000/api/location/status"
# Re-download databases if corrupted
cd data/geoip
rm *.mmdb
# Follow GeoIP setup instructions aboveSymptoms:
- Dashboard shows zero requests
- All cards empty
Solutions:
# Verify log file path is correct
docker exec traefik-agent ls -lh /logs/
# Check log file permissions (should be readable)
docker exec traefik-agent cat /logs/access.log | head -5
# Verify log format matches configuration
# Should be JSON format:
docker exec traefik-agent head -1 /logs/access.log
# Check Traefik is generating logs
tail -f /path/to/your/traefik/logs/access.logSymptoms:
- Agent consuming excessive memory
- Dashboard slow or unresponsive
Solutions:
# Enable log rotation in Traefik
# traefik.yml:
# accessLog:
# filePath: "/logs/access.log"
# maxSize: 100 # MB
# maxBackups: 3
# maxAge: 7 # days
# Reduce dashboard refresh interval
# In UI: Settings → Refresh Interval → 30s or 60s
# Check database size
du -sh data/dashboard/agents.db
# Vacuum database if large
docker exec traefik-dashboard sqlite3 /app/data/agents.db "VACUUM;"Symptoms:
- Agent status never changes from "checking"
- No lastSeen timestamp
Solutions:
# Manually check agent status
curl -H "Authorization: Bearer YOUR_TOKEN" \
http://agent-url:5000/api/logs/status
# Check network connectivity
docker exec traefik-dashboard ping -c 3 traefik-agent
# Verify token is correct
# In Dashboard: Settings → Agents → Edit Agent → Update Token
# Force status refresh
# In Dashboard: Settings → Agents → Click refresh buttonSymptoms:
- Error: "database is locked"
- Agent operations fail
Solutions:
# Stop dashboard
docker compose stop traefik-dashboard
# Check for stale locks
ls -la data/dashboard/
# Remove lock files if present
rm data/dashboard/agents.db-shm
rm data/dashboard/agents.db-wal
# Restart dashboard
docker compose start traefik-dashboard- Agent Documentation: ./agent/README.md
- Dashboard Documentation: ./dashboard/README.md
- CLI Documentation: ./cli/README.md
- API Reference: ./docs/API.md
- Architecture Guide: ./docs/ARCHITECTURE.md
- Migration Guide V1→V2: ./docs/MigrationV1toV2.md
Contributions are welcome! Please read our Contributing Guide.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the GNU AFFERO GENERAL PUBLIC LICENSE - see the LICENSE file for details.