ethlog: add Godoc documentation, remove README
This commit is contained in:
parent
a6265cb49a
commit
e0f93c74c5
@ -1,62 +0,0 @@
|
|||||||
## Features
|
|
||||||
|
|
||||||
- packages use tagged logger sending log messages to shared (process-wide) logging engine
|
|
||||||
- log writers (interface ethlog.LogSystem) can be added to the logging engine by wrappers/guis/clients
|
|
||||||
- shared logging engine dispatching to multiple log systems
|
|
||||||
- log level can be set separately per log system
|
|
||||||
- async logging thread: logging IO does not block main thread
|
|
||||||
- log messages are synchronously stringified to avoid incorrectly logging of changed states
|
|
||||||
- log level enum: ethlog.LogLevel: Silence, ErrorLevel, WarnLevel, InfoLevel, DebugLevel, DebugDetailLevel
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
In an ethereum component package:
|
|
||||||
|
|
||||||
import "github.com/ethereum/eth-go/ethlog"
|
|
||||||
|
|
||||||
// package-wide logger using tag
|
|
||||||
var logger = ethlog.NewLogger("TAG")
|
|
||||||
|
|
||||||
Logger provides named Printf and Println style methods for all loglevels
|
|
||||||
|
|
||||||
logger.Infoln("this is info") # > [TAG] This is info
|
|
||||||
logger.Infof("this %v is info", object) # > [TAG] This object is info
|
|
||||||
|
|
||||||
Ethereum wrappers should register log systems conforming to ethlog.LogSystem
|
|
||||||
|
|
||||||
import "github.com/ethereum/eth-go/ethlog"
|
|
||||||
|
|
||||||
type CustomLogWriter struct {
|
|
||||||
logLevel ethlog.LogLevel
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *TestLogSystem) SetLogLevel(i LogLevel) {
|
|
||||||
t.level = i
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *TestLogSystem) GetLogLevel() LogLevel {
|
|
||||||
return t.level
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *CustomLogWriter) Printf(format string, v...interface{}) {
|
|
||||||
//....
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *CustomLogWriter) Println(v...interface{}) {
|
|
||||||
//....
|
|
||||||
}
|
|
||||||
|
|
||||||
ethlog.AddLogWriter(&CustomLogWriter{})
|
|
||||||
|
|
||||||
ethlog also provides constructors for that wrap io.Writers into a standard logger with a settable level:
|
|
||||||
|
|
||||||
filename := "test.log"
|
|
||||||
file, _ := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, os.ModePerm)
|
|
||||||
fileLogSystem := NewStdLogSystem(file, 0, WarnLevel)
|
|
||||||
AddLogSystem(fileLogSystem)
|
|
||||||
stdOutLogSystem := NewStdLogSystem(os.Stdout, 0, WarnLevel)
|
|
||||||
AddLogSystem(stdOutLogSystem)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,3 +1,36 @@
|
|||||||
|
/*
|
||||||
|
Package ethlog implements a multi-output leveled logger.
|
||||||
|
|
||||||
|
Features
|
||||||
|
|
||||||
|
Other packages use tagged logger to send log messages to shared (process-wide) logging engine.
|
||||||
|
The shared logging engine dispatches to multiple log systems.
|
||||||
|
The log level can be set separately per log system.
|
||||||
|
|
||||||
|
Logging is asynchrounous and does not block the main thread. Message
|
||||||
|
formatting is performed by the caller goroutine to avoid incorrect
|
||||||
|
logging of mutable state.
|
||||||
|
|
||||||
|
Usage
|
||||||
|
|
||||||
|
The Logger type provides named Printf and Println style methods for
|
||||||
|
all loglevels. Each ethereum component should have its own logger with
|
||||||
|
a unique prefix.
|
||||||
|
|
||||||
|
logger.Infoln("this is info") # > [TAG] This is info
|
||||||
|
logger.Infof("this %v is info", object) # > [TAG] This object is info
|
||||||
|
|
||||||
|
ethlog also provides constructors for that wrap io.Writers into a
|
||||||
|
standard logger with a settable level:
|
||||||
|
|
||||||
|
filename := "test.log"
|
||||||
|
file, _ := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, os.ModePerm)
|
||||||
|
fileLogSystem := NewStdLogSystem(file, 0, WarnLevel)
|
||||||
|
AddLogSystem(fileLogSystem)
|
||||||
|
stdOutLogSystem := NewStdLogSystem(os.Stdout, 0, WarnLevel)
|
||||||
|
AddLogSystem(stdOutLogSystem)
|
||||||
|
|
||||||
|
*/
|
||||||
package ethlog
|
package ethlog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -9,6 +42,8 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// LogSystem is implemented by log output devices.
|
||||||
|
// All methods can be called concurrently from multiple goroutines.
|
||||||
type LogSystem interface {
|
type LogSystem interface {
|
||||||
GetLogLevel() LogLevel
|
GetLogLevel() LogLevel
|
||||||
SetLogLevel(i LogLevel)
|
SetLogLevel(i LogLevel)
|
||||||
@ -33,6 +68,7 @@ func newPrintfLogMessage(level LogLevel, tag string, format string, v ...interfa
|
|||||||
type LogLevel uint8
|
type LogLevel uint8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// Standard log levels
|
||||||
Silence LogLevel = iota
|
Silence LogLevel = iota
|
||||||
ErrorLevel
|
ErrorLevel
|
||||||
WarnLevel
|
WarnLevel
|
||||||
@ -102,7 +138,7 @@ func send(msg *logMessage) {
|
|||||||
logMessages <- msg
|
logMessages <- msg
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset removes all registered log systems.
|
// Reset removes all active log systems.
|
||||||
func Reset() {
|
func Reset() {
|
||||||
mutex.Lock()
|
mutex.Lock()
|
||||||
logSystems = nil
|
logSystems = nil
|
||||||
@ -117,6 +153,15 @@ func Flush() {
|
|||||||
<-waiter
|
<-waiter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddLogSystem starts printing messages to the given LogSystem.
|
||||||
|
func AddLogSystem(logSystem LogSystem) {
|
||||||
|
mutex.Lock()
|
||||||
|
logSystems = append(logSystems, logSystem)
|
||||||
|
mutex.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Logger prints messages prefixed by a given tag.
|
||||||
|
// You should create one with a unique tag for each high-level component.
|
||||||
type Logger struct {
|
type Logger struct {
|
||||||
tag string
|
tag string
|
||||||
}
|
}
|
||||||
@ -125,12 +170,6 @@ func NewLogger(tag string) *Logger {
|
|||||||
return &Logger{tag}
|
return &Logger{tag}
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddLogSystem(logSystem LogSystem) {
|
|
||||||
mutex.Lock()
|
|
||||||
logSystems = append(logSystems, logSystem)
|
|
||||||
mutex.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *Logger) sendln(level LogLevel, v ...interface{}) {
|
func (logger *Logger) sendln(level LogLevel, v ...interface{}) {
|
||||||
if logMessages != nil {
|
if logMessages != nil {
|
||||||
msg := newPrintlnLogMessage(level, logger.tag, v...)
|
msg := newPrintlnLogMessage(level, logger.tag, v...)
|
||||||
@ -145,80 +184,94 @@ func (logger *Logger) sendf(level LogLevel, format string, v ...interface{}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Errorln writes a message with ErrorLevel.
|
||||||
func (logger *Logger) Errorln(v ...interface{}) {
|
func (logger *Logger) Errorln(v ...interface{}) {
|
||||||
logger.sendln(ErrorLevel, v...)
|
logger.sendln(ErrorLevel, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warnln writes a message with WarnLevel.
|
||||||
func (logger *Logger) Warnln(v ...interface{}) {
|
func (logger *Logger) Warnln(v ...interface{}) {
|
||||||
logger.sendln(WarnLevel, v...)
|
logger.sendln(WarnLevel, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Infoln writes a message with InfoLevel.
|
||||||
func (logger *Logger) Infoln(v ...interface{}) {
|
func (logger *Logger) Infoln(v ...interface{}) {
|
||||||
logger.sendln(InfoLevel, v...)
|
logger.sendln(InfoLevel, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Debugln writes a message with DebugLevel.
|
||||||
func (logger *Logger) Debugln(v ...interface{}) {
|
func (logger *Logger) Debugln(v ...interface{}) {
|
||||||
logger.sendln(DebugLevel, v...)
|
logger.sendln(DebugLevel, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DebugDetailln writes a message with DebugDetailLevel.
|
||||||
func (logger *Logger) DebugDetailln(v ...interface{}) {
|
func (logger *Logger) DebugDetailln(v ...interface{}) {
|
||||||
logger.sendln(DebugDetailLevel, v...)
|
logger.sendln(DebugDetailLevel, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Errorf writes a message with ErrorLevel.
|
||||||
func (logger *Logger) Errorf(format string, v ...interface{}) {
|
func (logger *Logger) Errorf(format string, v ...interface{}) {
|
||||||
logger.sendf(ErrorLevel, format, v...)
|
logger.sendf(ErrorLevel, format, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warnf writes a message with WarnLevel.
|
||||||
func (logger *Logger) Warnf(format string, v ...interface{}) {
|
func (logger *Logger) Warnf(format string, v ...interface{}) {
|
||||||
logger.sendf(WarnLevel, format, v...)
|
logger.sendf(WarnLevel, format, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Infof writes a message with InfoLevel.
|
||||||
func (logger *Logger) Infof(format string, v ...interface{}) {
|
func (logger *Logger) Infof(format string, v ...interface{}) {
|
||||||
logger.sendf(InfoLevel, format, v...)
|
logger.sendf(InfoLevel, format, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Debugf writes a message with DebugLevel.
|
||||||
func (logger *Logger) Debugf(format string, v ...interface{}) {
|
func (logger *Logger) Debugf(format string, v ...interface{}) {
|
||||||
logger.sendf(DebugLevel, format, v...)
|
logger.sendf(DebugLevel, format, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DebugDetailf writes a message with DebugDetailLevel.
|
||||||
func (logger *Logger) DebugDetailf(format string, v ...interface{}) {
|
func (logger *Logger) DebugDetailf(format string, v ...interface{}) {
|
||||||
logger.sendf(DebugDetailLevel, format, v...)
|
logger.sendf(DebugDetailLevel, format, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fatalln writes a message with ErrorLevel and exits the program.
|
||||||
func (logger *Logger) Fatalln(v ...interface{}) {
|
func (logger *Logger) Fatalln(v ...interface{}) {
|
||||||
logger.sendln(ErrorLevel, v...)
|
logger.sendln(ErrorLevel, v...)
|
||||||
Flush()
|
Flush()
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fatalf writes a message with ErrorLevel and exits the program.
|
||||||
func (logger *Logger) Fatalf(format string, v ...interface{}) {
|
func (logger *Logger) Fatalf(format string, v ...interface{}) {
|
||||||
logger.sendf(ErrorLevel, format, v...)
|
logger.sendf(ErrorLevel, format, v...)
|
||||||
Flush()
|
Flush()
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
type StdLogSystem struct {
|
// NewStdLogSystem creates a LogSystem that prints to the given writer.
|
||||||
|
// The flag values are defined package log.
|
||||||
|
func NewStdLogSystem(writer io.Writer, flags int, level LogLevel) LogSystem {
|
||||||
|
logger := log.New(writer, "", flags)
|
||||||
|
return &stdLogSystem{logger, uint32(level)}
|
||||||
|
}
|
||||||
|
|
||||||
|
type stdLogSystem struct {
|
||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
level uint32
|
level uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *StdLogSystem) Println(v ...interface{}) {
|
func (t *stdLogSystem) Println(v ...interface{}) {
|
||||||
t.logger.Println(v...)
|
t.logger.Println(v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *StdLogSystem) Printf(format string, v ...interface{}) {
|
func (t *stdLogSystem) Printf(format string, v ...interface{}) {
|
||||||
t.logger.Printf(format, v...)
|
t.logger.Printf(format, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *StdLogSystem) SetLogLevel(i LogLevel) {
|
func (t *stdLogSystem) SetLogLevel(i LogLevel) {
|
||||||
atomic.StoreUint32(&t.level, uint32(i))
|
atomic.StoreUint32(&t.level, uint32(i))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *StdLogSystem) GetLogLevel() LogLevel {
|
func (t *stdLogSystem) GetLogLevel() LogLevel {
|
||||||
return LogLevel(atomic.LoadUint32(&t.level))
|
return LogLevel(atomic.LoadUint32(&t.level))
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStdLogSystem(writer io.Writer, flags int, level LogLevel) *StdLogSystem {
|
|
||||||
logger := log.New(writer, "", flags)
|
|
||||||
return &StdLogSystem{logger, uint32(level)}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user