diff --git a/util/logstash/log.go b/util/logstash/log.go index 1f52cc4cd..4e434f073 100644 --- a/util/logstash/log.go +++ b/util/logstash/log.go @@ -28,11 +28,13 @@ func Size() int64 { type logger struct { mu sync.RWMutex data *ring.Ring + size int } func New(size int) *logger { return &logger{ - data: ring.New(size), + data: ring.New(1), + size: size, } } @@ -44,6 +46,12 @@ func (l *logger) Write(p []byte) (n int, err error) { if !strings.HasPrefix(string(p), "[cache ]") { l.data.Value = element(string(p)) + + // dynamically grow the ring + if l.data.Len() < l.size { + l.data.Link(ring.New(1)) + } + l.data = l.data.Next() } @@ -95,7 +103,7 @@ func (l *logger) All(areas []string, level jww.Threshold, count int) []string { r := l.data all := len(areas) == 0 && level == jww.LevelTrace - var res []string + res := make([]string, 0, r.Len()) for range r.Len() { r = r.Next() if e, ok := r.Value.(element); ok && e != "" && (all || e.match(areas, level)) { diff --git a/util/logstash/log_test.go b/util/logstash/log_test.go index 87c07de7a..c5dc8f6b3 100644 --- a/util/logstash/log_test.go +++ b/util/logstash/log_test.go @@ -7,13 +7,15 @@ import ( "github.com/stretchr/testify/assert" ) +var ( + s1 = "[test1 ] TRACE test1" + s2 = "[test2 ] ERROR test2" + s3 = "[test1 ] TRACE test3" +) + func TestLog(t *testing.T) { log := New(10) - s1 := "[test1 ] TRACE test1" - s2 := "[test2 ] ERROR test2" - s3 := "[test1 ] TRACE test3" - // old to new log.Write([]byte(s1)) log.Write([]byte(s2)) @@ -33,3 +35,16 @@ func TestLog(t *testing.T) { assert.Equal(t, idx, log.data, "data should not be changed after All() call") assert.Equal(t, []string{"test1", "test2"}, log.Areas()) } + +func BenchmarkLog(b *testing.B) { + log := New(10000) + + // old to new + log.Write([]byte(s1)) + log.Write([]byte(s2)) + log.Write([]byte(s3)) + + for i := 0; i < b.N; i++ { + log.All(nil, jww.LevelTrace, 1) + } +}