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  }