From 78cff9e3a4c71d003c5ab3f5747ccae1dbc959fe Mon Sep 17 00:00:00 2001 From: zelig Date: Sat, 21 Mar 2015 09:20:47 +0000 Subject: independent flag for json structured logging - logjson flag remove logformat flag - passed to eth Config - logsystem not a field of Ethereum - LogSystem does not need to expose GetLogLevel/SetLogLevel - message struct just implements more generic LogMsg interface - LogMsg is a fmt.Stringer with Level() - jsonMsg ([]byte) implements LogMsg - remove "raw" systems - move level logic inside StdLogSystem - logsystems only print their kind of msg: jsonLogSystem prints jsonMsg, StdLogSystem prints stdMsg --- logger/log.go | 24 +++++++++++++------- logger/loggers.go | 7 +++--- logger/loggers_test.go | 10 +++++---- logger/logsystem.go | 61 ++++++++++++++------------------------------------ logger/sys.go | 45 ++++++++++++++++++++++++------------- 5 files changed, 72 insertions(+), 75 deletions(-) (limited to 'logger') diff --git a/logger/log.go b/logger/log.go index fab004d0a..e2a35ba53 100644 --- a/logger/log.go +++ b/logger/log.go @@ -18,7 +18,7 @@ func openLogFile(datadir string, filename string) *os.File { return file } -func New(datadir string, logFile string, logLevel int, logFormat string) LogSystem { +func New(datadir string, logFile string, logLevel int) LogSystem { var writer io.Writer if logFile == "" { writer = os.Stdout @@ -27,14 +27,22 @@ func New(datadir string, logFile string, logLevel int, logFormat string) LogSyst } var sys LogSystem - switch logFormat { - case "raw": - sys = NewRawLogSystem(writer, 0, LogLevel(logLevel)) - case "json": - sys = NewJsonLogSystem(writer, 0, LogLevel(logLevel)) - default: - sys = NewStdLogSystem(writer, log.LstdFlags, LogLevel(logLevel)) + sys = NewStdLogSystem(writer, log.LstdFlags, LogLevel(logLevel)) + AddLogSystem(sys) + + return sys +} + +func NewJSONsystem(datadir string, logFile string) LogSystem { + var writer io.Writer + if logFile == "-" { + writer = os.Stdout + } else { + writer = openLogFile(datadir, logFile) } + + var sys LogSystem + sys = NewJsonLogSystem(writer) AddLogSystem(sys) return sys diff --git a/logger/loggers.go b/logger/loggers.go index 25263853a..42c8cbc07 100644 --- a/logger/loggers.go +++ b/logger/loggers.go @@ -28,7 +28,6 @@ const ( InfoLevel DebugLevel DebugDetailLevel - JsonLevel = 1000 ) // A Logger prints messages prefixed by a given tag. It provides named @@ -43,11 +42,11 @@ func NewLogger(tag string) *Logger { } func (logger *Logger) Sendln(level LogLevel, v ...interface{}) { - logMessageC <- message{level, logger.tag + fmt.Sprintln(v...)} + logMessageC <- stdMsg{level, logger.tag + fmt.Sprintln(v...)} } func (logger *Logger) Sendf(level LogLevel, format string, v ...interface{}) { - logMessageC <- message{level, logger.tag + fmt.Sprintf(format, v...)} + logMessageC <- stdMsg{level, logger.tag + fmt.Sprintf(format, v...)} } // Errorln writes a message with ErrorLevel. @@ -129,6 +128,6 @@ func (logger *JsonLogger) LogJson(v JsonLog) { } jsontxt, _ := json.Marshal(obj) - logMessageC <- message{JsonLevel, string(jsontxt)} + logMessageC <- (jsonMsg(jsontxt)) } diff --git a/logger/loggers_test.go b/logger/loggers_test.go index adc4df016..276b65b78 100644 --- a/logger/loggers_test.go +++ b/logger/loggers_test.go @@ -15,9 +15,11 @@ type TestLogSystem struct { level LogLevel } -func (ls *TestLogSystem) LogPrint(level LogLevel, msg string) { +func (ls *TestLogSystem) LogPrint(msg LogMsg) { ls.mutex.Lock() - ls.output += msg + if ls.level >= msg.Level() { + ls.output += msg.String() + } ls.mutex.Unlock() } @@ -47,9 +49,9 @@ type blockedLogSystem struct { unblock chan struct{} } -func (ls blockedLogSystem) LogPrint(level LogLevel, msg string) { +func (ls blockedLogSystem) LogPrint(msg LogMsg) { <-ls.unblock - ls.LogSystem.LogPrint(level, msg) + ls.LogSystem.LogPrint(msg) } func TestLoggerFlush(t *testing.T) { diff --git a/logger/logsystem.go b/logger/logsystem.go index 1318a9f96..995cf4240 100644 --- a/logger/logsystem.go +++ b/logger/logsystem.go @@ -9,9 +9,7 @@ import ( // LogSystem is implemented by log output devices. // All methods can be called concurrently from multiple goroutines. type LogSystem interface { - GetLogLevel() LogLevel - SetLogLevel(i LogLevel) - LogPrint(LogLevel, string) + LogPrint(LogMsg) } // NewStdLogSystem creates a LogSystem that prints to the given writer. @@ -26,8 +24,13 @@ type stdLogSystem struct { level uint32 } -func (t *stdLogSystem) LogPrint(level LogLevel, msg string) { - t.logger.Print(msg) +func (t *stdLogSystem) LogPrint(msg LogMsg) { + stdmsg, ok := msg.(stdMsg) + if ok { + if t.GetLogLevel() >= stdmsg.Level() { + t.logger.Print(stdmsg.String()) + } + } } func (t *stdLogSystem) SetLogLevel(i LogLevel) { @@ -38,50 +41,20 @@ func (t *stdLogSystem) GetLogLevel() LogLevel { return LogLevel(atomic.LoadUint32(&t.level)) } -// NewRawLogSystem creates a LogSystem that prints to the given writer without -// adding extra information. Suitable for preformatted output -func NewRawLogSystem(writer io.Writer, flags int, level LogLevel) LogSystem { +// NewJSONLogSystem creates a LogSystem that prints to the given writer without +// adding extra information irrespective of loglevel only if message is JSON type +func NewJsonLogSystem(writer io.Writer) LogSystem { logger := log.New(writer, "", 0) - return &rawLogSystem{logger, uint32(level)} -} - -type rawLogSystem struct { - logger *log.Logger - level uint32 -} - -func (t *rawLogSystem) LogPrint(level LogLevel, msg string) { - t.logger.Print(msg) -} - -func (t *rawLogSystem) SetLogLevel(i LogLevel) { - atomic.StoreUint32(&t.level, uint32(i)) -} - -func (t *rawLogSystem) GetLogLevel() LogLevel { - return LogLevel(atomic.LoadUint32(&t.level)) -} - -// NewRawLogSystem creates a LogSystem that prints to the given writer without -// adding extra information. Suitable for preformatted output -func NewJsonLogSystem(writer io.Writer, flags int, level LogLevel) LogSystem { - logger := log.New(writer, "", 0) - return &jsonLogSystem{logger, uint32(level)} + return &jsonLogSystem{logger} } type jsonLogSystem struct { logger *log.Logger - level uint32 } -func (t *jsonLogSystem) LogPrint(level LogLevel, msg string) { - t.logger.Print(msg) -} - -func (t *jsonLogSystem) SetLogLevel(i LogLevel) { - atomic.StoreUint32(&t.level, uint32(i)) -} - -func (t *jsonLogSystem) GetLogLevel() LogLevel { - return LogLevel(atomic.LoadUint32(&t.level)) +func (t *jsonLogSystem) LogPrint(msg LogMsg) { + jsonmsg, ok := msg.(jsonMsg) + if ok { + t.logger.Print(jsonmsg.String()) + } } diff --git a/logger/sys.go b/logger/sys.go index db4251a52..c4d5c382a 100644 --- a/logger/sys.go +++ b/logger/sys.go @@ -1,16 +1,40 @@ package logger import ( + "fmt" "sync" ) -type message struct { +type stdMsg struct { level LogLevel msg string } +type jsonMsg []byte + +func (m jsonMsg) Level() LogLevel { + return 0 +} + +func (m jsonMsg) String() string { + return string(m) +} + +type LogMsg interface { + Level() LogLevel + fmt.Stringer +} + +func (m stdMsg) Level() LogLevel { + return m.level +} + +func (m stdMsg) String() string { + return m.msg +} + var ( - logMessageC = make(chan message) + logMessageC = make(chan LogMsg) addSystemC = make(chan LogSystem) flushC = make(chan chan struct{}) resetC = make(chan chan struct{}) @@ -27,11 +51,11 @@ const sysBufferSize = 500 func dispatchLoop() { var ( systems []LogSystem - systemIn []chan message + systemIn []chan LogMsg systemWG sync.WaitGroup ) bootSystem := func(sys LogSystem) { - in := make(chan message, sysBufferSize) + in := make(chan LogMsg, sysBufferSize) systemIn = append(systemIn, in) systemWG.Add(1) go sysLoop(sys, in, &systemWG) @@ -73,18 +97,9 @@ func dispatchLoop() { } } -func sysLoop(sys LogSystem, in <-chan message, wg *sync.WaitGroup) { +func sysLoop(sys LogSystem, in <-chan LogMsg, wg *sync.WaitGroup) { for msg := range in { - switch sys.(type) { - case *jsonLogSystem: - if msg.level == JsonLevel { - sys.LogPrint(msg.level, msg.msg) - } - default: - if sys.GetLogLevel() >= msg.level { - sys.LogPrint(msg.level, msg.msg) - } - } + sys.LogPrint(msg) } wg.Done() } -- cgit