Fix logger formatting.
This change copies the behavior of btcd for using seelog for logging, including making timestamps human readable, and setting the default logging level to info. Fixes #8.
This commit is contained in:
parent
68cbb4192c
commit
91b4a5711c
3 changed files with 150 additions and 2 deletions
16
cmd.go
16
cmd.go
|
@ -26,7 +26,6 @@ import (
|
|||
"github.com/conformal/btcwallet/tx"
|
||||
"github.com/conformal/btcwallet/wallet"
|
||||
"github.com/conformal/btcwire"
|
||||
"github.com/conformal/seelog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
@ -43,7 +42,6 @@ var (
|
|||
ErrNoWallet = errors.New("wallet file does not exist")
|
||||
|
||||
cfg *config
|
||||
log = seelog.Default
|
||||
|
||||
curHeight = struct {
|
||||
sync.RWMutex
|
||||
|
@ -617,6 +615,15 @@ func JSONIDGenerator(c chan uint64) {
|
|||
}
|
||||
|
||||
func main() {
|
||||
// Initialize logging and setup deferred flushing to ensure all
|
||||
// outstanding messages are written on shutdown
|
||||
loggers := setLogLevel(defaultLogLevel)
|
||||
defer func() {
|
||||
for _, logger := range loggers {
|
||||
logger.Flush()
|
||||
}
|
||||
}()
|
||||
|
||||
tcfg, _, err := loadConfig()
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
|
@ -624,6 +631,11 @@ func main() {
|
|||
}
|
||||
cfg = tcfg
|
||||
|
||||
// Change the logging level if needed.
|
||||
if cfg.DebugLevel != defaultLogLevel {
|
||||
loggers = setLogLevel(cfg.DebugLevel)
|
||||
}
|
||||
|
||||
// Open default wallet
|
||||
w, err := OpenWallet(cfg, "")
|
||||
if err != nil {
|
||||
|
|
28
config.go
28
config.go
|
@ -167,5 +167,33 @@ func loadConfig() (*config, []string, error) {
|
|||
}
|
||||
updateConfigWithActiveParams(&cfg)
|
||||
|
||||
// Validate debug log level
|
||||
if !validLogLevel(cfg.DebugLevel) {
|
||||
str := "%s: The specified debug level [%v] is invalid"
|
||||
err := fmt.Errorf(str, "loadConfig", cfg.DebugLevel)
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
parser.WriteHelp(os.Stderr)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return &cfg, remainingArgs, nil
|
||||
}
|
||||
|
||||
// validLogLevel returns whether or not logLevel is a valid debug log level.
|
||||
func validLogLevel(logLevel string) bool {
|
||||
switch logLevel {
|
||||
case "trace":
|
||||
fallthrough
|
||||
case "debug":
|
||||
fallthrough
|
||||
case "info":
|
||||
fallthrough
|
||||
case "warn":
|
||||
fallthrough
|
||||
case "error":
|
||||
fallthrough
|
||||
case "critical":
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
108
log.go
Normal file
108
log.go
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Conformal Systems LLC <info@conformal.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/conformal/seelog"
|
||||
"os"
|
||||
)
|
||||
|
||||
const (
|
||||
// lockTimeThreshold is the number below which a lock time is
|
||||
// interpreted to be a block number. Since an average of one block
|
||||
// is generated per 10 minutes, this allows blocks for about 9,512
|
||||
// years. However, if the field is interpreted as a timestamp, given
|
||||
// the lock time is a uint32, the max is sometime around 2106.
|
||||
lockTimeThreshold uint32 = 5e8 // Tue Nov 5 00:53:20 1985 UTC
|
||||
)
|
||||
|
||||
var (
|
||||
log = seelog.Disabled
|
||||
)
|
||||
|
||||
// logClosure is used to provide a closure over expensive logging operations
|
||||
// so don't have to be performed when the logging level doesn't warrant it.
|
||||
type logClosure func() string
|
||||
|
||||
// String invokes the underlying function and returns the result.
|
||||
func (c logClosure) String() string {
|
||||
return c()
|
||||
}
|
||||
|
||||
// newLogClosure returns a new closure over a function that returns a string
|
||||
// which itself provides a Stringer interface so that it can be used with the
|
||||
// logging system.
|
||||
func newLogClosure(c func() string) logClosure {
|
||||
return logClosure(c)
|
||||
}
|
||||
|
||||
// newLogger creates a new seelog logger using the provided logging level and
|
||||
// log message prefix.
|
||||
func newLogger(level string, prefix string) seelog.LoggerInterface {
|
||||
//<seelog type="adaptive" mininterval="2000000" maxinterval="100000000"
|
||||
// critmsgcount="500" minlevel="%s">
|
||||
|
||||
fmtstring := `
|
||||
<seelog type="sync" minlevel="%s">
|
||||
<outputs formatid="all">
|
||||
<console/>
|
||||
</outputs>
|
||||
<formats>
|
||||
<format id="all" format="%%Time %%Date [%%LEV] %s: %%Msg%%n" />
|
||||
</formats>
|
||||
</seelog>`
|
||||
config := fmt.Sprintf(fmtstring, level, prefix)
|
||||
|
||||
logger, err := seelog.LoggerFromConfigAsString(config)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to create logger: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
return logger
|
||||
}
|
||||
|
||||
// useLogger sets the btcd logger to the passed logger.
|
||||
func useLogger(logger seelog.LoggerInterface) {
|
||||
log = logger
|
||||
}
|
||||
|
||||
// setLogLevel sets the log level for the logging system. It initializes a
|
||||
// logger for each subsystem at the provided level.
|
||||
func setLogLevel(logLevel string) []seelog.LoggerInterface {
|
||||
var loggers []seelog.LoggerInterface
|
||||
|
||||
// Define sub-systems.
|
||||
subSystems := []struct {
|
||||
level string
|
||||
prefix string
|
||||
useLogger func(seelog.LoggerInterface)
|
||||
}{
|
||||
{logLevel, "BTCW", useLogger},
|
||||
}
|
||||
|
||||
// Configure all sub-systems with new loggers while keeping track of
|
||||
// the created loggers to return so they can be flushed.
|
||||
for _, s := range subSystems {
|
||||
newLog := newLogger(s.level, s.prefix)
|
||||
loggers = append(loggers, newLog)
|
||||
s.useLogger(newLog)
|
||||
}
|
||||
|
||||
return loggers
|
||||
}
|
Loading…
Reference in a new issue