logger: update logger interface

Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
Василий Толстов 2021-01-10 18:56:39 +03:00
parent 270ad1b889
commit 7b3a7a9448
5 changed files with 111 additions and 84 deletions

View File

@ -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

View File

@ -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

View File

@ -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")
}

View File

@ -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
}

View File

@ -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
}
}