decred.org/dcrdex@v1.0.5/client/app/log.go (about)

     1  // This code is available on the terms of the project LICENSE.md file,
     2  // also available online at https://blueoakcouncil.org/license/1.0.0.
     3  
     4  package app
     5  
     6  import (
     7  	"fmt"
     8  	"os"
     9  	"path/filepath"
    10  
    11  	"decred.org/dcrdex/client/asset"
    12  	"decred.org/dcrdex/dex"
    13  	"github.com/decred/slog"
    14  	"github.com/jrick/logrotate/rotator"
    15  )
    16  
    17  const (
    18  	maxLogRolls = 16
    19  )
    20  
    21  var (
    22  	// logRotator is one of the logging outputs. It should be closed on
    23  	// application shutdown.
    24  	logRotator         *rotator.Rotator
    25  	defaultLogLevelMap = map[string]slog.Level{asset.InternalNodeLoggerName: slog.LevelError}
    26  )
    27  
    28  // logWriter implements an io.Writer that outputs to a rotating log file.
    29  type logWriter struct {
    30  	*rotator.Rotator
    31  	stdout bool
    32  }
    33  
    34  // Write writes the data in p to the log file.
    35  func (w logWriter) Write(p []byte) (n int, err error) {
    36  	if w.stdout {
    37  		os.Stdout.Write(p)
    38  	}
    39  	return w.Rotator.Write(p)
    40  }
    41  
    42  // initLogging initializes the logging rotater to write logs to logFile and
    43  // create roll files in the same directory. initLogging must be called before
    44  // the package-global log rotator variables are used.
    45  func InitLogging(logFilename, lvl string, stdout bool, utc bool) (lm *dex.LoggerMaker, closeFn func()) {
    46  	logDirectory := filepath.Dir(logFilename)
    47  	err := os.MkdirAll(logDirectory, 0700)
    48  	if err != nil {
    49  		fmt.Fprintf(os.Stderr, "failed to create log directory: %v\n", err)
    50  		os.Exit(1)
    51  	}
    52  	logRotator, err = rotator.New(logFilename, 32*1024, false, maxLogRolls)
    53  	if err != nil {
    54  		fmt.Fprintf(os.Stderr, "failed to create file rotator: %v\n", err)
    55  		os.Exit(1)
    56  	}
    57  	if !stdout {
    58  		fmt.Println("Logging to", logFilename)
    59  	}
    60  	lm, err = dex.NewLoggerMaker(&logWriter{logRotator, stdout}, lvl, utc)
    61  	if err != nil {
    62  		fmt.Fprintf(os.Stderr, "failed to create custom logger: %v\n", err)
    63  		os.Exit(1)
    64  	}
    65  	lm.SetLevelsFromMap(defaultLogLevelMap)
    66  	return lm, func() {
    67  		logRotator.Close()
    68  	}
    69  }