Skip to content

Commit

Permalink
增加MutableLogger
Browse files Browse the repository at this point in the history
  • Loading branch information
xfali committed Sep 8, 2020
1 parent 4574b96 commit 5fbbd37
Show file tree
Hide file tree
Showing 6 changed files with 374 additions and 0 deletions.
141 changes: 141 additions & 0 deletions default.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

package xlog

import "sync/atomic"

type xlog struct {
logging Logging
depth int
Expand Down Expand Up @@ -148,3 +150,142 @@ func (l *xlog) WithDepth(depth int) Logger {

return ret
}

type mutableLog struct {
logging *atomic.Value
depth int
fields KeyValues
name string
}

func newMutableLogger(logging *atomic.Value, fields KeyValues, name ...string) *mutableLog {
if fields == nil {
fields = NewKeyValues()
}
var t string
if len(name) > 0 {
t = name[0]
if t != "" {
fields.Add(KeyName, t)
}
}
ret := &mutableLog{
logging: logging,
depth: 1,
name: t,
fields: fields,
}
return ret
}

func (l *mutableLog) getLogging() Logging {
return l.logging.Load().(Logging)
}

func (l *mutableLog) Debug(args ...interface{}) {
l.getLogging().Log(DEBUG, l.depth, l.fields, args...)
}

func (l *mutableLog) Debugln(args ...interface{}) {
l.getLogging().Logln(DEBUG, l.depth, l.fields, args...)
}

func (l *mutableLog) Debugf(fmt string, args ...interface{}) {
l.getLogging().Logf(DEBUG, l.depth, l.fields, fmt, args...)
}

func (l *mutableLog) Info(args ...interface{}) {
l.getLogging().Log(INFO, l.depth, l.fields, args...)
}

func (l *mutableLog) Infoln(args ...interface{}) {
l.getLogging().Logln(INFO, l.depth, l.fields, args...)
}

func (l *mutableLog) Infof(fmt string, args ...interface{}) {
l.getLogging().Logf(INFO, l.depth, l.fields, fmt, args...)
}

func (l *mutableLog) Warn(args ...interface{}) {
l.getLogging().Log(WARN, l.depth, l.fields, args...)
}

func (l *mutableLog) Warnln(args ...interface{}) {
l.getLogging().Logln(WARN, l.depth, l.fields, args...)
}

func (l *mutableLog) Warnf(fmt string, args ...interface{}) {
l.getLogging().Logf(WARN, l.depth, l.fields, fmt, args...)
}

func (l *mutableLog) Error(args ...interface{}) {
l.getLogging().Log(ERROR, l.depth, l.fields, args...)
}

func (l *mutableLog) Errorln(args ...interface{}) {
l.getLogging().Logln(ERROR, l.depth, l.fields, args...)
}

func (l *mutableLog) Errorf(fmt string, args ...interface{}) {
l.getLogging().Logf(ERROR, l.depth, l.fields, fmt, args...)
}

func (l *mutableLog) Panic(args ...interface{}) {
l.getLogging().Log(PANIC, l.depth, l.fields, args...)
}

func (l *mutableLog) Panicln(args ...interface{}) {
l.getLogging().Logln(PANIC, l.depth, l.fields, args...)
}

func (l *mutableLog) Panicf(fmt string, args ...interface{}) {
l.getLogging().Logf(PANIC, l.depth, l.fields, fmt, args...)
}

func (l *mutableLog) Fatal(args ...interface{}) {
l.getLogging().Log(FATAL, l.depth, l.fields, args...)
}

func (l *mutableLog) Fatalln(args ...interface{}) {
l.getLogging().Logln(FATAL, l.depth, l.fields, args...)
}

func (l *mutableLog) Fatalf(fmt string, args ...interface{}) {
l.getLogging().Logf(FATAL, l.depth, l.fields, fmt, args...)
}

func (l *mutableLog) WithName(name string) Logger {
if l == nil {
return nil
}

if l.name != "" {
name = l.name + "." + name
}
ret := newMutableLogger(l.logging, l.fields.Clone(), name)
ret.fields.Add(KeyName, ret.name)
ret.depth = l.depth

return ret
}

func (l *mutableLog) WithFields(keyAndValues ...interface{}) Logger {
if l == nil {
return nil
}
ret := newMutableLogger(l.logging, l.fields.Clone(), l.name)
ret.fields.Add(keyAndValues...)
ret.depth = l.depth

return ret
}

func (l *mutableLog) WithDepth(depth int) Logger {
if l == nil {
return nil
}
ret := newMutableLogger(l.logging, l.fields.Clone(), l.name)
ret.depth += depth

return ret
}
41 changes: 41 additions & 0 deletions loggerfactory.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,44 @@ func SimplifyNameFirstLetter(s string) string {
}
return s[:1]
}

type mutableLoggerFactory struct {
loggerFactory
}

func NewMutableFactory(logging Logging) *mutableLoggerFactory {
ret := &mutableLoggerFactory{}
ret.value.Store(logging)
return ret
}

func (fac *mutableLoggerFactory) GetLogger(o ...interface{}) Logger {
if len(o) == 0 {
return newMutableLogger(&fac.value, nil)
} else {
if o[0] == nil {
return newMutableLogger(&fac.value, nil)
}
t := reflect.TypeOf(o[0])
if t.Kind() == reflect.String {
return newMutableLogger(&fac.value, nil, o[0].(string))
}

name := t.PkgPath()
if name != "" {
if fac.SimplifyNameFunc != nil {
names := strings.Split(name, "/")
builder := strings.Builder{}
for _, v := range names {
builder.WriteString(fac.SimplifyNameFunc(v))
builder.WriteByte('.')
}
builder.WriteString(t.Name())
name = builder.String()
} else {
name = strings.Replace(name, "/", ".", -1) + "." + t.Name()
}
}
return newMutableLogger(&fac.value, nil, name)
}
}
66 changes: 66 additions & 0 deletions test/bench/logger_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (C) 2019-2020, Xiongfa Li.
// @author xiongfa.li
// @version V1.0
// Description:

