mirror of
https://github.com/hibiken/asynq.git
synced 2024-12-25 07:12:17 +08:00
Change LogLevel to satisfy flag.Value interface
This commit is contained in:
parent
d13f7e900f
commit
fa3082e5bb
@ -13,7 +13,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Base supports logging with various log levels.
|
// Base supports logging at various log levels.
|
||||||
type Base interface {
|
type Base interface {
|
||||||
// Debug logs a message at Debug level.
|
// Debug logs a message at Debug level.
|
||||||
Debug(args ...interface{})
|
Debug(args ...interface{})
|
||||||
@ -87,7 +87,7 @@ func NewLogger(base Base) *Logger {
|
|||||||
return &Logger{base: base, level: DebugLevel}
|
return &Logger{base: base, level: DebugLevel}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logger logs message to io.Writer with various log levels.
|
// Logger logs message to io.Writer at various log levels.
|
||||||
type Logger struct {
|
type Logger struct {
|
||||||
base Base
|
base Base
|
||||||
|
|
||||||
@ -121,6 +121,9 @@ const (
|
|||||||
FatalLevel
|
FatalLevel
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// String is part of the fmt.Stringer interface.
|
||||||
|
//
|
||||||
|
// Used for testing and debugging purposes.
|
||||||
func (l Level) String() string {
|
func (l Level) String() string {
|
||||||
switch l {
|
switch l {
|
||||||
case DebugLevel:
|
case DebugLevel:
|
||||||
@ -167,14 +170,14 @@ func (l *Logger) Warn(args ...interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Error(args ...interface{}) {
|
func (l *Logger) Error(args ...interface{}) {
|
||||||
if !l.canLogAt(WarnLevel) {
|
if !l.canLogAt(ErrorLevel) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
l.base.Error(args...)
|
l.base.Error(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Fatal(args ...interface{}) {
|
func (l *Logger) Fatal(args ...interface{}) {
|
||||||
if !l.canLogAt(WarnLevel) {
|
if !l.canLogAt(FatalLevel) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
l.base.Fatal(args...)
|
l.base.Fatal(args...)
|
||||||
|
@ -284,7 +284,9 @@ func TestLoggerErrorf(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLoggerWithMinLevels(t *testing.T) {
|
func TestLoggerWithLowerLevels(t *testing.T) {
|
||||||
|
// Logger should not log messages at a level
|
||||||
|
// lower than the specified level.
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
level Level
|
level Level
|
||||||
op string
|
op string
|
||||||
@ -334,3 +336,53 @@ func TestLoggerWithMinLevels(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLoggerWithSameOrHigherLevels(t *testing.T) {
|
||||||
|
// Logger should log messages at a level
|
||||||
|
// same as or higher than the specified level.
|
||||||
|
tests := []struct {
|
||||||
|
level Level
|
||||||
|
op string
|
||||||
|
}{
|
||||||
|
// same level
|
||||||
|
{DebugLevel, "Debug"},
|
||||||
|
{InfoLevel, "Infof"},
|
||||||
|
{WarnLevel, "Warn"},
|
||||||
|
{ErrorLevel, "Errorf"},
|
||||||
|
// higher level
|
||||||
|
{DebugLevel, "Info"},
|
||||||
|
{InfoLevel, "Warnf"},
|
||||||
|
{WarnLevel, "Error"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range tests {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
logger := NewLogger(newBase(&buf))
|
||||||
|
logger.SetLevel(tc.level)
|
||||||
|
|
||||||
|
switch tc.op {
|
||||||
|
case "Debug":
|
||||||
|
logger.Debug("hello")
|
||||||
|
case "Debugf":
|
||||||
|
logger.Debugf("hello, %s", "world")
|
||||||
|
case "Info":
|
||||||
|
logger.Info("hello")
|
||||||
|
case "Infof":
|
||||||
|
logger.Infof("hello, %s", "world")
|
||||||
|
case "Warn":
|
||||||
|
logger.Warn("hello")
|
||||||
|
case "Warnf":
|
||||||
|
logger.Warnf("hello, %s", "world")
|
||||||
|
case "Error":
|
||||||
|
logger.Error("hello")
|
||||||
|
case "Errorf":
|
||||||
|
logger.Errorf("hello, %s", "world")
|
||||||
|
default:
|
||||||
|
t.Fatalf("unexpected op: %q", tc.op)
|
||||||
|
}
|
||||||
|
|
||||||
|
if buf.String() == "" {
|
||||||
|
t.Errorf("logger.%s did not output log message when level is set to %v", tc.op, tc.level)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
41
server.go
41
server.go
@ -12,6 +12,7 @@ import (
|
|||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -138,7 +139,7 @@ func (fn ErrorHandlerFunc) HandleError(task *Task, err error, retried, maxRetry
|
|||||||
fn(task, err, retried, maxRetry)
|
fn(task, err, retried, maxRetry)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logger supports logging with various log levels.
|
// Logger supports logging at various log levels.
|
||||||
type Logger interface {
|
type Logger interface {
|
||||||
// Debug logs a message at Debug level.
|
// Debug logs a message at Debug level.
|
||||||
Debug(args ...interface{})
|
Debug(args ...interface{})
|
||||||
@ -158,6 +159,8 @@ type Logger interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// LogLevel represents logging level.
|
// LogLevel represents logging level.
|
||||||
|
//
|
||||||
|
// It satisfies flag.Value interface.
|
||||||
type LogLevel int32
|
type LogLevel int32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -181,6 +184,42 @@ const (
|
|||||||
FatalLevel
|
FatalLevel
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// String is part of the flag.Value interface.
|
||||||
|
func (l *LogLevel) String() string {
|
||||||
|
switch *l {
|
||||||
|
case DebugLevel:
|
||||||
|
return "debug"
|
||||||
|
case InfoLevel:
|
||||||
|
return "info"
|
||||||
|
case WarnLevel:
|
||||||
|
return "warn"
|
||||||
|
case ErrorLevel:
|
||||||
|
return "error"
|
||||||
|
case FatalLevel:
|
||||||
|
return "fatal"
|
||||||
|
}
|
||||||
|
panic(fmt.Sprintf("asynq: unexpected log level: %v", *l))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set is part of the flag.Value interface.
|
||||||
|
func (l *LogLevel) Set(val string) error {
|
||||||
|
switch strings.ToLower(val) {
|
||||||
|
case "debug":
|
||||||
|
*l = DebugLevel
|
||||||
|
case "info":
|
||||||
|
*l = InfoLevel
|
||||||
|
case "warn", "warning":
|
||||||
|
*l = WarnLevel
|
||||||
|
case "error":
|
||||||
|
*l = ErrorLevel
|
||||||
|
case "fatal":
|
||||||
|
*l = FatalLevel
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("asynq: unsupported log level %q", val)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Formula taken from https://github.com/mperham/sidekiq.
|
// Formula taken from https://github.com/mperham/sidekiq.
|
||||||
func defaultDelayFunc(n int, e error, t *Task) time.Duration {
|
func defaultDelayFunc(n int, e error, t *Task) time.Duration {
|
||||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
|
@ -208,3 +208,32 @@ func TestServerWithFlakyBroker(t *testing.T) {
|
|||||||
|
|
||||||
srv.Stop()
|
srv.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLogLevel(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
flagVal string
|
||||||
|
want LogLevel
|
||||||
|
wantStr string
|
||||||
|
}{
|
||||||
|
{"debug", DebugLevel, "debug"},
|
||||||
|
{"Info", InfoLevel, "info"},
|
||||||
|
{"WARN", WarnLevel, "warn"},
|
||||||
|
{"warning", WarnLevel, "warn"},
|
||||||
|
{"Error", ErrorLevel, "error"},
|
||||||
|
{"fatal", FatalLevel, "fatal"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range tests {
|
||||||
|
level := new(LogLevel)
|
||||||
|
if err := level.Set(tc.flagVal); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if *level != tc.want {
|
||||||
|
t.Errorf("Set(%q): got %v, want %v", tc.flagVal, level, &tc.want)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if got := level.String(); got != tc.wantStr {
|
||||||
|
t.Errorf("String() returned %q, want %q", got, tc.wantStr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user