decred.org/dcrdex@v1.0.5/server/cmd/dcrdex/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 main
     5  
     6  import (
     7  	"fmt"
     8  	"os"
     9  	"path/filepath"
    10  
    11  	"decred.org/dcrdex/dex"
    12  	"github.com/jrick/logrotate/rotator"
    13  )
    14  
    15  // logWriter implements an io.Writer that outputs to both standard output and
    16  // the write-end pipe of an initialized log rotator.
    17  type logWriter struct{}
    18  
    19  // Write writes the data in p to standard out and the log rotator.
    20  func (logWriter) Write(p []byte) (n int, err error) {
    21  	if logRotator == nil {
    22  		return os.Stdout.Write(p)
    23  	}
    24  	os.Stdout.Write(p)
    25  	return logRotator.Write(p) // not safe concurrent writes, so only one logWriter{} allowed!
    26  }
    27  
    28  // Loggers per subsystem. A single backend logger is created and all subsystem
    29  // loggers created from it will write to the backend. When adding new
    30  // subsystems, define it in the subsystemLoggers map.
    31  //
    32  // For packages with package-level loggers, subsystem logging calls should not
    33  // be done before actually setting the logger in parseAndSetDebugLevels.
    34  //
    35  // Loggers should not be used before the log rotator has been initialized with a
    36  // log file. This must be performed early during application startup by calling
    37  // initLogRotator.
    38  var (
    39  	// logRotator is one of the logging outputs. Use initLogRotator to set it.
    40  	// It should be closed on application shutdown.
    41  	logRotator *rotator.Rotator
    42  
    43  	// package main's Logger.
    44  	log = dex.Disabled
    45  
    46  	// subsystemLoggers maps each subsystem identifier to its associated logger.
    47  	// The loggers are disabled until parseAndSetDebugLevels is called.
    48  	subsystemLoggers = map[string]dex.Logger{
    49  		"MAIN": dex.Disabled,
    50  		"DEX":  dex.Disabled,
    51  		"DB":   dex.Disabled,
    52  		"COMM": dex.Disabled,
    53  		"AUTH": dex.Disabled,
    54  		"SWAP": dex.Disabled,
    55  		"MKT":  dex.Disabled,
    56  		"BOOK": dex.Disabled,
    57  		"MTCH": dex.Disabled,
    58  		"WAIT": dex.Disabled,
    59  		"ADMN": dex.Disabled,
    60  
    61  		// Individual assets get their own subsystem loggers. This is here to
    62  		// register the ASSET subsystem ID, allowing the user to set the log
    63  		// level for the asset subsystems.
    64  		"ASSET": dex.Disabled,
    65  	}
    66  )
    67  
    68  // initLogRotator initializes the logging rotater to write logs to logFile and
    69  // create roll files in the same directory.  It must be called before the
    70  // package-global log rotater variables are used.
    71  func initLogRotator(logFile string, maxRolls int) {
    72  	logDir, _ := filepath.Split(logFile)
    73  	err := os.MkdirAll(logDir, 0700)
    74  	if err != nil {
    75  		fmt.Fprintf(os.Stderr, "failed to create log directory: %v\n", err)
    76  		os.Exit(1)
    77  	}
    78  	logRotator, err = rotator.New(logFile, 32*1024, false, maxRolls)
    79  	if err != nil {
    80  		fmt.Fprintf(os.Stderr, "failed to create file rotator: %v\n", err)
    81  		os.Exit(1)
    82  	}
    83  }