diff --git a/example/main.go b/example/main.go index 23122b8..9e4a57c 100755 --- a/example/main.go +++ b/example/main.go @@ -148,6 +148,17 @@ func main() { glg.Printf("%s : %s", "printf", "formatted") glg.CustomLog(customTag, "custom logging") glg.CustomLog(customErrTag, "custom error logging") + + glg.Info("kpango's glg supports disable timestamp for logging") + glg.Get().DisableTimestamp() + glg.Info("timestamp disabled") + glg.Warn("timestamp disabled") + glg.Log("timestamp disabled") + glg.Get().EnableTimestamp() + glg.Info("timestamp enabled") + glg.Warn("timestamp enabled") + glg.Log("timestamp enabled") + glg.Info("kpango's glg support json logging") glg.Get().EnableJSON() err := glg.Warn("kpango's glg", "support", "json", "logging") diff --git a/glg.go b/glg.go index 3c7a651..ea99bbd 100755 --- a/glg.go +++ b/glg.go @@ -66,14 +66,15 @@ type LEVEL uint8 type wMode uint8 type logger struct { - tag string - rawtag []byte - writer io.Writer - std io.Writer - color func(string) string - isColor bool - mode MODE - writeMode wMode + tag string + rawtag []byte + writer io.Writer + std io.Writer + color func(string) string + isColor bool + mode MODE + writeMode wMode + disableTimestamp bool } const ( @@ -127,9 +128,10 @@ const ( rc = "\n" rcl = len(rc) - lsep = "\t[" + tab = "\t" + lsep = tab + "[" lsepl = len(lsep) - sep = "]:\t" + sep = "]:" + tab sepl = len(sep) ) @@ -479,6 +481,50 @@ func (g *Glg) AddErrLevel(tag string, mode MODE, isColor bool) *Glg { return g } +// EnableTimestamp enables timestamp output +func (g *Glg) EnableTimestamp() *Glg { + + g.logger.Range(func(lev LEVEL, l *logger) bool { + l.disableTimestamp = false + g.logger.Store(lev, l) + return true + }) + + return g +} + +// DisableTimestamp disables timestamp output +func (g *Glg) DisableTimestamp() *Glg { + + g.logger.Range(func(lev LEVEL, l *logger) bool { + l.disableTimestamp = true + g.logger.Store(lev, l) + return true + }) + + return g +} + +// EnableLevelTimestamp enables timestamp output +func (g *Glg) EnableLevelTimestamp(lv LEVEL) *Glg { + l, ok := g.logger.Load(lv) + if ok { + l.disableTimestamp = false + g.logger.Store(lv, l) + } + return g +} + +// DisableLevelTimestamp disables timestamp output +func (g *Glg) DisableLevelTimestamp(lv LEVEL) *Glg { + l, ok := g.logger.Load(lv) + if ok { + l.disableTimestamp = true + g.logger.Store(lv, l) + } + return g +} + // EnableColor enables color output func (g *Glg) EnableColor() *Glg { @@ -685,7 +731,6 @@ func (g *Glg) out(level LEVEL, format string, val ...interface{}) error { return fmt.Errorf("error:\tLog Level %d Not Found", level) } - fn := fastime.FormattedNow() if g.enableJSON { var w io.Writer switch log.writeMode { @@ -706,8 +751,13 @@ func (g *Glg) out(level LEVEL, format string, val ...interface{}) error { } else { detail = val[0] } + var timestamp string + if !log.disableTimestamp { + fn := fastime.FormattedNow() + timestamp = *(*string)(unsafe.Pointer(&fn)) + } return json.NewEncoder(w).Encode(JSONFormat{ - Date: *(*string)(unsafe.Pointer(&fn)), + Date: timestamp, Level: log.tag, Detail: detail, }) @@ -719,8 +769,12 @@ func (g *Glg) out(level LEVEL, format string, val ...interface{}) error { b = g.buffer.Get().(*bytes.Buffer) ) - b.Write(fn) - b.Write(log.rawtag) + if log.disableTimestamp { + b.Write(log.rawtag[len(tab):]) + } else { + b.Write(fastime.FormattedNow()) + b.Write(log.rawtag) + } b.WriteString(format) switch { diff --git a/glg_test.go b/glg_test.go index 71f03dc..225665e 100755 --- a/glg_test.go +++ b/glg_test.go @@ -24,7 +24,6 @@ package glg import ( "bytes" - "encoding/json" "errors" "fmt" "io" @@ -33,8 +32,11 @@ import ( "os" "reflect" "strings" + "sync" "testing" "time" + + json "github.com/goccy/go-json" ) type ExitError int @@ -3936,3 +3938,319 @@ func TestGlg_EnablePoolBuffer(t *testing.T) { t.Error("buffer is not bytes.Buffer") } } + +func Test_logger_updateMode(t *testing.T) { + type fields struct { + writer io.Writer + isColor bool + mode MODE + } + tests := []struct { + name string + fields fields + want wMode + }{ + { + name: "writeWriter mode", + fields: fields{ + mode: WRITER, + writer: new(bytes.Buffer), + }, + want: writeWriter, + }, + + { + name: "writeColorBoth mode", + fields: fields{ + mode: BOTH, + isColor: true, + writer: new(bytes.Buffer), + }, + want: writeColorBoth, + }, + { + name: "writeBoth mode", + fields: fields{ + mode: BOTH, + writer: new(bytes.Buffer), + }, + want: writeBoth, + }, + { + name: "writeColorStd mode due to nil writer", + fields: fields{ + mode: BOTH, + isColor: true, + }, + want: writeColorStd, + }, + { + name: "writeStd mode due to nil writer", + fields: fields{ + mode: BOTH, + }, + want: writeStd, + }, + { + name: "writeColorStd mode", + fields: fields{ + mode: STD, + isColor: true, + }, + want: writeColorStd, + }, + { + name: "writeStd mode", + fields: fields{ + mode: STD, + }, + want: writeStd, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + l := &logger{ + writer: tt.fields.writer, + isColor: tt.fields.isColor, + mode: tt.fields.mode, + } + if got := l.updateMode(); l.writeMode != tt.want { + t.Errorf("logger.updateMode() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestGlg_EnableTimestamp(t *testing.T) { + type fields struct { + bs *uint64 + logger loggers + levelCounter *uint32 + levelMap levelMap + buffer sync.Pool + enableJSON bool + } + tests := []struct { + name string + fields fields + want *Glg + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + g := &Glg{ + bs: tt.fields.bs, + logger: tt.fields.logger, + levelCounter: tt.fields.levelCounter, + levelMap: tt.fields.levelMap, + buffer: tt.fields.buffer, + enableJSON: tt.fields.enableJSON, + } + if got := g.EnableTimestamp(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Glg.EnableTimestamp() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestGlg_DisableTimestamp(t *testing.T) { + type fields struct { + bs *uint64 + logger loggers + levelCounter *uint32 + levelMap levelMap + buffer sync.Pool + enableJSON bool + } + tests := []struct { + name string + fields fields + want *Glg + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + g := &Glg{ + bs: tt.fields.bs, + logger: tt.fields.logger, + levelCounter: tt.fields.levelCounter, + levelMap: tt.fields.levelMap, + buffer: tt.fields.buffer, + enableJSON: tt.fields.enableJSON, + } + if got := g.DisableTimestamp(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Glg.DisableTimestamp() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestGlg_EnableLevelTimestamp(t *testing.T) { + type fields struct { + bs *uint64 + logger loggers + levelCounter *uint32 + levelMap levelMap + buffer sync.Pool + enableJSON bool + } + type args struct { + lv LEVEL + } + tests := []struct { + name string + fields fields + args args + want *Glg + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + g := &Glg{ + bs: tt.fields.bs, + logger: tt.fields.logger, + levelCounter: tt.fields.levelCounter, + levelMap: tt.fields.levelMap, + buffer: tt.fields.buffer, + enableJSON: tt.fields.enableJSON, + } + if got := g.EnableLevelTimestamp(tt.args.lv); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Glg.EnableLevelTimestamp() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestGlg_DisableLevelTimestamp(t *testing.T) { + type fields struct { + bs *uint64 + logger loggers + levelCounter *uint32 + levelMap levelMap + buffer sync.Pool + enableJSON bool + } + type args struct { + lv LEVEL + } + tests := []struct { + name string + fields fields + args args + want *Glg + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + g := &Glg{ + bs: tt.fields.bs, + logger: tt.fields.logger, + levelCounter: tt.fields.levelCounter, + levelMap: tt.fields.levelMap, + buffer: tt.fields.buffer, + enableJSON: tt.fields.enableJSON, + } + if got := g.DisableLevelTimestamp(tt.args.lv); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Glg.DisableLevelTimestamp() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestGlg_blankFormat(t *testing.T) { + type fields struct { + bs *uint64 + logger loggers + levelCounter *uint32 + levelMap levelMap + buffer sync.Pool + enableJSON bool + } + type args struct { + l int + } + tests := []struct { + name string + fields fields + args args + want string + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + g := &Glg{ + bs: tt.fields.bs, + logger: tt.fields.logger, + levelCounter: tt.fields.levelCounter, + levelMap: tt.fields.levelMap, + buffer: tt.fields.buffer, + enableJSON: tt.fields.enableJSON, + } + if got := g.blankFormat(tt.args.l); got != tt.want { + t.Errorf("Glg.blankFormat() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_isModeEnable(t *testing.T) { + type args struct { + l LEVEL + } + tests := []struct { + name string + args args + want bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := isModeEnable(tt.args.l); got != tt.want { + t.Errorf("isModeEnable() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestGlg_isModeEnable(t *testing.T) { + type fields struct { + bs *uint64 + logger loggers + levelCounter *uint32 + levelMap levelMap + buffer sync.Pool + enableJSON bool + } + type args struct { + l LEVEL + } + tests := []struct { + name string + fields fields + args args + want bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + g := &Glg{ + bs: tt.fields.bs, + logger: tt.fields.logger, + levelCounter: tt.fields.levelCounter, + levelMap: tt.fields.levelMap, + buffer: tt.fields.buffer, + enableJSON: tt.fields.enableJSON, + } + if got := g.isModeEnable(tt.args.l); got != tt.want { + t.Errorf("Glg.isModeEnable() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/go.mod b/go.mod index 23f0423..314dade 100644 --- a/go.mod +++ b/go.mod @@ -2,8 +2,10 @@ module github.com/kpango/glg go 1.16 +replace github.com/goccy/go-json => github.com/goccy/go-json v0.4.8-0.20210319151453-094f8da49e66 + require ( - github.com/goccy/go-json v0.4.7 + github.com/goccy/go-json v0.0.0-00010101000000-000000000000 github.com/kpango/fastime v1.0.16 go.uber.org/zap v1.16.0 ) diff --git a/go.sum b/go.sum index bb498f0..f801372 100644 --- a/go.sum +++ b/go.sum @@ -3,8 +3,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/goccy/go-json v0.4.7 h1:xGUjaNfhpqhKAV2LoyNXihFLZ8ABSST8B+W+duHqkPI= -github.com/goccy/go-json v0.4.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.4.8-0.20210319151453-094f8da49e66 h1:dSk7i/Ttu2BnlvAE+FWRrYMxYiXXhDxZYQmuvUkbHIE= +github.com/goccy/go-json v0.4.8-0.20210319151453-094f8da49e66/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kpango/fastime v1.0.16 h1:1prFG/3pTjzcDeCTxt98VB4IvjxcySLs0ldCEhZg0R8=