Skip to content

Commit

Permalink
✨ feat: update record.Time init logic, support repeat use a Record in…
Browse files Browse the repository at this point in the history
…stance
  • Loading branch information
inhere committed Jul 2, 2023
1 parent 53f432c commit 4321da1
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 13 deletions.
25 changes: 25 additions & 0 deletions issues_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package slog_test

import (
"fmt"
"sync"
"testing"
"time"

Expand Down Expand Up @@ -67,3 +68,27 @@ func TestIssues_75(t *testing.T) {
slog.Reset()
// dump.P(slog.GetFormatter())
}

// https://github.com/gookit/slog/issues/105
func TestIssues_105(t *testing.T) {
t.Run("simple write", func(t *testing.T) {
for i := 0; i < 10; i++ {
slog.Error("simple error log", i)
time.Sleep(time.Millisecond * 100)
}
})

// test concurrent write
t.Run("concurrent write", func(t *testing.T) {
wg := sync.WaitGroup{}
for i := 0; i < 100; i++ {
wg.Add(1)
go func(i int) {
slog.Error("concurrent error log", i)
time.Sleep(time.Millisecond * 100)
wg.Done()
}(i)
}
wg.Wait()
})
}
17 changes: 10 additions & 7 deletions write.go → logger_write.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ package slog
// r.Buffer = nil
// }

// Init something for record.
// Init something for record(eg: time, level name).
func (r *Record) Init(lowerLevelName bool) {
r.inited = true

// use lower level name
if lowerLevelName {
r.levelName = r.Level.LowerName()
Expand Down Expand Up @@ -54,22 +56,22 @@ func (r *Record) beforeHandle(l *Logger) {
}
}

// do write log record
// do write record to handlers, will add lock.
func (l *Logger) writeRecord(level Level, r *Record) {
l.mu.Lock()
defer l.mu.Unlock()
// reset init flag, useful for repeat use Record
r.inited = false

// do write log message
var inited bool
for _, handler := range l.handlers {
if handler.IsHandling(level) {
if !inited {
// init, call processors
// init record, call processors
if !r.inited {
r.Init(l.LowerLevelName)
r.beforeHandle(l)
inited = true
}

// do write log message by handler
if err := handler.Handle(r); err != nil {
l.err = err
printlnStderr("slog: failed to handle log, error:", err)
Expand All @@ -78,6 +80,7 @@ func (l *Logger) writeRecord(level Level, r *Record) {
}

// ---- after write log ----
r.Time = emptyTime

// flush logs on level <= error level.
if level <= ErrorLevel {
Expand Down
16 changes: 11 additions & 5 deletions record.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,14 @@ import (
// Record a log record definition
type Record struct {
logger *Logger

// Time for record log
// release flag for record. TODO
unreleased bool
// inited flag for record
inited bool

// Time for record log, if is empty will use now.
//
// TIP: Will be emptied after each use (write)
Time time.Time
// Level log level for record
Level Level
Expand Down Expand Up @@ -134,9 +140,9 @@ func (r *Record) Copy() *Record {
}

return &Record{
logger: r.logger,
Channel: r.Channel,
Time: r.Time,
logger: r.logger,
Channel: r.Channel,
// Time: r.Time,
Level: r.Level,
levelName: r.levelName,
CallerFlag: r.CallerFlag,
Expand Down
36 changes: 35 additions & 1 deletion record_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ package slog_test
import (
"context"
"fmt"
"os"
"sync"
"testing"
"time"

"github.com/gookit/goutil/byteutil"
"github.com/gookit/goutil/errorx"
"github.com/gookit/goutil/testutil/assert"
"github.com/gookit/goutil/timex"
Expand Down Expand Up @@ -187,7 +191,7 @@ func TestRecord_allLevel(t *testing.T) {
})

r := l.Record()
r.WithContext(context.Background())
r = r.WithContext(context.Background())
printAllLevelLogs(r, "a message use record.XX()")
r.Log(slog.InfoLevel, "a message use record.XX()")
r.Notice("a message use record.XX()")
Expand All @@ -210,3 +214,33 @@ func TestRecord_allLevel(t *testing.T) {
assert.Contains(t, s, "[NOTICE]")
assert.Contains(t, s, "[TRACE]")
}

func TestRecord_useMultiTimes(t *testing.T) {
buf := byteutil.NewBuffer()
l := slog.NewWithHandlers(
handler.NewSimple(buf, slog.DebugLevel),
handler.NewSimple(os.Stdout, slog.DebugLevel),
)

r := l.Record()
t.Run("simple", func(t *testing.T) {
for i := 0; i < 10; i++ {
r.Error("simple error log", i)
time.Sleep(time.Millisecond * 100)
}
})

// test concurrent write
t.Run("concurrent", func(t *testing.T) {
wg := sync.WaitGroup{}
for i := 0; i < 100; i++ {
wg.Add(1)
go func(i int) {
r.Error("concurrent error log", i)
time.Sleep(time.Millisecond * 100)
wg.Done()
}(i)
}
wg.Wait()
})
}

0 comments on commit 4321da1

Please sign in to comment.