Skip to content

Commit c6933a3

Browse files
committed
Move logger subsystem variables to internal package
This will allow the loader package to pass in appropriate logger variables for the subsystems that it initializes.
1 parent dc82294 commit c6933a3

File tree

5 files changed

+121
-98
lines changed

5 files changed

+121
-98
lines changed

config.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121

2222
"decred.org/dcrwallet/v3/errors"
2323
"decred.org/dcrwallet/v3/internal/cfgutil"
24+
"decred.org/dcrwallet/v3/internal/loggers"
2425
"decred.org/dcrwallet/v3/internal/netparams"
2526
"decred.org/dcrwallet/v3/version"
2627
"decred.org/dcrwallet/v3/wallet"
@@ -518,7 +519,7 @@ func loadConfig(ctx context.Context) (*config, []string, error) {
518519

519520
// Initialize log rotation. After log rotation has been initialized, the
520521
// logger variables may be used.
521-
initLogRotator(filepath.Join(cfg.LogDir.Value, defaultLogFilename), logsize)
522+
loggers.InitLogRotator(filepath.Join(cfg.LogDir.Value, defaultLogFilename), logsize)
522523
}
523524

524525
// Special show command to list supported subsystems and exit.

dcrwallet.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"decred.org/dcrwallet/v3/chain"
2222
"decred.org/dcrwallet/v3/errors"
2323
ldr "decred.org/dcrwallet/v3/internal/loader"
24+
"decred.org/dcrwallet/v3/internal/loggers"
2425
"decred.org/dcrwallet/v3/internal/prompt"
2526
"decred.org/dcrwallet/v3/internal/rpc/rpcserver"
2627
"decred.org/dcrwallet/v3/internal/vsp"
@@ -83,11 +84,7 @@ func run(ctx context.Context) error {
8384
return err
8485
}
8586
cfg = tcfg
86-
defer func() {
87-
if logRotator != nil {
88-
logRotator.Close()
89-
}
90-
}()
87+
defer loggers.CloseLogRotator()
9188

