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,12 +5,12 @@ import (
"database/sql"
_ "embed"
"fmt"
"log/slog"
"os"
"path/filepath"
"time"
"git.eeqj.de/sneak/routewatch/internal/config"
"git.eeqj.de/sneak/routewatch/internal/logger"
"git.eeqj.de/sneak/routewatch/pkg/asinfo"
"github.com/google/uuid"
_ "github.com/mattn/go-sqlite3" // CGO SQLite driver
@@ -24,12 +24,12 @@ const dirPermissions = 0750 // rwxr-x---
// Database manages the SQLite database connection and operations.
type Database struct {
db *sql.DB
logger *slog.Logger
logger *logger.Logger
path string
}
// New creates a new database connection and initializes the schema.
func New(cfg *config.Config, logger *slog.Logger) (*Database, error) {
func New(cfg *config.Config, logger *logger.Logger) (*Database, error) {
dbPath := filepath.Join(cfg.GetStateDir(), "db.sqlite")
// Log database path
@@ -348,28 +348,24 @@ func (d *Database) GetStats() (Stats, error) {
var stats Stats
// Count ASNs
d.logger.Info("Counting ASNs")
err := d.queryRow("SELECT COUNT(*) FROM asns").Scan(&stats.ASNs)
if err != nil {
return stats, err
}
// Count prefixes
d.logger.Info("Counting prefixes")
err = d.queryRow("SELECT COUNT(*) FROM prefixes").Scan(&stats.Prefixes)
if err != nil {
return stats, err
}
// Count IPv4 and IPv6 prefixes
d.logger.Info("Counting IPv4 prefixes")
const ipVersionV4 = 4
err = d.queryRow("SELECT COUNT(*) FROM prefixes WHERE ip_version = ?", ipVersionV4).Scan(&stats.IPv4Prefixes)
if err != nil {
return stats, err
}
d.logger.Info("Counting IPv6 prefixes")
const ipVersionV6 = 6
err = d.queryRow("SELECT COUNT(*) FROM prefixes WHERE ip_version = ?", ipVersionV6).Scan(&stats.IPv6Prefixes)
if err != nil {
@@ -377,14 +373,12 @@ func (d *Database) GetStats() (Stats, error) {
}
// Count peerings
d.logger.Info("Counting peerings")
err = d.queryRow("SELECT COUNT(*) FROM asn_peerings").Scan(&stats.Peerings)
if err != nil {
return stats, err
}
// Get database file size
d.logger.Info("Getting database file size")
fileInfo, err := os.Stat(d.path)
if err != nil {
d.logger.Warn("Failed to get database file size", "error", err)
@@ -393,7 +387,5 @@ func (d *Database) GetStats() (Stats, error) {
stats.FileSizeBytes = fileInfo.Size()
}
d.logger.Info("Stats collection complete")
return stats, nil
}

View File

@@ -3,14 +3,15 @@ package database
import (
"context"
"database/sql"
"log/slog"
"time"
"git.eeqj.de/sneak/routewatch/internal/logger"
)
const slowQueryThreshold = 50 * time.Millisecond
// logSlowQuery logs queries that take longer than slowQueryThreshold
func logSlowQuery(logger *slog.Logger, query string, start time.Time) {
func logSlowQuery(logger *logger.Logger, query string, start time.Time) {
elapsed := time.Since(start)
if elapsed > slowQueryThreshold {
logger.Debug("Slow query", "query", query, "duration", elapsed)
@@ -47,7 +48,7 @@ func (d *Database) exec(query string, args ...interface{}) error {
// loggingTx wraps sql.Tx to log slow queries
type loggingTx struct {
*sql.Tx
logger *slog.Logger
logger *logger.Logger
}
// QueryRow wraps sql.Tx.QueryRow to log slow queries