multi: add persistent logger

This commit is contained in:
Oliver Gugger 2019-10-28 17:06:07 +01:00
parent 0d76d6e162
commit b574e344ea
No known key found for this signature in database
GPG key ID: 8E4256593F177720
18 changed files with 201 additions and 135 deletions

View file

@ -1,5 +1,23 @@
package main
import (
"path/filepath"
"github.com/btcsuite/btcutil"
)
var (
loopDirBase = btcutil.AppDataDir("loop", false)
defaultLogLevel = "info"
defaultLogDirname = "logs"
defaultLogFilename = "loopd.log"
defaultLogDir = filepath.Join(loopDirBase, defaultLogDirname)
defaultMaxLogFiles = 3
defaultMaxLogFileSize = 10
)
type lndConfig struct {
Host string `long:"host" description:"lnd instance rpc address"`
MacaroonDir string `long:"macaroondir" description:"Path to the directory containing all the required lnd macaroons"`
@ -16,6 +34,12 @@ type config struct {
RPCListen string `long:"rpclisten" description:"Address to listen on for gRPC clients"`
RESTListen string `long:"restlisten" description:"Address to listen on for REST clients"`
LogDir string `long:"logdir" description:"Directory to log output."`
MaxLogFiles int `long:"maxlogfiles" description:"Maximum logfiles to keep (0 for no rotation)"`
MaxLogFileSize int `long:"maxlogfilesize" description:"Maximum logfile size in MB"`
DebugLevel string `short:"d" long:"debuglevel" description:"Logging level for all subsystems {trace, debug, info, warn, error, critical} -- You may also specify <subsystem>=<level>,<subsystem2>=<level>,... to set the log level for individual subsystems -- Use show to list available subsystems"`
Lnd *lndConfig `group:"lnd" namespace:"lnd"`
View viewParameters `command:"view" alias:"v" description:"View all swaps in the database. This command can only be executed when loopd is not running."`
@ -27,10 +51,14 @@ const (
)
var defaultConfig = config{
Network: "mainnet",
RPCListen: "localhost:11010",
RESTListen: "localhost:8081",
Insecure: false,
Network: "mainnet",
RPCListen: "localhost:11010",
RESTListen: "localhost:8081",
Insecure: false,
LogDir: defaultLogDir,
MaxLogFiles: defaultMaxLogFiles,
MaxLogFileSize: defaultMaxLogFileSize,
DebugLevel: defaultLogLevel,
Lnd: &lndConfig{
Host: "localhost:10009",
},

View file

@ -40,7 +40,7 @@ func daemon(config *config) error {
}
}
logger.Infof("Swap server address: %v", config.SwapServer)
log.Infof("Swap server address: %v", config.SwapServer)
// Create an instance of the loop client library.
swapClient, cleanup, err := getClient(
@ -73,7 +73,7 @@ func daemon(config *config) error {
looprpc.RegisterSwapClientServer(grpcServer, &server)
// Next, start the gRPC server listening for HTTP/2 connections.
logger.Infof("Starting gRPC listener")
log.Infof("Starting gRPC listener")
grpcListener, err := net.Listen("tcp", config.RPCListen)
if err != nil {
return fmt.Errorf("RPC server unable to listen on %s",
@ -95,7 +95,7 @@ func daemon(config *config) error {
return err
}
logger.Infof("Starting REST proxy listener")
log.Infof("Starting REST proxy listener")
restListener, err := net.Listen("tcp", config.RESTListen)
if err != nil {
return fmt.Errorf("REST proxy unable to listen on %s",
@ -115,14 +115,14 @@ func daemon(config *config) error {
go func() {
defer wg.Done()
logger.Infof("Starting swap client")
log.Infof("Starting swap client")
err := swapClient.Run(mainCtx, statusChan)
if err != nil {
logger.Error(err)
log.Error(err)
}
logger.Infof("Swap client stopped")
log.Infof("Swap client stopped")
logger.Infof("Stopping gRPC server")
log.Infof("Stopping gRPC server")
grpcServer.Stop()
cancel()
@ -133,7 +133,7 @@ func daemon(config *config) error {
go func() {
defer wg.Done()
logger.Infof("Waiting for updates")
log.Infof("Waiting for updates")
for {
select {
case swap := <-statusChan:
@ -160,12 +160,12 @@ func daemon(config *config) error {
go func() {
defer wg.Done()
logger.Infof("RPC server listening on %s", grpcListener.Addr())
logger.Infof("REST proxy listening on %s", restListener.Addr())
log.Infof("RPC server listening on %s", grpcListener.Addr())
log.Infof("REST proxy listening on %s", restListener.Addr())
err = grpcServer.Serve(grpcListener)
if err != nil {
logger.Error(err)
log.Error(err)
}
}()
@ -175,7 +175,7 @@ func daemon(config *config) error {
// Run until the users terminates loopd or an error occurred.
select {
case <-interruptChannel:
logger.Infof("Received SIGINT (Ctrl+C).")
log.Infof("Received SIGINT (Ctrl+C).")
// TODO: Remove debug code.
// Debug code to dump goroutines on hanging exit.

View file

@ -1,24 +1,40 @@
package main
import (
"os"
"github.com/btcsuite/btclog"
"github.com/lightninglabs/loop"
"github.com/lightninglabs/loop/lndclient"
"github.com/lightninglabs/loop/loopdb"
"github.com/lightningnetwork/lnd/build"
)
// log is a logger that is initialized with no output filters. This means the
// package will not perform any logging by default until the caller requests
// it.
var (
backendLog = btclog.NewBackend(logWriter{})
logger = backendLog.Logger("LOOPD")
logWriter = build.NewRotatingLogWriter()
log = build.NewSubLogger("LOOPD", logWriter.GenSubLogger)
)
// logWriter implements an io.Writer that outputs to both standard output and
// the write-end pipe of an initialized log rotator.
type logWriter struct{}
func (logWriter) Write(p []byte) (n int, err error) {
os.Stdout.Write(p)
return len(p), nil
func init() {
setSubLogger("LOOPD", log, nil)
addSubLogger("LOOP", loop.UseLogger)
addSubLogger("LNDC", lndclient.UseLogger)
addSubLogger("STORE", loopdb.UseLogger)
}
// addSubLogger is a helper method to conveniently create and register the
// logger of a sub system.
func addSubLogger(subsystem string, useLogger func(btclog.Logger)) {
logger := build.NewSubLogger(subsystem, logWriter.GenSubLogger)
setSubLogger(subsystem, logger, useLogger)
}
// setSubLogger is a helper method to conveniently register the logger of a sub
// system.
func setSubLogger(subsystem string, logger btclog.Logger,
useLogger func(btclog.Logger)) {
logWriter.RegisterSubLogger(subsystem, logger)
if useLogger != nil {
useLogger(logger)
}
}

View file

@ -7,10 +7,9 @@ import (
"strings"
"sync"
flags "github.com/jessevdk/go-flags"
"github.com/btcsuite/btcutil"
"github.com/jessevdk/go-flags"
"github.com/lightninglabs/loop"
"github.com/lightningnetwork/lnd/build"
"github.com/lightningnetwork/lnd/lntypes"
)
@ -19,7 +18,6 @@ const (
)
var (
loopDirBase = btcutil.AppDataDir("loop", false)
defaultConfigFilename = "loopd.conf"
swaps = make(map[lntypes.Hash]loop.SwapInfo)
@ -81,8 +79,32 @@ func start() error {
os.Exit(0)
}
// Special show command to list supported subsystems and exit.
if config.DebugLevel == "show" {
fmt.Printf("Supported subsystems: %v\n",
logWriter.SupportedSubsystems())
os.Exit(0)
}
// Append the network type to the log directory so it is
// "namespaced" per network in the same fashion as the data directory.
config.LogDir = filepath.Join(config.LogDir, config.Network)
// Initialize logging at the default logging level.
err = logWriter.InitLogRotator(
filepath.Join(config.LogDir, defaultLogFilename),
config.MaxLogFileSize, config.MaxLogFiles,
)
if err != nil {
return err
}
err = build.ParseAndSetDebugLevels(config.DebugLevel, logWriter)
if err != nil {
return err
}
// Print the version before executing either primary directive.
logger.Infof("Version: %v", loop.Version())
log.Infof("Version: %v", loop.Version())
// Execute command.
if parser.Active == nil {

View file

@ -40,7 +40,7 @@ func (s *swapClientServer) LoopOut(ctx context.Context,
in *looprpc.LoopOutRequest) (
*looprpc.SwapResponse, error) {
logger.Infof("Loop out request received")
log.Infof("Loop out request received")
sweepConfTarget, err := validateConfTarget(
in.SweepConfTarget, loop.DefaultSweepConfTarget,
@ -82,7 +82,7 @@ func (s *swapClientServer) LoopOut(ctx context.Context,
}
hash, htlc, err := s.impl.LoopOut(ctx, req)
if err != nil {
logger.Errorf("LoopOut: %v", err)
log.Errorf("LoopOut: %v", err)
return nil, err
}
@ -140,7 +140,7 @@ func (s *swapClientServer) marshallSwap(loopSwap *loop.SwapInfo) (
func (s *swapClientServer) Monitor(in *looprpc.MonitorRequest,
server looprpc.SwapClient_MonitorServer) error {
logger.Infof("Monitor request received")
log.Infof("Monitor request received")
send := func(info loop.SwapInfo) error {
rpcSwap, err := s.marshallSwap(&info)
@ -234,11 +234,11 @@ func (s *swapClientServer) Monitor(in *looprpc.MonitorRequest,
func (s *swapClientServer) LoopOutTerms(ctx context.Context,
req *looprpc.TermsRequest) (*looprpc.TermsResponse, error) {
logger.Infof("Loop out terms request received")
log.Infof("Loop out terms request received")
terms, err := s.impl.LoopOutTerms(ctx)
if err != nil {
logger.Errorf("Terms request: %v", err)
log.Errorf("Terms request: %v", err)
return nil, err
}
@ -280,11 +280,11 @@ func (s *swapClientServer) LoopOutQuote(ctx context.Context,
func (s *swapClientServer) GetLoopInTerms(ctx context.Context, req *looprpc.TermsRequest) (
*looprpc.TermsResponse, error) {
logger.Infof("Loop in terms request received")
log.Infof("Loop in terms request received")
terms, err := s.impl.LoopInTerms(ctx)
if err != nil {
logger.Errorf("Terms request: %v", err)
log.Errorf("Terms request: %v", err)
return nil, err
}
@ -298,7 +298,7 @@ func (s *swapClientServer) GetLoopInTerms(ctx context.Context, req *looprpc.Term
func (s *swapClientServer) GetLoopInQuote(ctx context.Context,
req *looprpc.QuoteRequest) (*looprpc.QuoteResponse, error) {
logger.Infof("Loop in quote request received")
log.Infof("Loop in quote request received")
quote, err := s.impl.LoopInQuote(ctx, &loop.LoopInQuoteRequest{
Amount: btcutil.Amount(req.Amt),
@ -318,7 +318,7 @@ func (s *swapClientServer) LoopIn(ctx context.Context,
in *looprpc.LoopInRequest) (
*looprpc.SwapResponse, error) {
logger.Infof("Loop in request received")
log.Infof("Loop in request received")
req := &loop.LoopInRequest{
Amount: btcutil.Amount(in.Amt),
@ -332,7 +332,7 @@ func (s *swapClientServer) LoopIn(ctx context.Context,
}
hash, htlc, err := s.impl.LoopIn(ctx, req)
if err != nil {
logger.Errorf("Loop in: %v", err)
log.Errorf("Loop in: %v", err)
return nil, err
}