internal, log: support debug log prints, displaying log origins
This commit is contained in:
parent
1ca20a2697
commit
f89dd62776
@ -30,12 +30,12 @@ import (
|
|||||||
var (
|
var (
|
||||||
verbosityFlag = cli.IntFlag{
|
verbosityFlag = cli.IntFlag{
|
||||||
Name: "verbosity",
|
Name: "verbosity",
|
||||||
Usage: "Logging verbosity: 0=silent, 1=error, 2=warn, 3=info, 4=core, 5=debug, 6=detail",
|
Usage: "Logging verbosity: 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail",
|
||||||
Value: 3,
|
Value: 3,
|
||||||
}
|
}
|
||||||
vmoduleFlag = cli.StringFlag{
|
vmoduleFlag = cli.StringFlag{
|
||||||
Name: "vmodule",
|
Name: "vmodule",
|
||||||
Usage: "Per-module verbosity: comma-separated list of <pattern>=<level> (e.g. eth/*=6,p2p=5)",
|
Usage: "Per-module verbosity: comma-separated list of <pattern>=<level> (e.g. eth/*=5,p2p=4)",
|
||||||
Value: "",
|
Value: "",
|
||||||
}
|
}
|
||||||
backtraceAtFlag = cli.StringFlag{
|
backtraceAtFlag = cli.StringFlag{
|
||||||
@ -43,6 +43,10 @@ var (
|
|||||||
Usage: "Request a stack trace at a specific logging statement (e.g. \"block.go:271\")",
|
Usage: "Request a stack trace at a specific logging statement (e.g. \"block.go:271\")",
|
||||||
Value: "",
|
Value: "",
|
||||||
}
|
}
|
||||||
|
debugFlag = cli.BoolFlag{
|
||||||
|
Name: "debug",
|
||||||
|
Usage: "Prepends log messages with call-site location (file and line number)",
|
||||||
|
}
|
||||||
pprofFlag = cli.BoolFlag{
|
pprofFlag = cli.BoolFlag{
|
||||||
Name: "pprof",
|
Name: "pprof",
|
||||||
Usage: "Enable the pprof HTTP server",
|
Usage: "Enable the pprof HTTP server",
|
||||||
@ -78,17 +82,21 @@ var (
|
|||||||
|
|
||||||
// Flags holds all command-line flags required for debugging.
|
// Flags holds all command-line flags required for debugging.
|
||||||
var Flags = []cli.Flag{
|
var Flags = []cli.Flag{
|
||||||
verbosityFlag, vmoduleFlag, backtraceAtFlag,
|
verbosityFlag, vmoduleFlag, backtraceAtFlag, debugFlag,
|
||||||
pprofFlag, pprofAddrFlag, pprofPortFlag,
|
pprofFlag, pprofAddrFlag, pprofPortFlag,
|
||||||
memprofilerateFlag, blockprofilerateFlag, cpuprofileFlag, traceFlag,
|
memprofilerateFlag, blockprofilerateFlag, cpuprofileFlag, traceFlag,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// glogger is the glog handler used by Geth, allowing the debug APIs to modify
|
||||||
|
// verbosity levels, vmodules and backtrace locations.
|
||||||
var glogger = log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat()))
|
var glogger = log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat()))
|
||||||
|
|
||||||
// Setup initializes profiling and logging based on the CLI flags.
|
// Setup initializes profiling and logging based on the CLI flags.
|
||||||
// It should be called as early as possible in the program.
|
// It should be called as early as possible in the program.
|
||||||
func Setup(ctx *cli.Context) error {
|
func Setup(ctx *cli.Context) error {
|
||||||
// logging
|
// logging
|
||||||
|
log.PrintOrigins(ctx.GlobalBool(debugFlag.Name))
|
||||||
|
|
||||||
glogger.Verbosity(log.Lvl(ctx.GlobalInt(verbosityFlag.Name)))
|
glogger.Verbosity(log.Lvl(ctx.GlobalInt(verbosityFlag.Name)))
|
||||||
glogger.Vmodule(ctx.GlobalString(vmoduleFlag.Name))
|
glogger.Vmodule(ctx.GlobalString(vmoduleFlag.Name))
|
||||||
glogger.BacktraceAt(ctx.GlobalString(backtraceAtFlag.Name))
|
glogger.BacktraceAt(ctx.GlobalString(backtraceAtFlag.Name))
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -18,6 +19,30 @@ const (
|
|||||||
termMsgJust = 40
|
termMsgJust = 40
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// locationTrims are trimmed for display to avoid unwieldy log lines.
|
||||||
|
var locationTrims = []string{
|
||||||
|
"github.com/ethereum/go-ethereum/",
|
||||||
|
"github.com/ethereum/ethash/",
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrintOrigins sets or unsets log location (file:line) printing for terminal
|
||||||
|
// format output.
|
||||||
|
func PrintOrigins(print bool) {
|
||||||
|
if print {
|
||||||
|
atomic.StoreUint32(&locationEnabled, 1)
|
||||||
|
} else {
|
||||||
|
atomic.StoreUint32(&locationEnabled, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// locationEnabled is an atomic flag controlling whether the terminal formatter
|
||||||
|
// should append the log locations too when printing entries.
|
||||||
|
var locationEnabled uint32
|
||||||
|
|
||||||
|
// locationLength is the maxmimum path length encountered, which all logs are
|
||||||
|
// padded to to aid in alignment.
|
||||||
|
var locationLength uint32
|
||||||
|
|
||||||
type Format interface {
|
type Format interface {
|
||||||
Format(r *Record) []byte
|
Format(r *Record) []byte
|
||||||
}
|
}
|
||||||
@ -64,12 +89,33 @@ func TerminalFormat() Format {
|
|||||||
|
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
lvl := strings.ToUpper(r.Lvl.String())
|
lvl := strings.ToUpper(r.Lvl.String())
|
||||||
if color > 0 {
|
if atomic.LoadUint32(&locationEnabled) != 0 {
|
||||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %s ", color, lvl, r.Time.Format(termTimeFormat), r.Msg)
|
// Log origin printing was requested, format the location path and line number
|
||||||
} else {
|
location := fmt.Sprintf("%+v", r.Call)
|
||||||
fmt.Fprintf(b, "[%s] [%s] %s ", lvl, r.Time.Format(termTimeFormat), r.Msg)
|
for _, prefix := range locationTrims {
|
||||||
}
|
location = strings.TrimPrefix(location, prefix)
|
||||||
|
}
|
||||||
|
// Maintain the maximum location length for fancyer alignment
|
||||||
|
align := int(atomic.LoadUint32(&locationLength))
|
||||||
|
if align < len(location) {
|
||||||
|
align = len(location)
|
||||||
|
atomic.StoreUint32(&locationLength, uint32(align))
|
||||||
|
}
|
||||||
|
padding := strings.Repeat(" ", align-len(location))
|
||||||
|
|
||||||
|
// Assemble and print the log heading
|
||||||
|
if color > 0 {
|
||||||
|
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s|%s]%s %s ", color, lvl, r.Time.Format(termTimeFormat), location, padding, r.Msg)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(b, "[%s] [%s|%s]%s %s ", lvl, r.Time.Format(termTimeFormat), location, padding, r.Msg)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if color > 0 {
|
||||||
|
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %s ", color, lvl, r.Time.Format(termTimeFormat), r.Msg)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(b, "[%s] [%s] %s ", lvl, r.Time.Format(termTimeFormat), r.Msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
// try to justify the log output for short messages
|
// try to justify the log output for short messages
|
||||||
if len(r.Ctx) > 0 && len(r.Msg) < termMsgJust {
|
if len(r.Ctx) > 0 && len(r.Msg) < termMsgJust {
|
||||||
b.Write(bytes.Repeat([]byte{' '}, termMsgJust-len(r.Msg)))
|
b.Write(bytes.Repeat([]byte{' '}, termMsgJust-len(r.Msg)))
|
||||||
|
Loading…
Reference in New Issue
Block a user