forked from quic-go/quic-go
create a logger interface and use it everywhere
This commit is contained in:
@@ -11,8 +11,6 @@ import (
|
||||
// LogLevel of quic-go
|
||||
type LogLevel uint8
|
||||
|
||||
const logEnv = "QUIC_GO_LOG_LEVEL"
|
||||
|
||||
const (
|
||||
// LogLevelNothing disables
|
||||
LogLevelNothing LogLevel = iota
|
||||
@@ -24,72 +22,92 @@ const (
|
||||
LogLevelDebug
|
||||
)
|
||||
|
||||
var (
|
||||
logLevel = LogLevelNothing
|
||||
timeFormat = ""
|
||||
)
|
||||
const logEnv = "QUIC_GO_LOG_LEVEL"
|
||||
|
||||
// A Logger logs.
|
||||
type Logger interface {
|
||||
SetLogLevel(LogLevel)
|
||||
SetLogTimeFormat(format string)
|
||||
Debug() bool
|
||||
|
||||
Errorf(format string, args ...interface{})
|
||||
Infof(format string, args ...interface{})
|
||||
Debugf(format string, args ...interface{})
|
||||
}
|
||||
|
||||
// DefaultLogger is used by quic-go for logging.
|
||||
var DefaultLogger Logger
|
||||
|
||||
type defaultLogger struct {
|
||||
logLevel LogLevel
|
||||
timeFormat string
|
||||
}
|
||||
|
||||
var _ Logger = &defaultLogger{}
|
||||
|
||||
// SetLogLevel sets the log level
|
||||
func SetLogLevel(level LogLevel) {
|
||||
logLevel = level
|
||||
func (l *defaultLogger) SetLogLevel(level LogLevel) {
|
||||
l.logLevel = level
|
||||
}
|
||||
|
||||
// SetLogTimeFormat sets the format of the timestamp
|
||||
// an empty string disables the logging of timestamps
|
||||
func SetLogTimeFormat(format string) {
|
||||
func (l *defaultLogger) SetLogTimeFormat(format string) {
|
||||
log.SetFlags(0) // disable timestamp logging done by the log package
|
||||
timeFormat = format
|
||||
l.timeFormat = format
|
||||
}
|
||||
|
||||
// Debugf logs something
|
||||
func Debugf(format string, args ...interface{}) {
|
||||
if logLevel == LogLevelDebug {
|
||||
logMessage(format, args...)
|
||||
func (l *defaultLogger) Debugf(format string, args ...interface{}) {
|
||||
if l.logLevel == LogLevelDebug {
|
||||
l.logMessage(format, args...)
|
||||
}
|
||||
}
|
||||
|
||||
// Infof logs something
|
||||
func Infof(format string, args ...interface{}) {
|
||||
if logLevel >= LogLevelInfo {
|
||||
logMessage(format, args...)
|
||||
func (l *defaultLogger) Infof(format string, args ...interface{}) {
|
||||
if l.logLevel >= LogLevelInfo {
|
||||
l.logMessage(format, args...)
|
||||
}
|
||||
}
|
||||
|
||||
// Errorf logs something
|
||||
func Errorf(format string, args ...interface{}) {
|
||||
if logLevel >= LogLevelError {
|
||||
logMessage(format, args...)
|
||||
func (l *defaultLogger) Errorf(format string, args ...interface{}) {
|
||||
if l.logLevel >= LogLevelError {
|
||||
l.logMessage(format, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func logMessage(format string, args ...interface{}) {
|
||||
if len(timeFormat) > 0 {
|
||||
log.Printf(time.Now().Format(timeFormat)+" "+format, args...)
|
||||
func (l *defaultLogger) logMessage(format string, args ...interface{}) {
|
||||
if len(l.timeFormat) > 0 {
|
||||
log.Printf(time.Now().Format(l.timeFormat)+" "+format, args...)
|
||||
} else {
|
||||
log.Printf(format, args...)
|
||||
}
|
||||
}
|
||||
|
||||
// Debug returns true if the log level is LogLevelDebug
|
||||
func Debug() bool {
|
||||
return logLevel == LogLevelDebug
|
||||
func (l *defaultLogger) Debug() bool {
|
||||
return l.logLevel == LogLevelDebug
|
||||
}
|
||||
|
||||
func init() {
|
||||
readLoggingEnv()
|
||||
DefaultLogger = &defaultLogger{}
|
||||
DefaultLogger.SetLogLevel(readLoggingEnv())
|
||||
}
|
||||
|
||||
func readLoggingEnv() {
|
||||
func readLoggingEnv() LogLevel {
|
||||
switch strings.ToLower(os.Getenv(logEnv)) {
|
||||
case "":
|
||||
return
|
||||
return LogLevelNothing
|
||||
case "debug":
|
||||
logLevel = LogLevelDebug
|
||||
return LogLevelDebug
|
||||
case "info":
|
||||
logLevel = LogLevelInfo
|
||||
return LogLevelInfo
|
||||
case "error":
|
||||
logLevel = LogLevelError
|
||||
return LogLevelError
|
||||
default:
|
||||
fmt.Fprintln(os.Stderr, "invalid quic-go log level, see https://github.com/lucas-clemente/quic-go/wiki/Logging")
|
||||
return LogLevelNothing
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,22 +11,16 @@ import (
|
||||
)
|
||||
|
||||
var _ = Describe("Log", func() {
|
||||
var (
|
||||
b *bytes.Buffer
|
||||
|
||||
initialTimeFormat string
|
||||
)
|
||||
var b *bytes.Buffer
|
||||
|
||||
BeforeEach(func() {
|
||||
b = bytes.NewBuffer([]byte{})
|
||||
b = &bytes.Buffer{}
|
||||
log.SetOutput(b)
|
||||
initialTimeFormat = timeFormat
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
log.SetOutput(os.Stdout)
|
||||
SetLogLevel(LogLevelNothing)
|
||||
timeFormat = initialTimeFormat
|
||||
DefaultLogger.SetLogLevel(LogLevelNothing)
|
||||
})
|
||||
|
||||
It("the log level has the correct numeric value", func() {
|
||||
@@ -37,103 +31,97 @@ var _ = Describe("Log", func() {
|
||||
})
|
||||
|
||||
It("log level nothing", func() {
|
||||
SetLogLevel(LogLevelNothing)
|
||||
Debugf("debug")
|
||||
Infof("info")
|
||||
Errorf("err")
|
||||
DefaultLogger.SetLogLevel(LogLevelNothing)
|
||||
DefaultLogger.Debugf("debug")
|
||||
DefaultLogger.Infof("info")
|
||||
DefaultLogger.Errorf("err")
|
||||
Expect(b.Bytes()).To(Equal([]byte("")))
|
||||
})
|
||||
|
||||
It("log level err", func() {
|
||||
SetLogLevel(LogLevelError)
|
||||
Debugf("debug")
|
||||
Infof("info")
|
||||
Errorf("err")
|
||||
DefaultLogger.SetLogLevel(LogLevelError)
|
||||
DefaultLogger.Debugf("debug")
|
||||
DefaultLogger.Infof("info")
|
||||
DefaultLogger.Errorf("err")
|
||||
Expect(b.Bytes()).To(ContainSubstring("err\n"))
|
||||
Expect(b.Bytes()).ToNot(ContainSubstring("info"))
|
||||
Expect(b.Bytes()).ToNot(ContainSubstring("debug"))
|
||||
})
|
||||
|
||||
It("log level info", func() {
|
||||
SetLogLevel(LogLevelInfo)
|
||||
Debugf("debug")
|
||||
Infof("info")
|
||||
Errorf("err")
|
||||
DefaultLogger.SetLogLevel(LogLevelInfo)
|
||||
DefaultLogger.Debugf("debug")
|
||||
DefaultLogger.Infof("info")
|
||||
DefaultLogger.Errorf("err")
|
||||
Expect(b.Bytes()).To(ContainSubstring("err\n"))
|
||||
Expect(b.Bytes()).To(ContainSubstring("info\n"))
|
||||
Expect(b.Bytes()).ToNot(ContainSubstring("debug"))
|
||||
})
|
||||
|
||||
It("log level debug", func() {
|
||||
SetLogLevel(LogLevelDebug)
|
||||
Debugf("debug")
|
||||
Infof("info")
|
||||
Errorf("err")
|
||||
DefaultLogger.SetLogLevel(LogLevelDebug)
|
||||
DefaultLogger.Debugf("debug")
|
||||
DefaultLogger.Infof("info")
|
||||
DefaultLogger.Errorf("err")
|
||||
Expect(b.Bytes()).To(ContainSubstring("err\n"))
|
||||
Expect(b.Bytes()).To(ContainSubstring("info\n"))
|
||||
Expect(b.Bytes()).To(ContainSubstring("debug\n"))
|
||||
})
|
||||
|
||||
It("doesn't add a timestamp if the time format is empty", func() {
|
||||
SetLogLevel(LogLevelDebug)
|
||||
SetLogTimeFormat("")
|
||||
Debugf("debug")
|
||||
DefaultLogger.SetLogLevel(LogLevelDebug)
|
||||
DefaultLogger.SetLogTimeFormat("")
|
||||
DefaultLogger.Debugf("debug")
|
||||
Expect(b.Bytes()).To(Equal([]byte("debug\n")))
|
||||
})
|
||||
|
||||
It("adds a timestamp", func() {
|
||||
format := "Jan 2, 2006"
|
||||
SetLogTimeFormat(format)
|
||||
SetLogLevel(LogLevelInfo)
|
||||
Infof("info")
|
||||
DefaultLogger.SetLogTimeFormat(format)
|
||||
DefaultLogger.SetLogLevel(LogLevelInfo)
|
||||
DefaultLogger.Infof("info")
|
||||
t, err := time.Parse(format, string(b.Bytes()[:b.Len()-6]))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(t).To(BeTemporally("~", time.Now(), 25*time.Hour))
|
||||
})
|
||||
|
||||
It("says whether debug is enabled", func() {
|
||||
Expect(Debug()).To(BeFalse())
|
||||
SetLogLevel(LogLevelDebug)
|
||||
Expect(Debug()).To(BeTrue())
|
||||
Expect(DefaultLogger.Debug()).To(BeFalse())
|
||||
DefaultLogger.SetLogLevel(LogLevelDebug)
|
||||
Expect(DefaultLogger.Debug()).To(BeTrue())
|
||||
})
|
||||
|
||||
Context("reading from env", func() {
|
||||
BeforeEach(func() {
|
||||
Expect(logLevel).To(Equal(LogLevelNothing))
|
||||
Expect(DefaultLogger.(*defaultLogger).logLevel).To(Equal(LogLevelNothing))
|
||||
})
|
||||
|
||||
It("reads DEBUG", func() {
|
||||
os.Setenv(logEnv, "DEBUG")
|
||||
readLoggingEnv()
|
||||
Expect(logLevel).To(Equal(LogLevelDebug))
|
||||
Expect(readLoggingEnv()).To(Equal(LogLevelDebug))
|
||||
})
|
||||
|
||||
It("reads debug", func() {
|
||||
os.Setenv(logEnv, "debug")
|
||||
readLoggingEnv()
|
||||
Expect(logLevel).To(Equal(LogLevelDebug))
|
||||
Expect(readLoggingEnv()).To(Equal(LogLevelDebug))
|
||||
})
|
||||
|
||||
It("reads INFO", func() {
|
||||
os.Setenv(logEnv, "INFO")
|
||||
readLoggingEnv()
|
||||
Expect(logLevel).To(Equal(LogLevelInfo))
|
||||
Expect(readLoggingEnv()).To(Equal(LogLevelInfo))
|
||||
})
|
||||
|
||||
It("reads ERROR", func() {
|
||||
os.Setenv(logEnv, "ERROR")
|
||||
readLoggingEnv()
|
||||
Expect(logLevel).To(Equal(LogLevelError))
|
||||
Expect(readLoggingEnv()).To(Equal(LogLevelError))
|
||||
})
|
||||
|
||||
It("does not error reading invalid log levels from env", func() {
|
||||
Expect(logLevel).To(Equal(LogLevelNothing))
|
||||
os.Setenv(logEnv, "")
|
||||
readLoggingEnv()
|
||||
Expect(logLevel).To(Equal(LogLevelNothing))
|
||||
Expect(readLoggingEnv()).To(Equal(LogLevelNothing))
|
||||
os.Setenv(logEnv, "asdf")
|
||||
readLoggingEnv()
|
||||
Expect(logLevel).To(Equal(LogLevelNothing))
|
||||
Expect(readLoggingEnv()).To(Equal(LogLevelNothing))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user