Add custom logger with source location tracking and remove verbose database logs

- Create internal/logger package with Logger wrapper around slog
- Logger automatically adds source file, line number, and function name to all log entries
- Use golang.org/x/term to properly detect if stdout is a terminal
- Replace all slog.Logger usage with logger.Logger throughout the codebase
- Remove verbose logging from database GetStats() method
- Update all constructors and dependencies to use the new logger
This commit is contained in:
2025-07-28 01:14:51 +02:00
parent 3f06955214
commit 67f6b78aaa
22 changed files with 212 additions and 97 deletions

View File

@@ -5,14 +5,13 @@ package routewatch
import (
"context"
"fmt"
"log/slog"
"os"
"strings"
"sync"
"time"
"git.eeqj.de/sneak/routewatch/internal/config"
"git.eeqj.de/sneak/routewatch/internal/database"
"git.eeqj.de/sneak/routewatch/internal/logger"
"git.eeqj.de/sneak/routewatch/internal/metrics"
"git.eeqj.de/sneak/routewatch/internal/routingtable"
"git.eeqj.de/sneak/routewatch/internal/server"
@@ -35,7 +34,7 @@ type Dependencies struct {
RoutingTable *routingtable.RoutingTable
Streamer *streamer.Streamer
Server *server.Server
Logger *slog.Logger
Logger *logger.Logger
Config *config.Config
}
@@ -46,7 +45,7 @@ type RouteWatch struct {
streamer *streamer.Streamer
server *server.Server
snapshotter *snapshotter.Snapshotter
logger *slog.Logger
logger *logger.Logger
maxRuntime time.Duration
shutdown bool
mu sync.Mutex
@@ -229,34 +228,11 @@ func (rw *RouteWatch) logRoutingTableStats(ctx context.Context) {
}
}
// NewLogger creates a structured logger
func NewLogger() *slog.Logger {
level := slog.LevelInfo
if debug := os.Getenv("DEBUG"); strings.Contains(debug, "routewatch") {
level = slog.LevelDebug
}
opts := &slog.HandlerOptions{
Level: level,
}
var handler slog.Handler
if os.Stdout.Name() != "/dev/stdout" || os.Getenv("TERM") == "" {
// Not a terminal, use JSON
handler = slog.NewJSONHandler(os.Stdout, opts)
} else {
// Terminal, use text
handler = slog.NewTextHandler(os.Stdout, opts)
}
return slog.New(handler)
}
// getModule provides all fx dependencies
func getModule() fx.Option {
return fx.Options(
fx.Provide(
NewLogger,
logger.New,
config.New,
metrics.New,
fx.Annotate(