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 }