114
logger/helper.go
114
logger/helper.go
@@ -1,114 +0,0 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
type Helper struct {
|
||||
Logger
|
||||
fields map[string]interface{}
|
||||
}
|
||||
|
||||
func NewHelper(log Logger) *Helper {
|
||||
return &Helper{Logger: log}
|
||||
}
|
||||
|
||||
func (h *Helper) Info(args ...interface{}) {
|
||||
if !h.Logger.Options().Level.Enabled(InfoLevel) {
|
||||
return
|
||||
}
|
||||
h.Logger.Fields(h.fields).Log(InfoLevel, args...)
|
||||
}
|
||||
|
||||
func (h *Helper) Infof(template string, args ...interface{}) {
|
||||
if !h.Logger.Options().Level.Enabled(InfoLevel) {
|
||||
return
|
||||
}
|
||||
h.Logger.Fields(h.fields).Logf(InfoLevel, template, args...)
|
||||
}
|
||||
|
||||
func (h *Helper) Trace(args ...interface{}) {
|
||||
if !h.Logger.Options().Level.Enabled(TraceLevel) {
|
||||
return
|
||||
}
|
||||
h.Logger.Fields(h.fields).Log(TraceLevel, args...)
|
||||
}
|
||||
|
||||
func (h *Helper) Tracef(template string, args ...interface{}) {
|
||||
if !h.Logger.Options().Level.Enabled(TraceLevel) {
|
||||
return
|
||||
}
|
||||
h.Logger.Fields(h.fields).Logf(TraceLevel, template, args...)
|
||||
}
|
||||
|
||||
func (h *Helper) Debug(args ...interface{}) {
|
||||
if !h.Logger.Options().Level.Enabled(DebugLevel) {
|
||||
return
|
||||
}
|
||||
h.Logger.Fields(h.fields).Log(DebugLevel, args...)
|
||||
}
|
||||
|
||||
func (h *Helper) Debugf(template string, args ...interface{}) {
|
||||
if !h.Logger.Options().Level.Enabled(DebugLevel) {
|
||||
return
|
||||
}
|
||||
h.Logger.Fields(h.fields).Logf(DebugLevel, template, args...)
|
||||
}
|
||||
|
||||
func (h *Helper) Warn(args ...interface{}) {
|
||||
if !h.Logger.Options().Level.Enabled(WarnLevel) {
|
||||
return
|
||||
}
|
||||
h.Logger.Fields(h.fields).Log(WarnLevel, args...)
|
||||
}
|
||||
|
||||
func (h *Helper) Warnf(template string, args ...interface{}) {
|
||||
if !h.Logger.Options().Level.Enabled(WarnLevel) {
|
||||
return
|
||||
}
|
||||
h.Logger.Fields(h.fields).Logf(WarnLevel, template, args...)
|
||||
}
|
||||
|
||||
func (h *Helper) Error(args ...interface{}) {
|
||||
if !h.Logger.Options().Level.Enabled(ErrorLevel) {
|
||||
return
|
||||
}
|
||||
h.Logger.Fields(h.fields).Log(ErrorLevel, args...)
|
||||
}
|
||||
|
||||
func (h *Helper) Errorf(template string, args ...interface{}) {
|
||||
if !h.Logger.Options().Level.Enabled(ErrorLevel) {
|
||||
return
|
||||
}
|
||||
h.Logger.Fields(h.fields).Logf(ErrorLevel, template, args...)
|
||||
}
|
||||
|
||||
func (h *Helper) Fatal(args ...interface{}) {
|
||||
if !h.Logger.Options().Level.Enabled(FatalLevel) {
|
||||
return
|
||||
}
|
||||
h.Logger.Fields(h.fields).Log(FatalLevel, args...)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func (h *Helper) Fatalf(template string, args ...interface{}) {
|
||||
if !h.Logger.Options().Level.Enabled(FatalLevel) {
|
||||
return
|
||||
}
|
||||
h.Logger.Fields(h.fields).Logf(FatalLevel, template, args...)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func (h *Helper) WithError(err error) *Helper {
|
||||
fields := copyFields(h.fields)
|
||||
fields["error"] = err
|
||||
return &Helper{Logger: h.Logger, fields: fields}
|
||||
}
|
||||
|
||||
func (h *Helper) WithFields(fields map[string]interface{}) *Helper {
|
||||
nfields := copyFields(fields)
|
||||
for k, v := range h.fields {
|
||||
nfields[k] = v
|
||||
}
|
||||
return &Helper{Logger: h.Logger, fields: nfields}
|
||||
}
|
@@ -2,7 +2,6 @@ package logger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Level int8
|
||||
@@ -19,7 +18,7 @@ const (
|
||||
WarnLevel
|
||||
// ErrorLevel level. Logs. Used for errors that should definitely be noted.
|
||||
ErrorLevel
|
||||
// FatalLevel level. Logs and then calls `logger.Exit(1)`. highest level of severity.
|
||||
// FatalLevel level. Logs and then calls `os.Exit(1)`. highest level of severity.
|
||||
FatalLevel
|
||||
)
|
||||
|
||||
@@ -63,60 +62,5 @@ func GetLevel(levelStr string) (Level, error) {
|
||||
case FatalLevel.String():
|
||||
return FatalLevel, nil
|
||||
}
|
||||
return InfoLevel, fmt.Errorf("Unknown Level String: '%s', defaulting to InfoLevel", levelStr)
|
||||
}
|
||||
|
||||
func Info(args ...interface{}) {
|
||||
DefaultLogger.Log(InfoLevel, args...)
|
||||
}
|
||||
|
||||
func Infof(template string, args ...interface{}) {
|
||||
DefaultLogger.Logf(InfoLevel, template, args...)
|
||||
}
|
||||
|
||||
func Trace(args ...interface{}) {
|
||||
DefaultLogger.Log(TraceLevel, args...)
|
||||
}
|
||||
|
||||
func Tracef(template string, args ...interface{}) {
|
||||
DefaultLogger.Logf(TraceLevel, template, args...)
|
||||
}
|
||||
|
||||
func Debug(args ...interface{}) {
|
||||
DefaultLogger.Log(DebugLevel, args...)
|
||||
}
|
||||
|
||||
func Debugf(template string, args ...interface{}) {
|
||||
DefaultLogger.Logf(DebugLevel, template, args...)
|
||||
}
|
||||
|
||||
func Warn(args ...interface{}) {
|
||||
DefaultLogger.Log(WarnLevel, args...)
|
||||
}
|
||||
|
||||
func Warnf(template string, args ...interface{}) {
|
||||
DefaultLogger.Logf(WarnLevel, template, args...)
|
||||
}
|
||||
|
||||
func Error(args ...interface{}) {
|
||||
DefaultLogger.Log(ErrorLevel, args...)
|
||||
}
|
||||
|
||||
func Errorf(template string, args ...interface{}) {
|
||||
DefaultLogger.Logf(ErrorLevel, template, args...)
|
||||
}
|
||||
|
||||
func Fatal(args ...interface{}) {
|
||||
DefaultLogger.Log(FatalLevel, args...)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func Fatalf(template string, args ...interface{}) {
|
||||
DefaultLogger.Logf(FatalLevel, template, args...)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Returns true if the given level is at or lower the current logger level
|
||||
func V(lvl Level) bool {
|
||||
return DefaultLogger.Options().Level <= lvl
|
||||
return InfoLevel, fmt.Errorf("unknown Level String: '%s', use InfoLevel", levelStr)
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@ package logger
|
||||
|
||||
var (
|
||||
// DefaultLogger variable
|
||||
DefaultLogger Logger = NewHelper(NewLogger())
|
||||
DefaultLogger Logger = NewLogger()
|
||||
)
|
||||
|
||||
// Logger is a generic logging interface
|
||||
@@ -16,14 +16,50 @@ type Logger interface {
|
||||
Options() Options
|
||||
// Fields set fields to always be logged
|
||||
Fields(fields map[string]interface{}) Logger
|
||||
// Log writes a log entry
|
||||
Log(level Level, v ...interface{})
|
||||
// Logf writes a formatted log entry
|
||||
Logf(level Level, format string, v ...interface{})
|
||||
// Info level message
|
||||
Info(msg string, args ...interface{})
|
||||
// Trace level message
|
||||
Trace(msg string, args ...interface{})
|
||||
// Debug level message
|
||||
Debug(msg string, args ...interface{})
|
||||
// Warn level message
|
||||
Warn(msg string, args ...interface{})
|
||||
// Error level message
|
||||
Error(msg string, args ...interface{})
|
||||
// Fatal level message
|
||||
Fatal(msg string, args ...interface{})
|
||||
// String returns the name of logger
|
||||
String() string
|
||||
}
|
||||
|
||||
func Info(msg string, args ...interface{}) {
|
||||
DefaultLogger.Info(msg, args...)
|
||||
}
|
||||
|
||||
func Error(msg string, args ...interface{}) {
|
||||
DefaultLogger.Error(msg, args...)
|
||||
}
|
||||
|
||||
func Debug(msg string, args ...interface{}) {
|
||||
DefaultLogger.Debug(msg, args...)
|
||||
}
|
||||
|
||||
func Warn(msg string, args ...interface{}) {
|
||||
DefaultLogger.Warn(msg, args...)
|
||||
}
|
||||
|
||||
func Trace(msg string, args ...interface{}) {
|
||||
DefaultLogger.Trace(msg, args...)
|
||||
}
|
||||
|
||||
func Fatal(msg string, args ...interface{}) {
|
||||
DefaultLogger.Fatal(msg, args...)
|
||||
}
|
||||
|
||||
func V(level Level) bool {
|
||||
return DefaultLogger.V(level)
|
||||
}
|
||||
|
||||
// Init initialize logger
|
||||
func Init(opts ...Option) error {
|
||||
return DefaultLogger.Init(opts...)
|
||||
@@ -33,18 +69,3 @@ func Init(opts ...Option) error {
|
||||
func Fields(fields map[string]interface{}) Logger {
|
||||
return DefaultLogger.Fields(fields)
|
||||
}
|
||||
|
||||
// Log writes log with specific level
|
||||
func Log(level Level, v ...interface{}) {
|
||||
DefaultLogger.Log(level, v...)
|
||||
}
|
||||
|
||||
// Logf writes formatted log with specific level
|
||||
func Logf(level Level, format string, v ...interface{}) {
|
||||
DefaultLogger.Logf(level, format, v...)
|
||||
}
|
||||
|
||||
// String return logger name
|
||||
func String() string {
|
||||
return DefaultLogger.String()
|
||||
}
|
||||
|
@@ -6,13 +6,10 @@ import (
|
||||
|
||||
func TestLogger(t *testing.T) {
|
||||
l := NewLogger(WithLevel(TraceLevel))
|
||||
h1 := NewHelper(l).WithFields(map[string]interface{}{"key1": "val1"})
|
||||
h1.Trace("trace_msg1")
|
||||
h1.Warn("warn_msg1")
|
||||
|
||||
h2 := NewHelper(l).WithFields(map[string]interface{}{"key2": "val2"})
|
||||
h2.Trace("trace_msg2")
|
||||
h2.Warn("warn_msg2")
|
||||
|
||||
l.Fields(map[string]interface{}{"key3": "val4"}).Log(InfoLevel, "test_msg")
|
||||
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")
|
||||
}
|
||||
|
@@ -1,16 +1,13 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
dlog "github.com/unistack-org/micro/v3/debug/log"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -19,31 +16,33 @@ func init() {
|
||||
lvl = InfoLevel
|
||||
}
|
||||
|
||||
DefaultLogger = NewHelper(NewLogger(WithLevel(lvl)))
|
||||
DefaultLogger = NewLogger(WithLevel(lvl))
|
||||
}
|
||||
|
||||
type defaultLogger struct {
|
||||
sync.RWMutex
|
||||
opts Options
|
||||
enc *json.Encoder
|
||||
}
|
||||
|
||||
// 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)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *defaultLogger) String() string {
|
||||
return "default"
|
||||
return "micro"
|
||||
}
|
||||
|
||||
func (l *defaultLogger) V(level Level) bool {
|
||||
if l.opts.Level.Enabled(level) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return l.opts.Level.Enabled(level)
|
||||
}
|
||||
|
||||
func (l *defaultLogger) Fields(fields map[string]interface{}) Logger {
|
||||
@@ -85,45 +84,32 @@ func logCallerfilePath(loggingFilePath string) string {
|
||||
return loggingFilePath[idx+1:]
|
||||
}
|
||||
|
||||
func (l *defaultLogger) Log(level Level, v ...interface{}) {
|
||||
if !l.V(level) {
|
||||
return
|
||||
}
|
||||
|
||||
l.RLock()
|
||||
fields := copyFields(l.opts.Fields)
|
||||
l.RUnlock()
|
||||
|
||||
fields["level"] = level.String()
|
||||
|
||||
if _, file, line, ok := runtime.Caller(l.opts.CallerSkipCount); ok {
|
||||
fields["file"] = fmt.Sprintf("%s:%d", logCallerfilePath(file), line)
|
||||
}
|
||||
|
||||
rec := dlog.Record{
|
||||
Timestamp: time.Now(),
|
||||
Message: fmt.Sprint(v...),
|
||||
Metadata: make(map[string]string, len(fields)),
|
||||
}
|
||||
|
||||
keys := make([]string, 0, len(fields))
|
||||
for k, v := range fields {
|
||||
keys = append(keys, k)
|
||||
rec.Metadata[k] = fmt.Sprintf("%v", v)
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
metadata := ""
|
||||
|
||||
for _, k := range keys {
|
||||
metadata += fmt.Sprintf(" %s=%v", k, fields[k])
|
||||
}
|
||||
|
||||
t := rec.Timestamp.Format("2006-01-02 15:04:05")
|
||||
fmt.Printf("%s %s %v\n", t, metadata, rec.Message)
|
||||
func (l *defaultLogger) Info(msg string, args ...interface{}) {
|
||||
l.log(InfoLevel, msg, args...)
|
||||
}
|
||||
|
||||
func (l *defaultLogger) Logf(level Level, format string, v ...interface{}) {
|
||||
func (l *defaultLogger) Error(msg string, args ...interface{}) {
|
||||
l.log(ErrorLevel, msg, args...)
|
||||
}
|
||||
|
||||
func (l *defaultLogger) Debug(msg string, args ...interface{}) {
|
||||
l.log(DebugLevel, msg, args...)
|
||||
}
|
||||
|
||||
func (l *defaultLogger) Warn(msg string, args ...interface{}) {
|
||||
l.log(WarnLevel, msg, args...)
|
||||
}
|
||||
|
||||
func (l *defaultLogger) Trace(msg string, args ...interface{}) {
|
||||
l.log(TraceLevel, msg, args...)
|
||||
}
|
||||
|
||||
func (l *defaultLogger) Fatal(msg string, args ...interface{}) {
|
||||
l.log(FatalLevel, msg, args...)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func (l *defaultLogger) log(level Level, msg string, args ...interface{}) {
|
||||
if !l.V(level) {
|
||||
return
|
||||
}
|
||||
@@ -135,30 +121,20 @@ func (l *defaultLogger) Logf(level Level, format string, v ...interface{}) {
|
||||
fields["level"] = level.String()
|
||||
|
||||
if _, file, line, ok := runtime.Caller(l.opts.CallerSkipCount); ok {
|
||||
fields["file"] = fmt.Sprintf("%s:%d", logCallerfilePath(file), line)
|
||||
fields["caller"] = fmt.Sprintf("%s:%d", logCallerfilePath(file), line)
|
||||
}
|
||||
|
||||
rec := dlog.Record{
|
||||
Timestamp: time.Now(),
|
||||
Message: fmt.Sprintf(format, v...),
|
||||
Metadata: make(map[string]string, len(fields)),
|
||||
fields["timestamp"] = time.Now().Format("2006-01-02 15:04:05")
|
||||
if len(msg) > 0 {
|
||||
if len(args) > 0 {
|
||||
fields["msg"] = fmt.Sprintf(msg, args...)
|
||||
} else {
|
||||
fields["msg"] = msg
|
||||
}
|
||||
}
|
||||
|
||||
keys := make([]string, 0, len(fields))
|
||||
for k, v := range fields {
|
||||
keys = append(keys, k)
|
||||
rec.Metadata[k] = fmt.Sprintf("%v", v)
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
metadata := ""
|
||||
|
||||
for _, k := range keys {
|
||||
metadata += fmt.Sprintf(" %s=%v", k, fields[k])
|
||||
}
|
||||
|
||||
t := rec.Timestamp.Format("2006-01-02 15:04:05")
|
||||
fmt.Printf("%s %s %v\n", t, metadata, rec.Message)
|
||||
l.RLock()
|
||||
_ = l.enc.Encode(fields)
|
||||
l.RUnlock()
|
||||
}
|
||||
|
||||
func (l *defaultLogger) Options() Options {
|
||||
@@ -172,19 +148,7 @@ func (l *defaultLogger) Options() Options {
|
||||
|
||||
// NewLogger builds a new logger based on options
|
||||
func NewLogger(opts ...Option) Logger {
|
||||
// Default options
|
||||
options := Options{
|
||||
Level: InfoLevel,
|
||||
Fields: make(map[string]interface{}),
|
||||
Out: os.Stderr,
|
||||
CallerSkipCount: 2,
|
||||
Context: context.Background(),
|
||||
}
|
||||
|
||||
l := &defaultLogger{opts: options}
|
||||
if err := l.Init(opts...); err != nil {
|
||||
l.Log(FatalLevel, err)
|
||||
}
|
||||
|
||||
l := &defaultLogger{opts: NewOptions(opts...)}
|
||||
l.enc = json.NewEncoder(l.opts.Out)
|
||||
return l
|
||||
}
|
@@ -3,6 +3,7 @@ package logger
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Option func(*Options)
|
||||
@@ -21,7 +22,13 @@ type Options struct {
|
||||
}
|
||||
|
||||
func NewOptions(opts ...Option) Options {
|
||||
options := Options{}
|
||||
options := Options{
|
||||
Level: InfoLevel,
|
||||
Fields: make(map[string]interface{}),
|
||||
Out: os.Stderr,
|
||||
CallerSkipCount: 2,
|
||||
Context: context.Background(),
|
||||
}
|
||||
for _, o := range opts {
|
||||
o(&options)
|
||||
}
|
||||
|
Reference in New Issue
Block a user