Skip to content

Commit

Permalink
vspd: Decouple config loading & log initialization
Browse files Browse the repository at this point in the history
Loading config and preparing loggers are two separate concepts which
should be handled individually. Nesting one inside the other makes
little sense and complicates reusing the code.
  • Loading branch information
jholdstock committed May 20, 2024
1 parent bb082cf commit fe917b1
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 27 deletions.
23 changes: 0 additions & 23 deletions cmd/vspd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (

"github.com/decred/dcrd/dcrutil/v4"
"github.com/decred/dcrd/hdkeychain/v3"
"github.com/decred/slog"
"github.com/decred/vspd/database"
"github.com/decred/vspd/internal/config"
"github.com/decred/vspd/internal/version"
Expand Down Expand Up @@ -76,9 +75,6 @@ type vspdConfig struct {
HomeDir string `long:"homedir" no-ini:"true" description:"Path to application home directory. Used for storing VSP database and logs."`
ConfigFile string `long:"configfile" no-ini:"true" description:"Path to configuration file."`

logBackend *slog.Backend
logLevel slog.Level

dbPath string
network *config.Network
dcrdCert []byte
Expand Down Expand Up @@ -406,19 +402,6 @@ func loadConfig() (*vspdConfig, error) {
return nil, fmt.Errorf("failed to create data directory: %w", err)
}

// Initialize loggers and log rotation.
logDir := filepath.Join(cfg.HomeDir, "logs", cfg.network.Name)
cfg.logBackend, err = newLogBackend(logDir, appName, cfg.MaxLogSize, cfg.LogsToKeep)
if err != nil {
return nil, fmt.Errorf("failed to initialize logger: %w", err)
}

var ok bool
cfg.logLevel, ok = slog.LevelFromString(cfg.LogLevel)
if !ok {
return nil, fmt.Errorf("unknown log level: %s", cfg.LogLevel)
}

// Set the database path
cfg.dbPath = filepath.Join(dataDir, defaultDBFilename)

Expand Down Expand Up @@ -454,9 +437,3 @@ func loadConfig() (*vspdConfig, error) {

return &cfg, nil
}

func (cfg *vspdConfig) logger(subsystem string) slog.Logger {
log := cfg.logBackend.Logger(subsystem)
log.SetLevel(cfg.logLevel)
return log
}
39 changes: 35 additions & 4 deletions cmd/vspd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ package main
import (
"fmt"
"os"
"path/filepath"
"runtime"
"sync"
"time"

"github.com/decred/dcrd/wire"
"github.com/decred/slog"
"github.com/decred/vspd/database"
"github.com/decred/vspd/internal/config"
"github.com/decred/vspd/internal/signal"
Expand All @@ -33,6 +35,29 @@ func main() {
os.Exit(run())
}

// initLogging uses the provided vspd config to create a logging backend, and
// returns a function which can be used to create ready-to-use subsystem
// loggers.
func initLogging(cfg *vspdConfig) (func(subsystem string) slog.Logger, error) {
logDir := filepath.Join(cfg.HomeDir, "logs", cfg.network.Name)
backend, err := newLogBackend(logDir, "vspd", cfg.MaxLogSize, cfg.LogsToKeep)
if err != nil {
return nil, fmt.Errorf("failed to initialize logger: %w", err)
}

var ok bool
level, ok := slog.LevelFromString(cfg.LogLevel)
if !ok {
return nil, fmt.Errorf("unknown log level: %q", cfg.LogLevel)
}

return func(subsystem string) slog.Logger {
log := backend.Logger(subsystem)
log.SetLevel(level)
return log
}, nil
}

// run is the real main function for vspd. It is necessary to work around the
// fact that deferred functions do not run when os.Exit() is called.
func run() int {
Expand All @@ -43,7 +68,13 @@ func run() int {
return 1
}

log := cfg.logger("VSP")
makeLogger, err := initLogging(cfg)
if err != nil {
fmt.Fprintf(os.Stderr, "initLogging error: %v\n", err)
return 1
}

log := makeLogger("VSP")

// Create a context that is canceled when a shutdown request is received
// through an interrupt signal such as SIGINT (Ctrl+C).
Expand All @@ -66,15 +97,15 @@ func run() int {
}

// Open database.
db, err := database.Open(cfg.dbPath, cfg.logger(" DB"), maxVoteChangeRecords)
db, err := database.Open(cfg.dbPath, makeLogger(" DB"), maxVoteChangeRecords)
if err != nil {
log.Errorf("Failed to open database: %v", err)
return 1
}
const writeBackup = true
defer db.Close(writeBackup)

rpcLog := cfg.logger("RPC")
rpcLog := makeLogger("RPC")

// Create a channel to receive blockConnected notifications from dcrd.
blockNotifChan := make(chan *wire.BlockHeader)
Expand Down Expand Up @@ -102,7 +133,7 @@ func run() int {
MaxVoteChangeRecords: maxVoteChangeRecords,
VspdVersion: version.String(),
}
api, err := webapi.New(db, cfg.logger("API"), dcrd, wallets, apiCfg)
api, err := webapi.New(db, makeLogger("API"), dcrd, wallets, apiCfg)
if err != nil {
log.Errorf("Failed to initialize webapi: %v", err)
return 1
Expand Down

0 comments on commit fe917b1

Please sign in to comment.