Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions buffer_pool.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package logrus

import (
"bytes"
"sync"
)

var (
bufferPool BufferPool
)

type BufferPool interface {
Put(*bytes.Buffer)
Get() *bytes.Buffer
}

type defaultPool struct {
pool *sync.Pool
}

func (p *defaultPool) Put(buf *bytes.Buffer) {
p.pool.Put(buf)
}

func (p *defaultPool) Get() *bytes.Buffer {
return p.pool.Get().(*bytes.Buffer)
}

func getBuffer() *bytes.Buffer {
return bufferPool.Get()
}

func putBuffer(buf *bytes.Buffer) {
buf.Reset()
bufferPool.Put(buf)
}

// SetBufferPool allows to replace the default logrus buffer pool
// to better meets the specific needs of an application.
func SetBufferPool(bp BufferPool) {
bufferPool = bp
}

func init() {
SetBufferPool(&defaultPool{
pool: &sync.Pool{
New: func() interface{} {
return new(bytes.Buffer)
},
},
})
}
24 changes: 14 additions & 10 deletions entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
)

var (
bufferPool *sync.Pool

// qualified package name, cached at first use
logrusPackage string
Expand All @@ -31,12 +30,6 @@ const (
)

func init() {
bufferPool = &sync.Pool{
New: func() interface{} {
return new(bytes.Buffer)
},
}

// start at the bottom of the stack before the package-name cache is primed
minimumCallerDepth = 1
}
Expand Down Expand Up @@ -80,6 +73,7 @@ type Entry struct {
func NewEntry(logger *Logger) *Entry {
return &Entry{
Logger: logger,
Level: logger.Level,
// Default is three fields, plus one optional. Give a little extra room.
Data: make(Fields, 6),
}
Expand Down Expand Up @@ -148,7 +142,14 @@ func (entry *Entry) WithFields(fields Fields) *Entry {
data[k] = v
}
}
return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, err: fieldErr, Context: entry.Context}
return &Entry{
Logger: entry.Logger,
Data: data,
Time: entry.Time,
Level: entry.Level,
err: fieldErr,
Context: entry.Context,
}
}

// Overrides the time of the Entry.
Expand Down Expand Up @@ -243,9 +244,12 @@ func (entry Entry) log(level Level, msg string) {

entry.fireHooks()

buffer = bufferPool.Get().(*bytes.Buffer)
buffer = getBuffer()
defer func() {
entry.Buffer = nil
putBuffer(buffer)
}()
buffer.Reset()
defer bufferPool.Put(buffer)
entry.Buffer = buffer

entry.write()
Expand Down
2 changes: 1 addition & 1 deletion logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
// LogFunction For big messages, it can be more efficient to pass a function
// and only call it if the log level is actually enables rather than
// generating the log message and then checking if the level is enabled
type LogFunction func()[]interface{}
type LogFunction func() []interface{}

type Logger struct {
// The logs are `io.Copy`'d to this in a mutex. It's common to set this to a
Expand Down
12 changes: 12 additions & 0 deletions logrus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -763,3 +763,15 @@ func TestSetReportCallerRace(t *testing.T) {
}
wg.Wait()
}

func TestLevel(t *testing.T) {
l := New()
l.SetLevel(InfoLevel)

e := l.WithField("foo", "bar")

assert.Equal(t, l.Level, e.Level)
e.Debug("I shouldn't be printed")
e.Info("I should be printed")
assert.Equal(t, l.Level, e.Level)
}
2 changes: 1 addition & 1 deletion text_formatter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func TestFormatting(t *testing.T) {
value string
expected string
}{
{`foo`, "time=\"0001-01-01T00:00:00Z\" level=panic test=foo\n"},
{`foo`, "time=\"0001-01-01T00:00:00Z\" level=info test=foo\n"},
}

for _, tc := range testCases {
Expand Down