decred.org/dcrwallet/v3@v3.1.0/internal/loggers/loggers.go (about)

     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  }