Add real-time log monitoring and system stats dashboard
Implements a comprehensive monitoring system for the admin interface: Backend: - New monitoring package with Redis ring buffer for log storage - Zerolog MultiWriter to capture logs to Redis - System stats collection (CPU, memory, disk, goroutines, GC) - HTTP metrics middleware (request counts, latency, error rates) - Asynq queue stats for worker process - WebSocket endpoint for real-time log streaming - Admin auth middleware now accepts token in query params (for WebSocket) Frontend: - New monitoring page with tabs (Overview, Logs, API Stats, Worker Stats) - Real-time log viewer with level filtering and search - System stats cards showing CPU, memory, goroutines, uptime - HTTP endpoint statistics table - Asynq queue depth visualization - Enable/disable monitoring toggle in settings Memory safeguards: - Max 200 unique endpoints tracked - Hourly stats reset to prevent unbounded growth - Max 1000 log entries in ring buffer - Max 1000 latency samples for P95 calculation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/treytartt/casera-api/internal/config"
|
||||
"github.com/treytartt/casera-api/internal/database"
|
||||
"github.com/treytartt/casera-api/internal/i18n"
|
||||
"github.com/treytartt/casera-api/internal/monitoring"
|
||||
"github.com/treytartt/casera-api/internal/push"
|
||||
"github.com/treytartt/casera-api/internal/router"
|
||||
"github.com/treytartt/casera-api/internal/services"
|
||||
@@ -29,7 +30,7 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Initialize logger
|
||||
// Initialize basic logger first (will be enhanced after Redis connects)
|
||||
utils.InitLogger(cfg.Server.Debug)
|
||||
|
||||
// Initialize i18n
|
||||
@@ -80,6 +81,27 @@ func main() {
|
||||
defer cache.Close()
|
||||
}
|
||||
|
||||
// Initialize monitoring service (if Redis is available)
|
||||
var monitoringService *monitoring.Service
|
||||
if cache != nil {
|
||||
monitoringService = monitoring.NewService(monitoring.Config{
|
||||
Process: "api",
|
||||
RedisClient: cache.Client(),
|
||||
DB: db, // Pass database for enable_monitoring setting sync
|
||||
})
|
||||
|
||||
// Reinitialize logger with monitoring writer
|
||||
utils.InitLoggerWithWriter(cfg.Server.Debug, monitoringService.LogWriter())
|
||||
|
||||
// Start stats collection
|
||||
monitoringService.Start()
|
||||
defer monitoringService.Stop()
|
||||
|
||||
log.Info().
|
||||
Bool("log_capture_enabled", monitoringService.IsEnabled()).
|
||||
Msg("Monitoring service initialized")
|
||||
}
|
||||
|
||||
// Initialize email service
|
||||
var emailService *services.EmailService
|
||||
log.Info().
|
||||
@@ -133,13 +155,14 @@ func main() {
|
||||
|
||||
// Setup router with dependencies (includes admin panel at /admin)
|
||||
deps := &router.Dependencies{
|
||||
DB: db,
|
||||
Cache: cache,
|
||||
Config: cfg,
|
||||
EmailService: emailService,
|
||||
PDFService: pdfService,
|
||||
PushClient: pushClient,
|
||||
StorageService: storageService,
|
||||
DB: db,
|
||||
Cache: cache,
|
||||
Config: cfg,
|
||||
EmailService: emailService,
|
||||
PDFService: pdfService,
|
||||
PushClient: pushClient,
|
||||
StorageService: storageService,
|
||||
MonitoringService: monitoringService,
|
||||
}
|
||||
r := router.SetupRouter(deps)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user