9289
// Show version at startup.
9390
log.Infof("Version %s (Go version %s %s/%s)", version.String(), runtime.Version(),
@@ -575,7 +572,7 @@ func rpcSyncLoop(ctx context.Context, w *wallet.Wallet) {
575572
})
576573
err := syncer.Run(ctx)
577574
if err != nil {
578-
syncLog.Errorf("Wallet synchronization stopped: %v", err)
575+
loggers.SyncLog.Errorf("Wallet synchronization stopped: %v", err)
579576
select {
580577
case <-ctx.Done():
581578
return

internal/loggers/loggers.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Copyright (c) 2023 The Decred developers
2+
// Use of this source code is governed by an ISC
3+
// license that can be found in the LICENSE file.
4+
5+
package loggers
6+
7+
import (
8+
"fmt"
9+
"os"
10+
"path/filepath"
11+
12+
"github.com/decred/slog"
13+
"github.com/jrick/logrotate/rotator"
14+
)
15+
16+
// logWriter implements an io.Writer that outputs to both standard output and
17+
// the write-end pipe of an initialized log rotator.
18+
type logWriter struct{}
19+
20+
func (logWriter) Write(p []byte) (n int, err error) {
21+
os.Stdout.Write(p)
22+
if logRotator != nil {
23+
logRotator.Write(p)
24+
}
25+
return len(p), nil
26+
}
27+
28+
// Loggers per subsystem. A single backend logger is created and all subsytem
29+
// loggers created from it will write to the backend. When adding new
30+
// subsystems, add the subsystem logger variable here and to the
31+
// subsystemLoggers map.
32+
//
33+
// Loggers can not be used before the log rotator has been initialized with a
34+
// log file. This must be performed early during application startup by calling
35+
// initLogRotator.
36+
var (
37+
// backendLog is the logging backend used to create all subsystem loggers.
38+
// The backend must not be used before the log rotator has been initialized,
39+
// or data races and/or nil pointer dereferences will occur.
40+
backendLog = slog.NewBackend(logWriter{})
41+
42+
// logRotator is one of the logging outputs. It should be closed on
43+
// application shutdown.
44+
logRotator *rotator.Rotator
45+
46+
MainLog = backendLog.Logger("DCRW")
47+
LoaderLog = backendLog.Logger("LODR")
48+
WalletLog = backendLog.Logger("WLLT")
49+
TkbyLog = backendLog.Logger("TKBY")
50+
SyncLog = backendLog.Logger("SYNC")
51+
GrpcLog = backendLog.Logger("GRPC")
52+
JsonrpcLog = backendLog.Logger("RPCS")
53+
CmgrLog = backendLog.Logger("CMGR")
54+
VspcLog = backendLog.Logger("VSPC")
55+
)
56+
57+
// InitLogRotator initializes the logging rotater to write logs to logFile and
58+
// create roll files in the same directory. logSize is the size in KiB after
59+
// which a log file will be rotated and compressed.
60+
//
61+
// This function must be called before the package-global log rotater variables
62+
// are used.
63+
func InitLogRotator(logFile string, logSize int64) {
64+
logDir, _ := filepath.Split(logFile)
65+
err := os.MkdirAll(logDir, 0700)
66+
if err != nil {
67+
fmt.Fprintf(os.Stderr, "failed to create log directory: %v\n", err)
68+
os.Exit(1)
69+
}
70+
r, err := rotator.New(logFile, logSize, false, 0)
71+
if err != nil {
72+
fmt.Fprintf(os.Stderr, "failed to create file rotator: %v\n", err)
73+
os.Exit(1)
74+
}
75+
76+
logRotator = r
77+
}
78+
79+
// CloseLogRotator closes the log rotator, syncing all file writes, if the
80+
// rotator was initialized.
81+
func CloseLogRotator() error {
82+
if logRotator == nil {
83+
return nil
84+
}
85+
86+
return logRotator.Close()
87+
}

log.go

Lines changed: 23 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,11 @@
66
package main
77

88
import (
9-
"fmt"
109
"os"
11-
"path/filepath"
1210

1311
"decred.org/dcrwallet/v3/chain"
1412
"decred.org/dcrwallet/v3/internal/loader"
13+
"decred.org/dcrwallet/v3/internal/loggers"
1514
"decred.org/dcrwallet/v3/internal/rpc/jsonrpc"
1615
"decred.org/dcrwallet/v3/internal/rpc/rpcserver"
1716
"decred.org/dcrwallet/v3/internal/vsp"
@@ -22,98 +21,36 @@ import (
2221
"decred.org/dcrwallet/v3/wallet/udb"
2322
"github.com/decred/dcrd/connmgr/v3"
2423
"github.com/decred/slog"
25-
"github.com/jrick/logrotate/rotator"
2624
)
2725

28-
// logWriter implements an io.Writer that outputs to both standard output and
29-
// the write-end pipe of an initialized log rotator.
30-
type logWriter struct{}
31-
32-
func (logWriter) Write(p []byte) (n int, err error) {
33-
os.Stdout.Write(p)
34-
if logRotator != nil {
35-
logRotator.Write(p)
36-
}
37-
return len(p), nil
38-
}
39-
40-
// Loggers per subsystem. A single backend logger is created and all subsytem
41-
// loggers created from it will write to the backend. When adding new
42-
// subsystems, add the subsystem logger variable here and to the
43-
// subsystemLoggers map.
44-
//
45-
// Loggers can not be used before the log rotator has been initialized with a
46-
// log file. This must be performed early during application startup by calling
47-
// initLogRotator.
48-
var (
49-
// backendLog is the logging backend used to create all subsystem loggers.
50-
// The backend must not be used before the log rotator has been initialized,
51-
// or data races and/or nil pointer dereferences will occur.
52-
backendLog = slog.NewBackend(logWriter{})
53-
54-
// logRotator is one of the logging outputs. It should be closed on
55-
// application shutdown.
56-
logRotator *rotator.Rotator
57-
58-
log = backendLog.Logger("DCRW")
59-
loaderLog = backendLog.Logger("LODR")
60-
walletLog = backendLog.Logger("WLLT")
61-
tkbyLog = backendLog.Logger("TKBY")
62-
syncLog = backendLog.Logger("SYNC")
63-
grpcLog = backendLog.Logger("GRPC")
64-
jsonrpcLog = backendLog.Logger("RPCS")
65-
cmgrLog = backendLog.Logger("CMGR")
66-
vspcLog = backendLog.Logger("VSPC")
67-
)
26+
var log = loggers.MainLog
6827

6928
// Initialize package-global logger variables.
7029
func init() {
71-
loader.UseLogger(loaderLog)
72-
wallet.UseLogger(walletLog)
73-
udb.UseLogger(walletLog)
74-
ticketbuyer.UseLogger(tkbyLog)
75-
chain.UseLogger(syncLog)
76-
spv.UseLogger(syncLog)
77-
p2p.UseLogger(syncLog)
78-
rpcserver.UseLogger(grpcLog)
79-
jsonrpc.UseLogger(jsonrpcLog)
80-
connmgr.UseLogger(cmgrLog)
81-
vsp.UseLogger(vspcLog)
30+
loader.UseLogger(loggers.LoaderLog)
31+
wallet.UseLogger(loggers.WalletLog)
32+
udb.UseLogger(loggers.WalletLog)
33+
ticketbuyer.UseLogger(loggers.TkbyLog)
34+
chain.UseLogger(loggers.SyncLog)
35+
spv.UseLogger(loggers.SyncLog)
36+
p2p.UseLogger(loggers.SyncLog)
37+
rpcserver.UseLogger(loggers.GrpcLog)
38+
jsonrpc.UseLogger(loggers.JsonrpcLog)
39+
connmgr.UseLogger(loggers.CmgrLog)
40+
vsp.UseLogger(loggers.VspcLog)
8241
}
8342

8443
// subsystemLoggers maps each subsystem identifier to its associated logger.
8544
var subsystemLoggers = map[string]slog.Logger{
86-
"DCRW": log,
87-
"LODR": loaderLog,
88-
"WLLT": walletLog,
89-
"TKBY": tkbyLog,
90-
"SYNC": syncLog,
91-
"GRPC": grpcLog,
92-
"RPCS": jsonrpcLog,
93-
"CMGR": cmgrLog,
94-
"VSPC": vspcLog,
95-
}
96-
97-
// initLogRotator initializes the logging rotater to write logs to logFile and
98-
// create roll files in the same directory. logSize is the size in KiB after
99-
// which a log file will be rotated and compressed.
100-
//
101-
// This function must be called before the package-global log rotater variables
102-
// are used.
103-
func initLogRotator(logFile string, logSize int64) {
104-
logDir, _ := filepath.Split(logFile)
105-
err := os.MkdirAll(logDir, 0700)
106-
if err != nil {
107-
fmt.Fprintf(os.Stderr, "failed to create log directory: %v\n", err)
108-
os.Exit(1)
109-
}
110-
r, err := rotator.New(logFile, logSize, false, 0)
111-
if err != nil {
112-
fmt.Fprintf(os.Stderr, "failed to create file rotator: %v\n", err)
113-
os.Exit(1)
114-
}
115-
116-
logRotator = r
45+
"DCRW": loggers.MainLog,
46+
"LODR": loggers.LoaderLog,
47+
"WLLT": loggers.WalletLog,
48+
"TKBY": loggers.TkbyLog,
49+
"SYNC": loggers.SyncLog,
50+
"GRPC": loggers.GrpcLog,
51+
"RPCS": loggers.JsonrpcLog,
52+
"CMGR": loggers.CmgrLog,
53+
"VSPC": loggers.VspcLog,
11754
}
11855

11956
// setLogLevel sets the logging level for provided subsystem. Invalid
@@ -147,6 +84,6 @@ func setLogLevels(logLevel string) {
14784
func fatalf(format string, args ...interface{}) {
14885
log.Errorf(format, args...)
14986
os.Stdout.Sync()
150-
logRotator.Close()
87+
loggers.CloseLogRotator()
15188
os.Exit(1)
15289
}

rpcserver.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"decred.org/dcrwallet/v3/errors"
2626
"decred.org/dcrwallet/v3/internal/cfgutil"
2727
"decred.org/dcrwallet/v3/internal/loader"
28+
"decred.org/dcrwallet/v3/internal/loggers"
2829
"decred.org/dcrwallet/v3/internal/rpc/jsonrpc"
2930
"decred.org/dcrwallet/v3/internal/rpc/rpcserver"
3031

@@ -401,7 +402,7 @@ func serviceName(method string) string {
401402
func interceptStreaming(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
402403
p, ok := peer.FromContext(ss.Context())
403404
if ok {
404-
grpcLog.Debugf("Streaming method %s invoked by %s", info.FullMethod,
405+
loggers.GrpcLog.Debugf("Streaming method %s invoked by %s", info.FullMethod,
405406
p.Addr.String())
406407
}
407408
err := rpcserver.ServiceReady(serviceName(info.FullMethod))
@@ -410,12 +411,12 @@ func interceptStreaming(srv interface{}, ss grpc.ServerStream, info *grpc.Stream
410411
}
411412
err = handler(srv, ss)
412413
if err != nil && ok {
413-
logf := grpcLog.Errorf
414+
logf := loggers.GrpcLog.Errorf
414415
if status.Code(err) == codes.Canceled && done(ss.Context()) {
415416
// Canceled contexts in streaming calls are expected
416417
// when client-initiated, so only log them with debug
417418
// level to reduce clutter.
418-
logf = grpcLog.Debugf
419+
logf = loggers.GrpcLog.Debugf
419420
}
420421

421422
logf("Streaming method %s invoked by %s errored: %v",
@@ -427,7 +428,7 @@ func interceptStreaming(srv interface{}, ss grpc.ServerStream, info *grpc.Stream
427428
func interceptUnary(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
428429
p, ok := peer.FromContext(ctx)
429430
if ok {
430-
grpcLog.Debugf("Unary method %s invoked by %s", info.FullMethod,
431+
loggers.GrpcLog.Debugf("Unary method %s invoked by %s", info.FullMethod,
431432
p.Addr.String())
432433
}
433434
err = rpcserver.ServiceReady(serviceName(info.FullMethod))
@@ -436,7 +437,7 @@ func interceptUnary(ctx context.Context, req interface{}, info *grpc.UnaryServer
436437
}
437438
resp, err = handler(ctx, req)
438439
if err != nil && ok {
439-
grpcLog.Errorf("Unary method %s invoked by %s errored: %v",
440+
loggers.GrpcLog.Errorf("Unary method %s invoked by %s errored: %v",
440441
info.FullMethod, p.Addr.String(), err)
441442
}
442443
return resp, err

0 commit comments

Comments
 (0)