diff --git a/p2p/kademlia/store/sqlite/replication.go b/p2p/kademlia/store/sqlite/replication.go index 486094ca..c900ea54 100644 --- a/p2p/kademlia/store/sqlite/replication.go +++ b/p2p/kademlia/store/sqlite/replication.go @@ -243,6 +243,13 @@ func (s *Store) StoreBatchRepKeys(values []string, id string, ip string, port ui func (s *Store) GetKeysForReplication(ctx context.Context, from time.Time, to time.Time) domain.KeysWithTimestamp { var results []domain.KeyWithTimestamp query := `SELECT key, createdAt FROM data WHERE createdAt > ? AND createdAt < ? ORDER BY createdAt ASC` + + logtrace.Debug(ctx, "fetching keys for replication", logtrace.Fields{ + logtrace.FieldModule: "p2p", + "from_time": from, + "to_time": to, + }) + if err := s.db.Select(&results, query, from, to); err != nil { logtrace.Error(ctx, "failed to get records for replication", logtrace.Fields{ logtrace.FieldModule: "p2p", @@ -250,6 +257,11 @@ func (s *Store) GetKeysForReplication(ctx context.Context, from time.Time, to ti return nil } + logtrace.Debug(ctx, "Successfully fetched keys for replication", logtrace.Fields{ + logtrace.FieldModule: "p2p", + "keys_count": len(results), + }) + return domain.KeysWithTimestamp(results) } diff --git a/p2p/kademlia/store/sqlite/sqlite.go b/p2p/kademlia/store/sqlite/sqlite.go index 917c9afc..ec2d8482 100644 --- a/p2p/kademlia/store/sqlite/sqlite.go +++ b/p2p/kademlia/store/sqlite/sqlite.go @@ -74,7 +74,7 @@ func NewStore(ctx context.Context, dataDir string, cloud cloud.Storage, mst *Mig quit: make(chan bool), } - logtrace.Info(ctx, "p2p data dir", logtrace.Fields{logtrace.FieldModule: "p2p", "data_dir": dataDir}) + logtrace.Debug(ctx, "p2p data dir", logtrace.Fields{logtrace.FieldModule: "p2p", "data_dir": dataDir}) if _, err := os.Stat(dataDir); os.IsNotExist(err) { if err := os.MkdirAll(dataDir, 0750); err != nil { return nil, fmt.Errorf("mkdir %q: %w", dataDir, err) @@ -131,18 +131,18 @@ func NewStore(ctx context.Context, dataDir string, cloud cloud.Storage, mst *Mig logtrace.Error(ctx, "URGENT! unable to create datatype column in p2p database", logtrace.Fields{logtrace.FieldError: err.Error()}) } - logtrace.Info(ctx, "p2p database creating index on key column", logtrace.Fields{logtrace.FieldModule: "p2p"}) + logtrace.Debug(ctx, "p2p database creating index on key column", logtrace.Fields{logtrace.FieldModule: "p2p"}) _, err = db.Exec("CREATE INDEX IF NOT EXISTS idx_key ON data(key);") if err != nil { logtrace.Error(ctx, "URGENT! unable to create index on key column in p2p database", logtrace.Fields{logtrace.FieldError: err.Error()}) } - logtrace.Info(ctx, "p2p database created index on key column", logtrace.Fields{logtrace.FieldModule: "p2p"}) + logtrace.Debug(ctx, "p2p database created index on key column", logtrace.Fields{logtrace.FieldModule: "p2p"}) _, err = db.Exec("CREATE INDEX IF NOT EXISTS idx_createdat ON data(createdAt);") if err != nil { logtrace.Error(ctx, "URGENT! unable to create index on createdAt column in p2p database", logtrace.Fields{logtrace.FieldError: err.Error()}) } - logtrace.Info(ctx, "p2p database created index on createdAt column", logtrace.Fields{logtrace.FieldModule: "p2p"}) + logtrace.Debug(ctx, "p2p database created index on createdAt column", logtrace.Fields{logtrace.FieldModule: "p2p"}) pragmas := []string{ "PRAGMA journal_mode=WAL;", diff --git a/pkg/logtrace/log.go b/pkg/logtrace/log.go index a6db8bb3..8cfa77a6 100644 --- a/pkg/logtrace/log.go +++ b/pkg/logtrace/log.go @@ -18,10 +18,22 @@ type ContextKey string const CorrelationIDKey ContextKey = "correlation_id" // Setup initializes the logger with a specified log level -func Setup(serviceName, env string, level slog.Level) { +func Setup(serviceName, env string, level string) { + var slogLevel slog.Level + switch level { + case "warn": + slogLevel = slog.LevelWarn + case "error": + slogLevel = slog.LevelError + case "debug": + slogLevel = slog.LevelDebug + default: + slogLevel = slog.LevelInfo + } + opts := &slog.HandlerOptions{ - AddSource: true, - Level: level, + AddSource: false, + Level: slogLevel, } hostname, _ := os.Hostname() @@ -32,23 +44,26 @@ func Setup(serviceName, env string, level slog.Level) { } // log logs a message with additional fields using the specified log function. -func log(logFunc LogLevel, message string, fields Fields) { +func log(logLevel slog.Level, logFunc LogLevel, message string, fields Fields) { fieldArgs := make([]interface{}, 0, len(fields)*2+1) - pc, file, line, ok := runtime.Caller(2) - if ok { - details := runtime.FuncForPC(pc) - fieldArgs = append(fieldArgs, slog.Group( - "source", - slog.Attr{Key: "filename", Value: slog.StringValue(file)}, - slog.Attr{Key: "lineno", Value: slog.IntValue(line)}, - slog.Attr{Key: "function", Value: slog.StringValue(details.Name())}, - )) + // Only attach source info for TRACE/DEBUG level + if logLevel == slog.LevelDebug || logLevel == slog.LevelError { + if pc, file, line, ok := runtime.Caller(2); ok { + details := runtime.FuncForPC(pc) + fieldArgs = append(fieldArgs, slog.Group( + "source", + slog.String("filename", file), + slog.Int("lineno", line), + slog.String("function", details.Name()), + )) + } } for key, value := range fields { fieldArgs = append(fieldArgs, slog.Any(key, value)) } + logFunc(message, fieldArgs...) } @@ -70,22 +85,22 @@ func addCorrelationID(ctx context.Context, fields Fields) Fields { // Error logs an error message with structured fields. func Error(ctx context.Context, message string, fields Fields) { - log(slog.Error, message, addCorrelationID(ctx, fields)) + log(slog.LevelError, slog.Error, message, addCorrelationID(ctx, fields)) } // Info logs an informational message with structured fields. func Info(ctx context.Context, message string, fields Fields) { - log(slog.Info, message, addCorrelationID(ctx, fields)) + log(slog.LevelInfo, slog.Info, message, addCorrelationID(ctx, fields)) } // Warn logs a warning message with structured fields. func Warn(ctx context.Context, message string, fields Fields) { - log(slog.Warn, message, addCorrelationID(ctx, fields)) + log(slog.LevelWarn, slog.Warn, message, addCorrelationID(ctx, fields)) } // Debug logs a debug message with structured fields. func Debug(ctx context.Context, message string, fields Fields) { - log(slog.Debug, message, addCorrelationID(ctx, fields)) + log(slog.LevelDebug, slog.Debug, message, addCorrelationID(ctx, fields)) } // CtxWithCorrelationID stores a correlation ID inside the context. diff --git a/supernode/cmd/start.go b/supernode/cmd/start.go index 3d5e72e1..6f01fc67 100644 --- a/supernode/cmd/start.go +++ b/supernode/cmd/start.go @@ -3,7 +3,6 @@ package cmd import ( "context" "fmt" - "log/slog" "os" "os/signal" "syscall" @@ -35,8 +34,7 @@ var startCmd = &cobra.Command{ The supernode will connect to the Lumera network and begin participating in the network.`, RunE: func(cmd *cobra.Command, args []string) error { // Initialize logging - logLevel := slog.LevelInfo - logtrace.Setup("supernode", "dev", logLevel) + logtrace.Setup("supernode", "dev", appConfig.LogConfig.Level) // Create context with correlation ID for tracing ctx := logtrace.CtxWithCorrelationID(context.Background(), "supernode-start") diff --git a/supernode/config.yml b/supernode/config.yml index 90c7bed4..9e3fc579 100644 --- a/supernode/config.yml +++ b/supernode/config.yml @@ -27,3 +27,7 @@ lumera: # RaptorQ Configuration raptorq: files_dir: "raptorq_files" + +#Logging Configuration +log: + level: "info" #debug, info, warn, error diff --git a/supernode/config/config.go b/supernode/config/config.go index b61d3f06..0c67f14c 100644 --- a/supernode/config/config.go +++ b/supernode/config/config.go @@ -39,12 +39,17 @@ type RaptorQConfig struct { FilesDir string `yaml:"files_dir"` } +type LogConfig struct { + Level string `yaml:"level"` +} + type Config struct { SupernodeConfig `yaml:"supernode"` KeyringConfig `yaml:"keyring"` P2PConfig `yaml:"p2p"` LumeraClientConfig `yaml:"lumera"` RaptorQConfig `yaml:"raptorq"` + LogConfig `yaml:"log"` // Store base directory (not from YAML) BaseDir string `yaml:"-"` @@ -135,11 +140,12 @@ func LoadConfig(filename string, baseDir string) (*Config, error) { return nil, err } - logtrace.Info(ctx, "Configuration loaded successfully", logtrace.Fields{ + logtrace.Debug(ctx, "Configuration loaded successfully", logtrace.Fields{ "baseDir": baseDir, "keyringDir": config.GetKeyringDir(), "p2pDataDir": config.GetP2PDataDir(), "raptorqFilesDir": config.GetRaptorQFilesDir(), + "logLevel": config.LogConfig.Level, }) return &config, nil