github.com/decred/dcrlnd@v0.7.6/log.go (about) 1 package dcrlnd 2 3 import ( 4 "github.com/decred/dcrd/connmgr" 5 "github.com/decred/dcrlnd/automation" 6 "github.com/decred/dcrlnd/autopilot" 7 "github.com/decred/dcrlnd/build" 8 "github.com/decred/dcrlnd/chainntnfs" 9 "github.com/decred/dcrlnd/chainreg" 10 "github.com/decred/dcrlnd/chainscan" 11 "github.com/decred/dcrlnd/chainscan/csdrivers" 12 "github.com/decred/dcrlnd/chanacceptor" 13 "github.com/decred/dcrlnd/chanbackup" 14 "github.com/decred/dcrlnd/chanfitness" 15 "github.com/decred/dcrlnd/channeldb" 16 "github.com/decred/dcrlnd/channelnotifier" 17 "github.com/decred/dcrlnd/cluster" 18 "github.com/decred/dcrlnd/contractcourt" 19 "github.com/decred/dcrlnd/discovery" 20 "github.com/decred/dcrlnd/funding" 21 "github.com/decred/dcrlnd/healthcheck" 22 "github.com/decred/dcrlnd/htlcswitch" 23 "github.com/decred/dcrlnd/invoices" 24 "github.com/decred/dcrlnd/keychain" 25 "github.com/decred/dcrlnd/kvdb/postgres" 26 "github.com/decred/dcrlnd/lnrpc/autopilotrpc" 27 "github.com/decred/dcrlnd/lnrpc/chainrpc" 28 "github.com/decred/dcrlnd/lnrpc/invoicesrpc" 29 "github.com/decred/dcrlnd/lnrpc/routerrpc" 30 "github.com/decred/dcrlnd/lnrpc/signrpc" 31 "github.com/decred/dcrlnd/lnrpc/verrpc" 32 "github.com/decred/dcrlnd/lnrpc/walletrpc" 33 "github.com/decred/dcrlnd/lnwallet" 34 "github.com/decred/dcrlnd/lnwallet/chancloser" 35 "github.com/decred/dcrlnd/lnwallet/chanfunding" 36 "github.com/decred/dcrlnd/lnwallet/dcrwallet" 37 "github.com/decred/dcrlnd/lnwallet/remotedcrwallet" 38 "github.com/decred/dcrlnd/monitoring" 39 "github.com/decred/dcrlnd/netann" 40 "github.com/decred/dcrlnd/peer" 41 "github.com/decred/dcrlnd/peernotifier" 42 "github.com/decred/dcrlnd/routing" 43 "github.com/decred/dcrlnd/routing/localchans" 44 "github.com/decred/dcrlnd/rpcperms" 45 "github.com/decred/dcrlnd/signal" 46 "github.com/decred/dcrlnd/sweep" 47 "github.com/decred/dcrlnd/tor" 48 "github.com/decred/dcrlnd/walletunlocker" 49 "github.com/decred/dcrlnd/watchtower" 50 "github.com/decred/dcrlnd/watchtower/wtclient" 51 sphinx "github.com/decred/lightning-onion/v4" 52 "github.com/decred/slog" 53 ) 54 55 // replaceableLogger is a thin wrapper around a logger that is used so the 56 // logger can be replaced easily without some black pointer magic. 57 type replaceableLogger struct { 58 slog.Logger 59 subsystem string 60 } 61 62 // Loggers can not be used before the log rotator has been initialized with a 63 // log file. This must be performed early during application startup by 64 // calling InitLogRotator() on the main log writer instance in the config. 65 var ( 66 // lndPkgLoggers is a list of all lnd package level loggers that are 67 // registered. They are tracked here so they can be replaced once the 68 // SetupLoggers function is called with the final root logger. 69 lndPkgLoggers []*replaceableLogger 70 71 // addLndPkgLogger is a helper function that creates a new replaceable 72 // main lnd package level logger and adds it to the list of loggers that 73 // are replaced again later, once the final root logger is ready. 74 addLndPkgLogger = func(subsystem string) *replaceableLogger { 75 l := &replaceableLogger{ 76 Logger: build.NewSubLogger(subsystem, nil), 77 subsystem: subsystem, 78 } 79 lndPkgLoggers = append(lndPkgLoggers, l) 80 return l 81 } 82 83 // Loggers that need to be accessible from the lnd package can be placed 84 // here. Loggers that are only used in sub modules can be added directly 85 // by using the addSubLogger method. We declare all loggers so we never 86 // run into a nil reference if they are used early. But the SetupLoggers 87 // function should always be called as soon as possible to finish 88 // setting them up properly with a root logger. 89 ltndLog = addLndPkgLogger("LTND") 90 rpcsLog = addLndPkgLogger("RPCS") 91 srvrLog = addLndPkgLogger("SRVR") 92 atplLog = addLndPkgLogger("ATPL") 93 ) 94 95 // genSubLogger creates a logger for a subsystem. We provide an instance of 96 // a signal.Interceptor to be able to shutdown in the case of a critical error. 97 func genSubLogger(root *build.RotatingLogWriter, 98 interceptor signal.Interceptor) func(string) slog.Logger { 99 100 // Create a shutdown function which will request shutdown from our 101 // interceptor if it is listening. 102 shutdown := func() { 103 if !interceptor.Listening() { 104 return 105 } 106 107 interceptor.RequestShutdown() 108 } 109 110 // Return a function which will create a sublogger from our root 111 // logger without shutdown fn. 112 return func(tag string) slog.Logger { 113 return root.GenSubLogger(tag, shutdown) 114 } 115 } 116 117 // SetupLoggers initializes all package-global logger variables. 118 func SetupLoggers(root *build.RotatingLogWriter, interceptor signal.Interceptor) { 119 genLogger := genSubLogger(root, interceptor) 120 121 // Now that we have the proper root logger, we can replace the 122 // placeholder lnd package loggers. 123 for _, l := range lndPkgLoggers { 124 l.Logger = build.NewSubLogger(l.subsystem, genLogger) 125 SetSubLogger(root, l.subsystem, l.Logger) 126 } 127 128 // Some of the loggers declared in the main lnd package are also used 129 // in sub packages. 130 signal.UseLogger(ltndLog) 131 autopilot.UseLogger(atplLog) 132 133 // Decred-specific logs. 134 AddSubLogger(root, "DCRW", interceptor, dcrwallet.UseLogger) 135 AddSubLogger(root, "RDCW", interceptor, remotedcrwallet.UseLogger) 136 AddSubLogger(root, "KCHN", interceptor, keychain.UseLogger) 137 AddSubLogger(root, "CSCN", interceptor, chainscan.UseLogger) 138 AddSubLogger(root, "CSDR", interceptor, csdrivers.UseLogger) 139 AddSubLogger(root, "AUTO", interceptor, automation.UseLogger) 140 AddSubLogger(root, "PGDB", interceptor, postgres.UseLogger) 141 AddSubLogger(root, "LCCH", interceptor, localchans.UseLogger) 142 AddSubLogger(root, "PING", interceptor, peer.UsePingLogger) 143 144 AddSubLogger(root, "LNWL", interceptor, lnwallet.UseLogger) 145 AddSubLogger(root, "DISC", interceptor, discovery.UseLogger) 146 AddSubLogger(root, "NTFN", interceptor, chainntnfs.UseLogger) 147 AddSubLogger(root, "CHDB", interceptor, channeldb.UseLogger) 148 AddSubLogger(root, "HSWC", interceptor, htlcswitch.UseLogger) 149 AddSubLogger(root, "CMGR", interceptor, connmgr.UseLogger) 150 AddSubLogger(root, "CNCT", interceptor, contractcourt.UseLogger) 151 AddSubLogger(root, "UTXN", interceptor, contractcourt.UseNurseryLogger) 152 AddSubLogger(root, "BRAR", interceptor, contractcourt.UseBreachLogger) 153 AddSubLogger(root, "SPHX", interceptor, sphinx.UseLogger) 154 AddSubLogger(root, "SWPR", interceptor, sweep.UseLogger) 155 AddSubLogger(root, "SGNR", interceptor, signrpc.UseLogger) 156 AddSubLogger(root, "WLKT", interceptor, walletrpc.UseLogger) 157 AddSubLogger(root, "ARPC", interceptor, autopilotrpc.UseLogger) 158 AddSubLogger(root, "INVC", interceptor, invoices.UseLogger) 159 AddSubLogger(root, "NANN", interceptor, netann.UseLogger) 160 AddSubLogger(root, "WTWR", interceptor, watchtower.UseLogger) 161 AddSubLogger(root, "NTFR", interceptor, chainrpc.UseLogger) 162 AddSubLogger(root, "IRPC", interceptor, invoicesrpc.UseLogger) 163 AddSubLogger(root, "CHNF", interceptor, channelnotifier.UseLogger) 164 AddSubLogger(root, "CHBU", interceptor, chanbackup.UseLogger) 165 AddSubLogger(root, "PROM", interceptor, monitoring.UseLogger) 166 AddSubLogger(root, "WTCL", interceptor, wtclient.UseLogger) 167 AddSubLogger(root, "PRNF", interceptor, peernotifier.UseLogger) 168 AddSubLogger(root, "CHFD", interceptor, chanfunding.UseLogger) 169 AddSubLogger(root, "PEER", interceptor, peer.UseLogger) 170 AddSubLogger(root, "CHCL", interceptor, chancloser.UseLogger) 171 AddSubLogger(root, "WUNL", interceptor, walletunlocker.UseLogger) 172 173 AddSubLogger(root, routing.Subsystem, interceptor, routing.UseLogger, localchans.UseLogger) 174 AddSubLogger(root, routerrpc.Subsystem, interceptor, routerrpc.UseLogger) 175 AddSubLogger(root, chanfitness.Subsystem, interceptor, chanfitness.UseLogger) 176 AddSubLogger(root, verrpc.Subsystem, interceptor, verrpc.UseLogger) 177 AddSubLogger(root, healthcheck.Subsystem, interceptor, healthcheck.UseLogger) 178 AddSubLogger(root, chainreg.Subsystem, interceptor, chainreg.UseLogger) 179 AddSubLogger(root, chanacceptor.Subsystem, interceptor, chanacceptor.UseLogger) 180 AddSubLogger(root, funding.Subsystem, interceptor, funding.UseLogger) 181 AddSubLogger(root, cluster.Subsystem, interceptor, cluster.UseLogger) 182 AddSubLogger(root, rpcperms.Subsystem, interceptor, rpcperms.UseLogger) 183 AddSubLogger(root, tor.Subsystem, interceptor, tor.UseLogger) 184 } 185 186 // AddSubLogger is a helper method to conveniently create and register the 187 // logger of one or more sub systems. 188 func AddSubLogger(root *build.RotatingLogWriter, subsystem string, 189 interceptor signal.Interceptor, useLoggers ...func(slog.Logger)) { 190 191 // genSubLogger will return a callback for creating a logger instance, 192 // which we will give to the root logger. 193 genLogger := genSubLogger(root, interceptor) 194 195 // Create and register just a single logger to prevent them from 196 // overwriting each other internally. 197 logger := build.NewSubLogger(subsystem, genLogger) 198 SetSubLogger(root, subsystem, logger, useLoggers...) 199 } 200 201 // SetSubLogger is a helper method to conveniently register the logger of a sub 202 // system. 203 func SetSubLogger(root *build.RotatingLogWriter, subsystem string, 204 logger slog.Logger, useLoggers ...func(slog.Logger)) { 205 206 root.RegisterSubLogger(subsystem, logger) 207 for _, useLogger := range useLoggers { 208 useLogger(logger) 209 } 210 } 211 212 // logClosure is used to provide a closure over expensive logging operations so 213 // don't have to be performed when the logging level doesn't warrant it. 214 type logClosure func() string 215 216 // String invokes the underlying function and returns the result. 217 func (c logClosure) String() string { 218 return c() 219 } 220 221 // newLogClosure returns a new closure over a function that returns a string 222 // which itself provides a Stringer interface so that it can be used with the 223 // logging system. 224 func newLogClosure(c func() string) logClosure { 225 return logClosure(c) 226 }