2017-03-18 19:00:40 +00:00
|
|
|
package params
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"sync"
|
|
|
|
|
2017-05-02 14:30:11 +00:00
|
|
|
"github.com/ethereum/go-ethereum/log"
|
2017-03-18 19:00:40 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Logger is wrapper for custom logging
|
|
|
|
type Logger struct {
|
2017-05-02 14:30:11 +00:00
|
|
|
origHandler log.Handler
|
|
|
|
handler log.Handler
|
|
|
|
config *NodeConfig
|
2017-03-18 19:00:40 +00:00
|
|
|
}
|
|
|
|
|
2017-05-02 14:30:11 +00:00
|
|
|
var (
|
|
|
|
onceInitNodeLogger sync.Once
|
|
|
|
nodeLoggerInstance *Logger
|
|
|
|
)
|
2017-03-18 19:00:40 +00:00
|
|
|
|
|
|
|
// SetupLogger configs logger using parameters in config
|
2017-05-02 14:30:11 +00:00
|
|
|
func SetupLogger(config *NodeConfig) (*Logger, error) {
|
2017-03-18 19:00:40 +00:00
|
|
|
if !config.LogEnabled {
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
2017-05-02 14:30:11 +00:00
|
|
|
onceInitNodeLogger.Do(func() {
|
|
|
|
nodeLoggerInstance = &Logger{
|
|
|
|
config: config,
|
|
|
|
origHandler: log.Root().GetHandler(),
|
|
|
|
}
|
2017-05-02 14:35:37 +00:00
|
|
|
nodeLoggerInstance.handler = nodeLoggerInstance.makeLogHandler(parseLogLevel(config.LogLevel))
|
2017-03-18 19:00:40 +00:00
|
|
|
})
|
|
|
|
|
2017-05-02 14:30:11 +00:00
|
|
|
if err := nodeLoggerInstance.Start(); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nodeLoggerInstance, nil
|
2017-03-18 19:00:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetV allows to dynamically change log level of messages being written
|
|
|
|
func (l *Logger) SetV(logLevel string) {
|
2017-05-02 14:30:11 +00:00
|
|
|
log.Root().SetHandler(l.makeLogHandler(parseLogLevel(logLevel)))
|
2017-03-18 19:00:40 +00:00
|
|
|
}
|
|
|
|
|
2017-05-02 14:30:11 +00:00
|
|
|
// Start installs logger handler
|
|
|
|
func (l *Logger) Start() error {
|
|
|
|
log.Root().SetHandler(l.handler)
|
|
|
|
return nil
|
2017-03-18 19:00:40 +00:00
|
|
|
}
|
|
|
|
|
2017-05-02 14:30:11 +00:00
|
|
|
// Stop replaces our handler back to the original log handler
|
|
|
|
func (l *Logger) Stop() error {
|
|
|
|
log.Root().SetHandler(l.origHandler)
|
|
|
|
return nil
|
2017-03-18 19:00:40 +00:00
|
|
|
}
|
|
|
|
|
2017-05-02 14:30:11 +00:00
|
|
|
// makeLogHandler creates a log handler for a given level and node configuration
|
|
|
|
func (l *Logger) makeLogHandler(lvl log.Lvl) log.Handler {
|
|
|
|
var handler log.Handler
|
|
|
|
logFilePath := filepath.Join(l.config.DataDir, l.config.LogFile)
|
2017-05-02 14:35:37 +00:00
|
|
|
fileHandler := log.Must.FileHandler(logFilePath, log.LogfmtFormat())
|
|
|
|
stderrHandler := log.StreamHandler(os.Stderr, log.TerminalFormat(true))
|
2017-05-02 14:30:11 +00:00
|
|
|
if l.config.LogToStderr {
|
|
|
|
handler = log.MultiHandler(
|
2017-05-02 14:35:37 +00:00
|
|
|
log.LvlFilterHandler(lvl, log.CallerFileHandler(log.CallerFuncHandler(stderrHandler))),
|
|
|
|
log.LvlFilterHandler(lvl, fileHandler))
|
2017-05-02 14:30:11 +00:00
|
|
|
} else {
|
2017-05-02 14:35:37 +00:00
|
|
|
handler = log.LvlFilterHandler(lvl, fileHandler)
|
2017-03-18 19:00:40 +00:00
|
|
|
}
|
|
|
|
|
2017-05-02 14:30:11 +00:00
|
|
|
return handler
|
2017-03-18 19:00:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// parseLogLevel parses string and returns logger.* constant
|
2017-05-02 14:30:11 +00:00
|
|
|
func parseLogLevel(logLevel string) log.Lvl {
|
2017-03-18 19:00:40 +00:00
|
|
|
switch logLevel {
|
|
|
|
case "ERROR":
|
2017-05-02 14:30:11 +00:00
|
|
|
return log.LvlError
|
2017-03-18 19:00:40 +00:00
|
|
|
case "WARNING":
|
2017-05-02 14:30:11 +00:00
|
|
|
return log.LvlWarn
|
2017-03-18 19:00:40 +00:00
|
|
|
case "INFO":
|
2017-05-02 14:30:11 +00:00
|
|
|
return log.LvlInfo
|
2017-03-18 19:00:40 +00:00
|
|
|
case "DEBUG":
|
2017-05-02 14:30:11 +00:00
|
|
|
return log.LvlDebug
|
|
|
|
case "TRACE":
|
|
|
|
return log.LvlTrace
|
2017-03-18 19:00:40 +00:00
|
|
|
}
|
|
|
|
|
2017-05-02 14:30:11 +00:00
|
|
|
return log.LvlInfo
|
2017-03-18 19:00:40 +00:00
|
|
|
}
|