package bench

import (
"crypto/rand"
"encoding/base64"
"github.com/xfali/xlog"
"sync"
"sync/atomic"
"testing"
)

func BenchmarkLogger(b *testing.B) {
data := make([]string, 3)
d := [64]byte{}
for i := 0; i < 3; i++ {
rand.Read(d[:])
data[i] = base64.StdEncoding.EncodeToString(d[:])
}
var count int32 = 0
wait := sync.WaitGroup{}
wait.Add(20)
logger := xlog.GetLogger()
for i := 0; i < 20; i++ {
go func() {
defer wait.Done()
for i := 0; i < b.N; i++ {
atomic.AddInt32(&count, 1)
logger.Infoln(count, "========", string(data[0]), string(data[1]), string(data[2]))
}
}()
}

wait.Wait()
b.Log(count)
}

func BenchmarkMutableLogger(b *testing.B) {
data := make([]string, 3)
d := [64]byte{}
for i := 0; i < 3; i++ {
rand.Read(d[:])
data[i] = base64.StdEncoding.EncodeToString(d[:])
}
var count int32 = 0
wait := sync.WaitGroup{}
wait.Add(20)
xlog.ResetFactory(xlog.NewMutableFactory(xlog.DefaultLogging()))
logger := xlog.GetLogger()
for i := 0; i < 20; i++ {
go func() {
defer wait.Done()
for i := 0; i < b.N; i++ {
atomic.AddInt32(&count, 1)
logger.Infoln(count, "========", string(data[0]), string(data[1]), string(data[2]))
}
}()
}

wait.Wait()
b.Log(count)
}
23 changes: 23 additions & 0 deletions test/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,26 @@ func TestFactorySimplifyName(t *testing.T) {
logger = xlog.GetLogger(1)
logger.Warnln("int")
}

func TestMutableFactoryTag(t *testing.T) {
xlog.ResetFactory(xlog.NewMutableFactory(xlog.DefaultLogging()))
logger := xlog.GetLogger()
logger.Warnln("test")
logger = xlog.GetLogger(nil)
logger.Warnln("test")
logger = logger.WithName("test2")
logger.Warnln("test2")
logger = logger.WithName("test3")
logger.Warnln("test3")
logger = logger.WithFields("FieldKey", "FieldValue")
logger.Warnln("test4")
logger = logger.WithFields("FieldKey", "FieldValue2")
logger.Warnln("test5")

type TestStructInTest struct{}
logger = xlog.GetLogger(TestStructInTest{})
logger.Warnln("A")

logger = xlog.GetLogger(1)
logger.Warnln("int")
}
69 changes: 69 additions & 0 deletions test/logger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,17 @@ import (
)

func TestLoggerln(t *testing.T) {
t.Run("reset logging", func(t *testing.T) {
log := xlog.GetLogger()

log.Infoln("test")

logging := xlog.NewLogging()
logging.SetSeverityLevel(xlog.WARN)
xlog.ResetFactoryLogging(logging)
log.Infoln("test2")
})

t.Run("default", func(t *testing.T) {
// reset default init at first
// no fatal trace, do not exit
Expand Down Expand Up @@ -136,3 +147,61 @@ func TestLogger(t *testing.T) {
log.Fatal("this ia a Fatal test")
})
}

func TestMutableLoggerln(t *testing.T) {
t.Run("reset logging", func(t *testing.T) {
xlog.ResetFactory(xlog.NewMutableFactory(
xlog.NewLogging(xlog.SetFatalNoTrace(true), xlog.SetExitFunc(func(i int) {
t.Log("exit: ", i)
}))))
log := xlog.GetLogger()

log.Infoln("test")

logging := xlog.NewLogging()
logging.SetSeverityLevel(xlog.WARN)
xlog.ResetFactoryLogging(logging)
log.Infoln("test2")
})

t.Run("default", func(t *testing.T) {
// reset default init at first
// no fatal trace, do not exit
xlog.ResetFactory(xlog.NewMutableFactory(
xlog.NewLogging(xlog.SetFatalNoTrace(true), xlog.SetExitFunc(func(i int) {
t.Log("exit: ", i)
}))))
log := xlog.GetLogger()
defer func() {
v := recover()
if kvs, ok := v.(xlog.KeyValues); ok {
t.Log("recover panic !", kvs.GetAll())
}
log.Fatalln("this ia a Fatalln test")
}()
log.Debugln("this is a Debugln test")
log.Infoln("this is a Infoln test")
log.Warnln("this ia a Warnln test")
log.Errorln("this ia a Errorln test")
log.Panicln("this ia a Panicln test")
})

t.Run("exit and panic", func(t *testing.T) {
// reset default init at first
// no fatal trace, do not exit
xlog.Init(xlog.NewLogging(xlog.SetFatalNoTrace(true), xlog.SetExitFunc(func(i int) {
t.Log("exit: ", i)
}), xlog.SetPanicFunc(func(v interface{}) {
if kvs, ok := v.(xlog.KeyValues); ok {
t.Log("panic !", kvs.GetAll())
}
})))
log := xlog.GetLogger()
log.Debugln("this is a Debugln test")
log.Infoln("this is a Infoln test")
log.Warnln("this ia a Warnln test")
log.Errorln("this ia a Errorln test")
log.Panicln("this ia a Panicln test")
log.Fatalln("this ia a Fatalln test")
})
}
Loading

0 comments on commit 5fbbd37

Please sign in to comment.