github.com/dashpay/godash@v0.0.0-20160726055534-e038a21e0e3d/log.go (about)

     1  // Copyright (c) 2013-2016 The btcsuite developers
     2  // Copyright (c) 2016 The Dash developers
     3  // Use of this source code is governed by an ISC
     4  // license that can be found in the LICENSE file.
     5  
     6  package main
     7  
     8  import (
     9  	"fmt"
    10  	"os"
    11  
    12  	"github.com/btcsuite/btclog"
    13  	"github.com/btcsuite/seelog"
    14  	"github.com/dashpay/godash/addrmgr"
    15  	"github.com/dashpay/godash/blockchain"
    16  	"github.com/dashpay/godash/blockchain/indexers"
    17  	"github.com/dashpay/godash/database"
    18  	"github.com/dashpay/godash/peer"
    19  	"github.com/dashpay/godash/txscript"
    20  )
    21  
    22  const (
    23  	// maxRejectReasonLen is the maximum length of a sanitized reject reason
    24  	// that will be logged.
    25  	maxRejectReasonLen = 250
    26  )
    27  
    28  // Loggers per subsystem.  Note that backendLog is a seelog logger that all of
    29  // the subsystem loggers route their messages to.  When adding new subsystems,
    30  // add a reference here, to the subsystemLoggers map, and the useLogger
    31  // function.
    32  var (
    33  	backendLog = seelog.Disabled
    34  	adxrLog    = btclog.Disabled
    35  	amgrLog    = btclog.Disabled
    36  	bcdbLog    = btclog.Disabled
    37  	bmgrLog    = btclog.Disabled
    38  	btcdLog    = btclog.Disabled
    39  	chanLog    = btclog.Disabled
    40  	discLog    = btclog.Disabled
    41  	indxLog    = btclog.Disabled
    42  	minrLog    = btclog.Disabled
    43  	peerLog    = btclog.Disabled
    44  	rpcsLog    = btclog.Disabled
    45  	scrpLog    = btclog.Disabled
    46  	srvrLog    = btclog.Disabled
    47  	txmpLog    = btclog.Disabled
    48  )
    49  
    50  // subsystemLoggers maps each subsystem identifier to its associated logger.
    51  var subsystemLoggers = map[string]btclog.Logger{
    52  	"ADXR": adxrLog,
    53  	"AMGR": amgrLog,
    54  	"BCDB": bcdbLog,
    55  	"BMGR": bmgrLog,
    56  	"BTCD": btcdLog,
    57  	"CHAN": chanLog,
    58  	"DISC": discLog,
    59  	"INDX": indxLog,
    60  	"MINR": minrLog,
    61  	"PEER": peerLog,
    62  	"RPCS": rpcsLog,
    63  	"SCRP": scrpLog,
    64  	"SRVR": srvrLog,
    65  	"TXMP": txmpLog,
    66  }
    67  
    68  // logClosure is used to provide a closure over expensive logging operations
    69  // so don't have to be performed when the logging level doesn't warrant it.
    70  type logClosure func() string
    71  
    72  // String invokes the underlying function and returns the result.
    73  func (c logClosure) String() string {
    74  	return c()
    75  }
    76  
    77  // newLogClosure returns a new closure over a function that returns a string
    78  // which itself provides a Stringer interface so that it can be used with the
    79  // logging system.
    80  func newLogClosure(c func() string) logClosure {
    81  	return logClosure(c)
    82  }
    83  
    84  // useLogger updates the logger references for subsystemID to logger.  Invalid
    85  // subsystems are ignored.
    86  func useLogger(subsystemID string, logger btclog.Logger) {
    87  	if _, ok := subsystemLoggers[subsystemID]; !ok {
    88  		return
    89  	}
    90  	subsystemLoggers[subsystemID] = logger
    91  
    92  	switch subsystemID {
    93  	case "ADXR":
    94  		adxrLog = logger
    95  
    96  	case "AMGR":
    97  		amgrLog = logger
    98  		addrmgr.UseLogger(logger)
    99  
   100  	case "BCDB":
   101  		bcdbLog = logger
   102  		database.UseLogger(logger)
   103  
   104  	case "BMGR":
   105  		bmgrLog = logger
   106  
   107  	case "BTCD":
   108  		btcdLog = logger
   109  
   110  	case "CHAN":
   111  		chanLog = logger
   112  		blockchain.UseLogger(logger)
   113  
   114  	case "DISC":
   115  		discLog = logger
   116  
   117  	case "INDX":
   118  		indxLog = logger
   119  		indexers.UseLogger(logger)
   120  
   121  	case "MINR":
   122  		minrLog = logger
   123  
   124  	case "PEER":
   125  		peerLog = logger
   126  		peer.UseLogger(logger)
   127  
   128  	case "RPCS":
   129  		rpcsLog = logger
   130  
   131  	case "SCRP":
   132  		scrpLog = logger
   133  		txscript.UseLogger(logger)
   134  
   135  	case "SRVR":
   136  		srvrLog = logger
   137  
   138  	case "TXMP":
   139  		txmpLog = logger
   140  	}
   141  }
   142  
   143  // initSeelogLogger initializes a new seelog logger that is used as the backend
   144  // for all logging subsystems.
   145  func initSeelogLogger(logFile string) {
   146  	config := `
   147  	<seelog type="adaptive" mininterval="2000000" maxinterval="100000000"
   148  		critmsgcount="500" minlevel="trace">
   149  		<outputs formatid="all">
   150  			<console />
   151  			<rollingfile type="size" filename="%s" maxsize="10485760" maxrolls="3" />
   152  		</outputs>
   153  		<formats>
   154  			<format id="all" format="%%Time %%Date [%%LEV] %%Msg%%n" />
   155  		</formats>
   156  	</seelog>`
   157  	config = fmt.Sprintf(config, logFile)
   158  
   159  	logger, err := seelog.LoggerFromConfigAsString(config)
   160  	if err != nil {
   161  		fmt.Fprintf(os.Stderr, "failed to create logger: %v", err)
   162  		os.Exit(1)
   163  	}
   164  
   165  	backendLog = logger
   166  }
   167  
   168  // setLogLevel sets the logging level for provided subsystem.  Invalid
   169  // subsystems are ignored.  Uninitialized subsystems are dynamically created as
   170  // needed.
   171  func setLogLevel(subsystemID string, logLevel string) {
   172  	// Ignore invalid subsystems.
   173  	logger, ok := subsystemLoggers[subsystemID]
   174  	if !ok {
   175  		return
   176  	}
   177  
   178  	// Default to info if the log level is invalid.
   179  	level, ok := btclog.LogLevelFromString(logLevel)
   180  	if !ok {
   181  		level = btclog.InfoLvl
   182  	}
   183  
   184  	// Create new logger for the subsystem if needed.
   185  	if logger == btclog.Disabled {
   186  		logger = btclog.NewSubsystemLogger(backendLog, subsystemID+": ")
   187  		useLogger(subsystemID, logger)
   188  	}
   189  	logger.SetLevel(level)
   190  }
   191  
   192  // setLogLevels sets the log level for all subsystem loggers to the passed
   193  // level.  It also dynamically creates the subsystem loggers as needed, so it
   194  // can be used to initialize the logging system.
   195  func setLogLevels(logLevel string) {
   196  	// Configure all sub-systems with the new logging level.  Dynamically
   197  	// create loggers as needed.
   198  	for subsystemID := range subsystemLoggers {
   199  		setLogLevel(subsystemID, logLevel)
   200  	}
   201  }
   202  
   203  // directionString is a helper function that returns a string that represents
   204  // the direction of a connection (inbound or outbound).
   205  func directionString(inbound bool) string {
   206  	if inbound {
   207  		return "inbound"
   208  	}
   209  	return "outbound"
   210  }