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:
@@ -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(
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"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"
|
||||
@@ -164,7 +165,7 @@ func TestRouteWatchLiveFeed(t *testing.T) {
|
||||
mockDB := newMockStore()
|
||||
defer mockDB.Close()
|
||||
|
||||
logger := NewLogger()
|
||||
logger := logger.New()
|
||||
|
||||
// Create metrics tracker
|
||||
metricsTracker := metrics.New()
|
||||
|
||||
@@ -1,12 +1,3 @@
|
||||
package routewatch
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewLogger(t *testing.T) {
|
||||
logger := NewLogger()
|
||||
if logger == nil {
|
||||
t.Fatal("NewLogger returned nil")
|
||||
}
|
||||
}
|
||||
// Tests for routewatch package are in app_integration_test.go
|
||||
|
||||
@@ -2,12 +2,12 @@ package routewatch
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"git.eeqj.de/sneak/routewatch/internal/logger"
|
||||
"go.uber.org/fx"
|
||||
)
|
||||
|
||||
@@ -21,7 +21,7 @@ func CLIEntry() {
|
||||
app := fx.New(
|
||||
getModule(),
|
||||
fx.StopTimeout(shutdownTimeout), // Allow 60 seconds for graceful shutdown
|
||||
fx.Invoke(func(lc fx.Lifecycle, rw *RouteWatch, logger *slog.Logger) {
|
||||
fx.Invoke(func(lc fx.Lifecycle, rw *RouteWatch, logger *logger.Logger) {
|
||||
lc.Append(fx.Hook{
|
||||
OnStart: func(_ context.Context) error {
|
||||
go func() {
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package routewatch
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
|
||||
"git.eeqj.de/sneak/routewatch/internal/database"
|
||||
"git.eeqj.de/sneak/routewatch/internal/logger"
|
||||
"git.eeqj.de/sneak/routewatch/internal/ristypes"
|
||||
)
|
||||
|
||||
@@ -15,13 +14,13 @@ const (
|
||||
// DatabaseHandler handles BGP messages and stores them in the database
|
||||
type DatabaseHandler struct {
|
||||
db database.Store
|
||||
logger *slog.Logger
|
||||
logger *logger.Logger
|
||||
}
|
||||
|
||||
// NewDatabaseHandler creates a new database handler
|
||||
func NewDatabaseHandler(
|
||||
db database.Store,
|
||||
logger *slog.Logger,
|
||||
logger *logger.Logger,
|
||||
) *DatabaseHandler {
|
||||
return &DatabaseHandler{
|
||||
db: db,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package routewatch
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"git.eeqj.de/sneak/routewatch/internal/database"
|
||||
"git.eeqj.de/sneak/routewatch/internal/logger"
|
||||
"git.eeqj.de/sneak/routewatch/internal/ristypes"
|
||||
)
|
||||
|
||||
@@ -23,7 +23,7 @@ const (
|
||||
// BatchedDatabaseHandler handles BGP messages and stores them in the database using batched operations
|
||||
type BatchedDatabaseHandler struct {
|
||||
db database.Store
|
||||
logger *slog.Logger
|
||||
logger *logger.Logger
|
||||
|
||||
// Batching
|
||||
mu sync.Mutex
|
||||
@@ -54,7 +54,7 @@ type peeringOp struct {
|
||||
// NewBatchedDatabaseHandler creates a new batched database handler
|
||||
func NewBatchedDatabaseHandler(
|
||||
db database.Store,
|
||||
logger *slog.Logger,
|
||||
logger *logger.Logger,
|
||||
) *BatchedDatabaseHandler {
|
||||
h := &BatchedDatabaseHandler{
|
||||
db: db,
|
||||
|
||||
@@ -1,19 +1,23 @@
|
||||
package routewatch
|
||||
|
||||
import (
|
||||
"git.eeqj.de/sneak/routewatch/internal/logger"
|
||||
"git.eeqj.de/sneak/routewatch/internal/ristypes"
|
||||
"log/slog"
|
||||
)
|
||||
|
||||
// SimpleHandler is a basic implementation of streamer.MessageHandler
|
||||
type SimpleHandler struct {
|
||||
logger *slog.Logger
|
||||
logger *logger.Logger
|
||||
messageTypes []string
|
||||
callback func(*ristypes.RISMessage)
|
||||
}
|
||||
|
||||
// NewSimpleHandler creates a handler that accepts specific message types
|
||||
func NewSimpleHandler(logger *slog.Logger, messageTypes []string, callback func(*ristypes.RISMessage)) *SimpleHandler {
|
||||
func NewSimpleHandler(
|
||||
logger *logger.Logger,
|
||||
messageTypes []string,
|
||||
callback func(*ristypes.RISMessage),
|
||||
) *SimpleHandler {
|
||||
return &SimpleHandler{
|
||||
logger: logger,
|
||||
messageTypes: messageTypes,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package routewatch
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"strconv"
|
||||
|
||||
"git.eeqj.de/sneak/routewatch/internal/database"
|
||||
"git.eeqj.de/sneak/routewatch/internal/logger"
|
||||
"git.eeqj.de/sneak/routewatch/internal/ristypes"
|
||||
)
|
||||
|
||||
@@ -16,11 +16,11 @@ const (
|
||||
// PeerHandler tracks BGP peers from all message types
|
||||
type PeerHandler struct {
|
||||
db database.Store
|
||||
logger *slog.Logger
|
||||
logger *logger.Logger
|
||||
}
|
||||
|
||||
// NewPeerHandler creates a new peer tracking handler
|
||||
func NewPeerHandler(db database.Store, logger *slog.Logger) *PeerHandler {
|
||||
func NewPeerHandler(db database.Store, logger *logger.Logger) *PeerHandler {
|
||||
return &PeerHandler{
|
||||
db: db,
|
||||
logger: logger,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package routewatch
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"git.eeqj.de/sneak/routewatch/internal/database"
|
||||
"git.eeqj.de/sneak/routewatch/internal/logger"
|
||||
"git.eeqj.de/sneak/routewatch/internal/ristypes"
|
||||
)
|
||||
|
||||
@@ -24,7 +24,7 @@ const (
|
||||
// BatchedPeerHandler tracks BGP peers from all message types using batched operations
|
||||
type BatchedPeerHandler struct {
|
||||
db database.Store
|
||||
logger *slog.Logger
|
||||
logger *logger.Logger
|
||||
|
||||
// Batching
|
||||
mu sync.Mutex
|
||||
@@ -42,7 +42,7 @@ type peerUpdate struct {
|
||||
}
|
||||
|
||||
// NewBatchedPeerHandler creates a new batched peer tracking handler
|
||||
func NewBatchedPeerHandler(db database.Store, logger *slog.Logger) *BatchedPeerHandler {
|
||||
func NewBatchedPeerHandler(db database.Store, logger *logger.Logger) *BatchedPeerHandler {
|
||||
h := &BatchedPeerHandler{
|
||||
db: db,
|
||||
logger: logger,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package routewatch
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"strconv"
|
||||
|
||||
"git.eeqj.de/sneak/routewatch/internal/logger"
|
||||
"git.eeqj.de/sneak/routewatch/internal/ristypes"
|
||||
"git.eeqj.de/sneak/routewatch/internal/routingtable"
|
||||
"github.com/google/uuid"
|
||||
@@ -17,11 +17,11 @@ const (
|
||||
// RoutingTableHandler handles BGP messages and updates the in-memory routing table
|
||||
type RoutingTableHandler struct {
|
||||
rt *routingtable.RoutingTable
|
||||
logger *slog.Logger
|
||||
logger *logger.Logger
|
||||
}
|
||||
|
||||
// NewRoutingTableHandler creates a new routing table handler
|
||||
func NewRoutingTableHandler(rt *routingtable.RoutingTable, logger *slog.Logger) *RoutingTableHandler {
|
||||
func NewRoutingTableHandler(rt *routingtable.RoutingTable, logger *logger.Logger) *RoutingTableHandler {
|
||||
return &RoutingTableHandler{
|
||||
rt: rt,
|
||||
logger: logger,
|
||||
|
||||
Reference in New Issue
Block a user