diff --git a/logger/level.go b/logger/level.go index 37bb9c0a..95123f46 100644 --- a/logger/level.go +++ b/logger/level.go @@ -12,12 +12,11 @@ const ( TraceLevel Level = iota - 2 // DebugLevel level. Usually only enabled when debugging. Very verbose logging. DebugLevel - // InfoLevel is the default logging priority. - // General operational entries about what's going on inside the application. + // InfoLevel level. General operational entries about what's going on inside the application. InfoLevel // WarnLevel level. Non-critical entries that deserve eyes. WarnLevel - // ErrorLevel level. Logs. Used for errors that should definitely be noted. + // ErrorLevel level. Used for errors that should definitely be noted. ErrorLevel // FatalLevel level. Logs and then calls `os.Exit(1)`. highest level of severity. FatalLevel diff --git a/logger/logger.go b/logger/logger.go index 6dcf8ef5..607eea87 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -1,9 +1,13 @@ // Package logger provides a log interface package logger +import "context" + var ( // DefaultLogger variable DefaultLogger Logger = NewLogger() + // DefaultLogger level + DefaultLevel Level = InfoLevel ) // Logger is a generic logging interface @@ -14,94 +18,100 @@ type Logger interface { V(level Level) bool // The Logger options Options() Options + // SetLevel modify current log level + SetLevel(level Level) // Fields set fields to always be logged Fields(fields map[string]interface{}) Logger // Info level message - Info(args ...interface{}) + Info(ctx context.Context, args ...interface{}) // Trace level message - Trace(args ...interface{}) + Trace(ctx context.Context, args ...interface{}) // Debug level message - Debug(args ...interface{}) + Debug(ctx context.Context, args ...interface{}) // Warn level message - Warn(args ...interface{}) + Warn(ctx context.Context, args ...interface{}) // Error level message - Error(args ...interface{}) + Error(ctx context.Context, args ...interface{}) // Fatal level message - Fatal(args ...interface{}) + Fatal(ctx context.Context, args ...interface{}) // Infof level message - Infof(msg string, args ...interface{}) + Infof(ctx context.Context, msg string, args ...interface{}) // Tracef level message - Tracef(msg string, args ...interface{}) + Tracef(ctx context.Context, msg string, args ...interface{}) // Debug level message - Debugf(msg string, args ...interface{}) + Debugf(ctx context.Context, msg string, args ...interface{}) // Warn level message - Warnf(msg string, args ...interface{}) + Warnf(ctx context.Context, msg string, args ...interface{}) // Error level message - Errorf(msg string, args ...interface{}) + Errorf(ctx context.Context, msg string, args ...interface{}) // Fatal level message - Fatalf(msg string, args ...interface{}) + Fatalf(ctx context.Context, msg string, args ...interface{}) + // Log logs message with needed level + Log(ctx context.Context, level Level, args ...interface{}) + // Logf logs message with needed level + Logf(ctx context.Context, level Level, msg string, args ...interface{}) // String returns the name of logger String() string } // Info writes msg to default logger on info level -func Info(args ...interface{}) { - DefaultLogger.Info(args...) +func Info(ctx context.Context, args ...interface{}) { + DefaultLogger.Info(ctx, args...) } // Error writes msg to default logger on error level -func Error(args ...interface{}) { - DefaultLogger.Error(args...) +func Error(ctx context.Context, args ...interface{}) { + DefaultLogger.Error(ctx, args...) } // Debug writes msg to default logger on debug level -func Debug(args ...interface{}) { - DefaultLogger.Debug(args...) +func Debug(ctx context.Context, args ...interface{}) { + DefaultLogger.Debug(ctx, args...) } // Warn writes msg to default logger on warn level -func Warn(args ...interface{}) { - DefaultLogger.Warn(args...) +func Warn(ctx context.Context, args ...interface{}) { + DefaultLogger.Warn(ctx, args...) } // Trace writes msg to default logger on trace level -func Trace(args ...interface{}) { - DefaultLogger.Trace(args...) +func Trace(ctx context.Context, args ...interface{}) { + DefaultLogger.Trace(ctx, args...) } // Fatal writes msg to default logger on fatal level -func Fatal(args ...interface{}) { - DefaultLogger.Fatal(args...) +func Fatal(ctx context.Context, args ...interface{}) { + DefaultLogger.Fatal(ctx, args...) } // Infof writes formatted msg to default logger on info level -func Infof(msg string, args ...interface{}) { - DefaultLogger.Infof(msg, args...) +func Infof(ctx context.Context, msg string, args ...interface{}) { + DefaultLogger.Infof(ctx, msg, args...) } // Errorf writes formatted msg to default logger on error level -func Errorf(msg string, args ...interface{}) { - DefaultLogger.Errorf(msg, args...) +func Errorf(ctx context.Context, msg string, args ...interface{}) { + DefaultLogger.Errorf(ctx, msg, args...) } // Debugf writes formatted msg to default logger on debug level -func Debugf(msg string, args ...interface{}) { - DefaultLogger.Debugf(msg, args...) +func Debugf(ctx context.Context, msg string, args ...interface{}) { + DefaultLogger.Debugf(ctx, msg, args...) } // Warnf writes formatted msg to default logger on warn level -func Warnf(msg string, args ...interface{}) { - DefaultLogger.Warnf(msg, args...) +func Warnf(ctx context.Context, msg string, args ...interface{}) { + DefaultLogger.Warnf(ctx, msg, args...) } // Tracef writes formatted msg to default logger on trace level -func Tracef(msg string, args ...interface{}) { - DefaultLogger.Tracef(msg, args...) +func Tracef(ctx context.Context, msg string, args ...interface{}) { + DefaultLogger.Tracef(ctx, msg, args...) } // Fatalf writes formatted msg to default logger on fatal level -func Fatalf(msg string, args ...interface{}) { - DefaultLogger.Fatalf(msg, args...) +func Fatalf(ctx context.Context, msg string, args ...interface{}) { + DefaultLogger.Fatalf(ctx, msg, args...) } // V returns true if passed level enabled in default logger diff --git a/logger/logger_test.go b/logger/logger_test.go index 02982f19..a6a1f376 100644 --- a/logger/logger_test.go +++ b/logger/logger_test.go @@ -1,16 +1,18 @@ package logger import ( + "context" "testing" ) func TestLogger(t *testing.T) { + ctx := context.TODO() l := NewLogger(WithLevel(TraceLevel)) if err := l.Init(); err != nil { t.Fatal(err) } - l.Trace("trace_msg1") - l.Warn("warn_msg1") - l.Fields(map[string]interface{}{"error": "test"}).Info("error message") - l.Warn("first", " ", "second") + l.Trace(ctx, "trace_msg1") + l.Warn(ctx, "warn_msg1") + l.Fields(map[string]interface{}{"error": "test"}).Info(ctx, "error message") + l.Warn(ctx, "first", " ", "second") } diff --git a/logger/micro.go b/logger/micro.go index 62c21161..6561dcea 100644 --- a/logger/micro.go +++ b/logger/micro.go @@ -1,6 +1,7 @@ package logger import ( + "context" "encoding/json" "fmt" "os" @@ -28,12 +29,11 @@ type defaultLogger struct { // Init(opts...) should only overwrite provided options func (l *defaultLogger) Init(opts ...Option) error { l.Lock() - defer l.Unlock() - for _, o := range opts { o(&l.opts) } l.enc = json.NewEncoder(l.opts.Out) + l.Unlock() return nil } @@ -41,8 +41,24 @@ func (l *defaultLogger) String() string { return "micro" } +func (l *defaultLogger) SetLevel(level Level) { + l.Lock() + l.opts.Level = level + l.Unlock() +} + +func (l *defaultLogger) GetLevel() Level { + l.RLock() + lvl := l.opts.Level + l.RUnlock() + return lvl +} + func (l *defaultLogger) V(level Level) bool { - return l.opts.Level.Enabled(level) + l.RLock() + ok := l.opts.Level.Enabled(level) + l.RUnlock() + return ok } func (l *defaultLogger) Fields(fields map[string]interface{}) Logger { @@ -84,57 +100,57 @@ func logCallerfilePath(loggingFilePath string) string { return loggingFilePath[idx+1:] } -func (l *defaultLogger) Info(args ...interface{}) { - l.log(InfoLevel, args...) +func (l *defaultLogger) Info(ctx context.Context, args ...interface{}) { + l.Log(ctx, InfoLevel, args...) } -func (l *defaultLogger) Error(args ...interface{}) { - l.log(ErrorLevel, args...) +func (l *defaultLogger) Error(ctx context.Context, args ...interface{}) { + l.Log(ctx, ErrorLevel, args...) } -func (l *defaultLogger) Debug(args ...interface{}) { - l.log(DebugLevel, args...) +func (l *defaultLogger) Debug(ctx context.Context, args ...interface{}) { + l.Log(ctx, DebugLevel, args...) } -func (l *defaultLogger) Warn(args ...interface{}) { - l.log(WarnLevel, args...) +func (l *defaultLogger) Warn(ctx context.Context, args ...interface{}) { + l.Log(ctx, WarnLevel, args...) } -func (l *defaultLogger) Trace(args ...interface{}) { - l.log(TraceLevel, args...) +func (l *defaultLogger) Trace(ctx context.Context, args ...interface{}) { + l.Log(ctx, TraceLevel, args...) } -func (l *defaultLogger) Fatal(args ...interface{}) { - l.log(FatalLevel, args...) +func (l *defaultLogger) Fatal(ctx context.Context, args ...interface{}) { + l.Log(ctx, FatalLevel, args...) os.Exit(1) } -func (l *defaultLogger) Infof(msg string, args ...interface{}) { - l.logf(InfoLevel, msg, args...) +func (l *defaultLogger) Infof(ctx context.Context, msg string, args ...interface{}) { + l.Logf(ctx, InfoLevel, msg, args...) } -func (l *defaultLogger) Errorf(msg string, args ...interface{}) { - l.logf(ErrorLevel, msg, args...) +func (l *defaultLogger) Errorf(ctx context.Context, msg string, args ...interface{}) { + l.Logf(ctx, ErrorLevel, msg, args...) } -func (l *defaultLogger) Debugf(msg string, args ...interface{}) { - l.logf(DebugLevel, msg, args...) +func (l *defaultLogger) Debugf(ctx context.Context, msg string, args ...interface{}) { + l.Logf(ctx, DebugLevel, msg, args...) } -func (l *defaultLogger) Warnf(msg string, args ...interface{}) { - l.logf(WarnLevel, msg, args...) +func (l *defaultLogger) Warnf(ctx context.Context, msg string, args ...interface{}) { + l.Logf(ctx, WarnLevel, msg, args...) } -func (l *defaultLogger) Tracef(msg string, args ...interface{}) { - l.logf(TraceLevel, msg, args...) +func (l *defaultLogger) Tracef(ctx context.Context, msg string, args ...interface{}) { + l.Logf(ctx, TraceLevel, msg, args...) } -func (l *defaultLogger) Fatalf(msg string, args ...interface{}) { - l.logf(FatalLevel, msg, args...) +func (l *defaultLogger) Fatalf(ctx context.Context, msg string, args ...interface{}) { + l.Logf(ctx, FatalLevel, msg, args...) os.Exit(1) } -func (l *defaultLogger) log(level Level, args ...interface{}) { +func (l *defaultLogger) Log(ctx context.Context, level Level, args ...interface{}) { if !l.V(level) { return } @@ -157,7 +173,7 @@ func (l *defaultLogger) log(level Level, args ...interface{}) { l.RUnlock() } -func (l *defaultLogger) logf(level Level, msg string, args ...interface{}) { +func (l *defaultLogger) Logf(ctx context.Context, level Level, msg string, args ...interface{}) { if !l.V(level) { return } diff --git a/logger/options.go b/logger/options.go index 73d43554..d3b36e93 100644 --- a/logger/options.go +++ b/logger/options.go @@ -26,10 +26,10 @@ type Options struct { // NewOptions creates new options struct func NewOptions(opts ...Option) Options { options := Options{ - Level: InfoLevel, + Level: DefaultLevel, Fields: make(map[string]interface{}), Out: os.Stderr, - CallerSkipCount: 2, + CallerSkipCount: 0, Context: context.Background(), } for _, o := range opts { @@ -40,35 +40,35 @@ func NewOptions(opts ...Option) Options { // WithFields set default fields for the logger func WithFields(fields map[string]interface{}) Option { - return func(args *Options) { - args.Fields = fields + return func(o *Options) { + o.Fields = fields } } // WithLevel set default level for the logger func WithLevel(level Level) Option { - return func(args *Options) { - args.Level = level + return func(o *Options) { + o.Level = level } } // WithOutput set default output writer for the logger func WithOutput(out io.Writer) Option { - return func(args *Options) { - args.Out = out + return func(o *Options) { + o.Out = out } } // WithCallerSkipCount set frame count to skip func WithCallerSkipCount(c int) Option { - return func(args *Options) { - args.CallerSkipCount = c + return func(o *Options) { + o.CallerSkipCount = c } } // WithContext set context func WithContext(ctx context.Context) Option { - return func(args *Options) { - args.Context = ctx + return func(o *Options) { + o.Context = ctx } }