From b46c3fa06d2369dd38eccff4a20a007966e28f20 Mon Sep 17 00:00:00 2001 From: q191201771 <191201771@qq.com> Date: Thu, 2 Apr 2020 11:46:32 +0800 Subject: [PATCH] =?UTF-8?q?[feat]=20package=20nazalog:=20=E5=88=A0?= =?UTF-8?q?=E6=8E=89AssertPanic=E5=92=8CAssertFatal=E5=87=BD=E6=95=B0?= =?UTF-8?q?=EF=BC=8C=E6=8A=8A=E5=8A=9F=E8=83=BD=E5=BD=92=E6=8B=A2=E5=88=B0?= =?UTF-8?q?Assert=E5=87=BD=E6=95=B0=E4=B8=AD=EF=BC=8CAssert=E6=96=AD?= =?UTF-8?q?=E8=A8=80=E5=A4=B1=E8=B4=A5=E5=90=8E=E7=9A=84=E8=A1=8C=E4=B8=BA?= =?UTF-8?q?=E7=94=B1=E9=85=8D=E7=BD=AE=E9=A1=B9=E6=8E=A7=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/nazalog/global.go | 31 +++----- pkg/nazalog/interface.go | 45 ++++++++--- pkg/nazalog/log.go | 29 +++---- pkg/nazalog/log_test.go | 168 ++++++++++++++++++++++----------------- 4 files changed, 154 insertions(+), 119 deletions(-) diff --git a/pkg/nazalog/global.go b/pkg/nazalog/global.go index f84a8ba..8bb3307 100644 --- a/pkg/nazalog/global.go +++ b/pkg/nazalog/global.go @@ -14,7 +14,7 @@ import ( "github.com/q191201771/naza/pkg/fake" ) -var global Logger +var global *logger func Outputf(level Level, calldepth int, format string, v ...interface{}) { global.Out(level, 3, fmt.Sprintf(format, v...)) @@ -92,22 +92,17 @@ func PanicIfErrorNotNil(err error) { func Assert(expected interface{}, actual interface{}) { if !equal(expected, actual) { - global.Out(LevelFatal, 3, fmt.Sprintf("fatal since excepted=%+v, but actual=%+v", expected, actual)) - } -} - -func FatalAssert(expected interface{}, actual interface{}) { - if !equal(expected, actual) { - global.Out(LevelFatal, 3, fmt.Sprintf("fatal since excepted=%+v, but actual=%+v", expected, actual)) - fake.Exit(1) - } -} - -func PanicAssert(expected interface{}, actual interface{}) { - if !equal(expected, actual) { - err := fmt.Sprintf("panic since excepted=%+v, but actual=%+v", expected, actual) - global.Out(LevelPanic, 3, err) - panic(err) + err := fmt.Sprintf("assert failed. excepted=%+v, but actual=%+v", expected, actual) + switch global.option.AssertBehavior { + case AssertError: + global.Out(LevelError, 3, err) + case AssertFatal: + global.Out(LevelFatal, 3, err) + fake.Exit(1) + case AssertPanic: + global.Out(LevelPanic, 3, err) + panic(err) + } } } @@ -122,7 +117,7 @@ func Sync() { // 这里不加锁保护,如果要调用Init函数初始化全局的Logger,那么由调用方保证调用Init函数时不会并发调用全局Logger的其他方法 func Init(modOptions ...ModOption) error { var err error - global, err = New(modOptions...) + global, err = newLogger(modOptions...) return err } diff --git a/pkg/nazalog/interface.go b/pkg/nazalog/interface.go index 7ce1b07..d6188c7 100644 --- a/pkg/nazalog/interface.go +++ b/pkg/nazalog/interface.go @@ -39,18 +39,18 @@ type Logger interface { Fatal(v ...interface{}) Panic(v ...interface{}) - FatalIfErrorNotNil(err error) - PanicIfErrorNotNil(err error) - - // 注意,expected和actual的类型必须相同,比如int(1)和int32(1)是不相等的 - Assert(expected interface{}, actual interface{}) // 不相等时打印error级别日志 - FatalAssert(expected interface{}, actual interface{}) - PanicAssert(expected interface{}, actual interface{}) - Outputf(level Level, calldepth int, format string, v ...interface{}) Output(level Level, calldepth int, v ...interface{}) Out(level Level, calldepth int, s string) + // 断言失败后的行为由配置项Option.AssertBehavior决定 + // 注意,expected和actual的类型必须相同,比如int(1)和int32(1)是不相等的 + Assert(expected interface{}, actual interface{}) + + FatalIfErrorNotNil(err error) + PanicIfErrorNotNil(err error) + + // flush to disk, typically Sync() } @@ -65,15 +65,18 @@ type Option struct { IsRotateDaily bool `json:"is_rotate_daily"` // 日志按天翻转 ShortFileFlag bool `json:"short_file_flag"` // 是否在每行日志尾部添加源码文件及行号的信息 + + AssertBehavior AssertBehavior `json:"assert_behavior"` // 断言失败时的行为 } // 没有配置的属性,将按如下配置 var defaultOption = Option{ - Level: LevelDebug, - Filename: "", - IsToStdout: true, - IsRotateDaily: false, - ShortFileFlag: true, + Level: LevelDebug, + Filename: "", + IsToStdout: true, + IsRotateDaily: false, + ShortFileFlag: true, + AssertBehavior: AssertError, } type Level uint8 @@ -88,9 +91,22 @@ const ( LevelPanic ) +type AssertBehavior uint8 + +const ( + _ AssertBehavior = iota + AssertError // 1 + AssertFatal + AssertPanic +) + type ModOption func(option *Option) func New(modOptions ...ModOption) (Logger, error) { + return newLogger(modOptions...) +} + +func newLogger(modOptions ...ModOption) (*logger, error) { var err error l := new(logger) @@ -124,5 +140,8 @@ func validate(option Option) error { if option.Level < LevelDebug || option.Level > LevelPanic { return ErrLog } + if option.AssertBehavior < AssertError || option.AssertBehavior > AssertPanic { + return ErrLog + } return nil } diff --git a/pkg/nazalog/log.go b/pkg/nazalog/log.go index 63569d7..59a3a1c 100644 --- a/pkg/nazalog/log.go +++ b/pkg/nazalog/log.go @@ -20,6 +20,8 @@ import ( "github.com/q191201771/naza/pkg/fake" ) +var _ Logger = new(logger) + const ( levelDebugString = "DEBUG " levelInfoString = " INFO " @@ -143,22 +145,17 @@ func (l *logger) PanicIfErrorNotNil(err error) { func (l *logger) Assert(expected interface{}, actual interface{}) { if !equal(expected, actual) { - l.Out(LevelError, 3, fmt.Sprintf("fatal since excepted=%+v, but actual=%+v", expected, actual)) - } -} - -func (l *logger) FatalAssert(expected interface{}, actual interface{}) { - if !equal(expected, actual) { - l.Out(LevelFatal, 3, fmt.Sprintf("fatal since excepted=%+v, but actual=%+v", expected, actual)) - fake.Exit(1) - } -} - -func (l *logger) PanicAssert(expected interface{}, actual interface{}) { - if !equal(expected, actual) { - err := fmt.Sprintf("panic since excepted=%+v, but actual=%+v", expected, actual) - l.Out(LevelPanic, 3, err) - panic(err) + err := fmt.Sprintf("assert failed. excepted=%+v, but actual=%+v", expected, actual) + switch l.option.AssertBehavior { + case AssertError: + l.Out(LevelError, 3, err) + case AssertFatal: + l.Out(LevelFatal, 3, err) + fake.Exit(1) + case AssertPanic: + l.Out(LevelPanic, 3, err) + panic(err) + } } } diff --git a/pkg/nazalog/log_test.go b/pkg/nazalog/log_test.go index 89b7507..5c112d7 100644 --- a/pkg/nazalog/log_test.go +++ b/pkg/nazalog/log_test.go @@ -6,7 +6,7 @@ // // Author: Chef (191201771@qq.com) -package nazalog +package nazalog_test import ( "encoding/hex" @@ -15,14 +15,16 @@ import ( "os" "testing" + "github.com/q191201771/naza/pkg/nazalog" + "github.com/q191201771/naza/pkg/fake" "github.com/q191201771/naza/pkg/assert" ) func TestLogger(t *testing.T) { - l, err := New(func(option *Option) { - option.Level = LevelInfo + l, err := nazalog.New(func(option *nazalog.Option) { + option.Level = nazalog.LevelInfo option.Filename = "/tmp/nazalogtest/aaa.log" option.IsToStdout = true option.IsRotateDaily = true @@ -38,62 +40,68 @@ func TestLogger(t *testing.T) { l.Info("l test msg by Info") l.Warn("l test msg by Warn") l.Error("l test msg by Error") - l.Outputf(LevelInfo, 3, "l test msg by Output%s", "f") - l.Output(LevelInfo, 3, "l test msg by Output") - l.Out(LevelInfo, 2, "l test msg by Out") + l.Outputf(nazalog.LevelInfo, 3, "l test msg by Output%s", "f") + l.Output(nazalog.LevelInfo, 3, "l test msg by Output") + l.Out(nazalog.LevelInfo, 2, "l test msg by Out") } func TestGlobal(t *testing.T) { buf := []byte("1234567890987654321") - Error(hex.Dump(buf)) - Debugf("g test msg by Debug%s", "f") - Infof("g test msg by Info%s", "f") - Warnf("g test msg by Warn%s", "f") - Errorf("g test msg by Error%s", "f") - Debug("g test msg by Debug") - Info("g test msg by Info") - Warn("g test msg by Warn") - Error("g test msg by Error") + nazalog.Error(hex.Dump(buf)) + nazalog.Debugf("g test msg by Debug%s", "f") + nazalog.Infof("g test msg by Info%s", "f") + nazalog.Warnf("g test msg by Warn%s", "f") + nazalog.Errorf("g test msg by Error%s", "f") + nazalog.Debug("g test msg by Debug") + nazalog.Info("g test msg by Info") + nazalog.Warn("g test msg by Warn") + nazalog.Error("g test msg by Error") - err := Init(func(option *Option) { - option.Level = LevelInfo + err := nazalog.Init(func(option *nazalog.Option) { + option.Level = nazalog.LevelInfo option.Filename = "/tmp/nazalogtest/bbb.log" option.IsToStdout = true }) assert.Equal(t, nil, err) - Debugf("gc test msg by Debug%s", "f") - Infof("gc test msg by Info%s", "f") - Warnf("gc test msg by Warn%s", "f") - Errorf("gc test msg by Error%s", "f") - Debug("gc test msg by Debug") - Info("gc test msg by Info") - Warn("gc test msg by Warn") - Error("gc test msg by Error") - Outputf(LevelInfo, 3, "gc test msg by Output%s", "f") - Output(LevelInfo, 3, "gc test msg by Output") - Out(LevelInfo, 3, "gc test msg by Out") - Sync() + nazalog.Debugf("gc test msg by Debug%s", "f") + nazalog.Infof("gc test msg by Info%s", "f") + nazalog.Warnf("gc test msg by Warn%s", "f") + nazalog.Errorf("gc test msg by Error%s", "f") + nazalog.Debug("gc test msg by Debug") + nazalog.Info("gc test msg by Info") + nazalog.Warn("gc test msg by Warn") + nazalog.Error("gc test msg by Error") + nazalog.Outputf(nazalog.LevelInfo, 3, "gc test msg by Output%s", "f") + nazalog.Output(nazalog.LevelInfo, 3, "gc test msg by Output") + nazalog.Out(nazalog.LevelInfo, 3, "gc test msg by Out") + nazalog.Sync() } func TestNew(t *testing.T) { var ( - l Logger + l nazalog.Logger err error ) - l, err = New(func(option *Option) { - option.Level = LevelPanic + 1 + l, err = nazalog.New(func(option *nazalog.Option) { + option.Level = nazalog.LevelPanic + 1 }) assert.Equal(t, nil, l) - assert.Equal(t, ErrLog, err) + assert.Equal(t, nazalog.ErrLog, err) - l, err = New(func(option *Option) { + l, err = nazalog.New(func(option *nazalog.Option) { + option.AssertBehavior = nazalog.AssertPanic + 1 + }) + assert.Equal(t, nil, l) + assert.Equal(t, nazalog.ErrLog, err) + + l, err = nazalog.New(func(option *nazalog.Option) { option.Filename = "/tmp" }) assert.Equal(t, nil, l) assert.IsNotNil(t, err) - l, err = New(func(option *Option) { + l, err = nazalog.New(func(option *nazalog.Option) { option.Filename = "./log_test.go/111" }) assert.Equal(t, nil, l) @@ -101,8 +109,8 @@ func TestNew(t *testing.T) { } func TestRotate(t *testing.T) { - err := Init(func(option *Option) { - option.Level = LevelInfo + err := nazalog.Init(func(option *nazalog.Option) { + option.Level = nazalog.LevelInfo option.Filename = "/tmp/nazalogtest/ccc.log" option.IsToStdout = false option.IsRotateDaily = true @@ -111,10 +119,10 @@ func TestRotate(t *testing.T) { assert.Equal(t, nil, err) b := make([]byte, 1024) for i := 0; i < 2*1024; i++ { - Info(b) + nazalog.Info(b) } for i := 0; i < 2*1024; i++ { - Infof("%+v", b) + nazalog.Infof("%+v", b) } } @@ -127,27 +135,27 @@ func withRecover(f func()) { func TestPanic(t *testing.T) { withRecover(func() { - Debug("ddd") - Panic("aaa") + nazalog.Debug("ddd") + nazalog.Panic("aaa") }) withRecover(func() { - Panicf("%s", "bbb") + nazalog.Panicf("%s", "bbb") }) withRecover(func() { - PanicIfErrorNotNil(errors.New("mock error")) + nazalog.PanicIfErrorNotNil(errors.New("mock error")) }) withRecover(func() { - l, err := New() + l, err := nazalog.New() assert.Equal(t, nil, err) l.Panic("aaa") }) withRecover(func() { - l, err := New() + l, err := nazalog.New() assert.Equal(t, nil, err) l.Panicf("%s", "bbb") }) withRecover(func() { - l, err := New() + l, err := nazalog.New() assert.Equal(t, nil, err) l.PanicIfErrorNotNil(errors.New("mock error")) }) @@ -156,22 +164,22 @@ func TestPanic(t *testing.T) { func TestFatal(t *testing.T) { var er fake.ExitResult er = fake.WithFakeExit(func() { - FatalIfErrorNotNil(errors.New("fxxk")) + nazalog.FatalIfErrorNotNil(errors.New("fxxk")) }) assert.Equal(t, true, er.HasExit) assert.Equal(t, 1, er.ExitCode) er = fake.WithFakeExit(func() { - Fatal("Fatal") + nazalog.Fatal("Fatal") }) assert.Equal(t, true, er.HasExit) assert.Equal(t, 1, er.ExitCode) er = fake.WithFakeExit(func() { - Fatalf("Fatalf%s", ".") + nazalog.Fatalf("Fatalf%s", ".") }) assert.Equal(t, true, er.HasExit) assert.Equal(t, 1, er.ExitCode) - logger, _ := New() + logger, _ := nazalog.New() er = fake.WithFakeExit(func() { logger.FatalIfErrorNotNil(errors.New("fxxk")) }) @@ -191,62 +199,78 @@ func TestFatal(t *testing.T) { func TestAssert(t *testing.T) { // 成功 - Assert(nil, nil) - FatalAssert(nil, nil) - PanicAssert(nil, nil) - PanicAssert(1, 1) - PanicAssert("aaa", "aaa") + nazalog.Assert(nil, nil) + nazalog.Assert(nil, nil) + nazalog.Assert(nil, nil) + nazalog.Assert(1, 1) + nazalog.Assert("aaa", "aaa") var ch chan struct{} - PanicAssert(nil, ch) + nazalog.Assert(nil, ch) var m map[string]string - PanicAssert(nil, m) + nazalog.Assert(nil, m) var p *int - PanicAssert(nil, p) + nazalog.Assert(nil, p) var i interface{} - PanicAssert(nil, i) + nazalog.Assert(nil, i) var b []byte - PanicAssert(nil, b) + nazalog.Assert(nil, b) - PanicAssert([]byte{}, []byte{}) - PanicAssert([]byte{0, 1, 2}, []byte{0, 1, 2}) + nazalog.Assert([]byte{}, []byte{}) + nazalog.Assert([]byte{0, 1, 2}, []byte{0, 1, 2}) // 失败 - Assert(nil, 1) + _ = nazalog.Init(func(option *nazalog.Option) { + option.AssertBehavior = nazalog.AssertError + }) + nazalog.Assert(nil, 1) + _ = nazalog.Init(func(option *nazalog.Option) { + option.AssertBehavior = nazalog.AssertFatal + }) err := fake.WithFakeExit(func() { - FatalAssert(nil, 1) + nazalog.Assert(nil, 1) }) assert.Equal(t, true, err.HasExit) assert.Equal(t, 1, err.ExitCode) + _ = nazalog.Init(func(option *nazalog.Option) { + option.AssertBehavior = nazalog.AssertPanic + }) withRecover(func() { - PanicAssert([]byte{}, "aaa") + nazalog.Assert([]byte{}, "aaa") }) - l, _ := New() + l, _ := nazalog.New() l.Assert(nil, 1) + + l, _ = nazalog.New(func(option *nazalog.Option) { + option.AssertBehavior = nazalog.AssertFatal + }) err = fake.WithFakeExit(func() { - l.FatalAssert(nil, 1) + l.Assert(nil, 1) }) assert.Equal(t, true, err.HasExit) assert.Equal(t, 1, err.ExitCode) + l, _ = nazalog.New(func(option *nazalog.Option) { + option.AssertBehavior = nazalog.AssertPanic + }) withRecover(func() { - l.PanicAssert([]byte{}, "aaa") + l.Assert([]byte{}, "aaa") }) } func BenchmarkStdout(b *testing.B) { b.ReportAllocs() - err := Init(func(option *Option) { - option.Level = LevelInfo + err := nazalog.Init(func(option *nazalog.Option) { + option.Level = nazalog.LevelInfo option.Filename = "/dev/null" }) assert.Equal(b, nil, err) for i := 0; i < b.N; i++ { - Infof("hello %s %d", "world", i) - Info("Info") + nazalog.Infof("hello %s %d", "world", i) + nazalog.Info("Info") } }