Skip to content

Commit

Permalink
now using a pool of lines for each span
Browse files Browse the repository at this point in the history
  • Loading branch information
muir committed Jul 9, 2022
1 parent 3dfdce2 commit 1b9555b
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 44 deletions.
6 changes: 6 additions & 0 deletions internal/multibase/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ func (s Spans) Line(level xopconst.Level, t time.Time) xopbase.Line {
return lines
}

func (l Lines) Recycle(level xopconst.Level, t time.Time) {
for _, line := range l {
line.Recycle(level, t)
}
}

func (l Lines) Int(k string, v int64) {
for _, line := range l {
line.Int(k, v)
Expand Down
71 changes: 41 additions & 30 deletions logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type Span struct {
spanType xopconst.SpanType
log *Log // back to self
base xopbase.Span
linePool sync.Pool
}

type local struct {
Expand Down Expand Up @@ -157,10 +158,9 @@ func (l *Log) Flush() {
}

func (l *Log) log(level xopconst.Level, msg string, values []xop.Thing) {
line := l.span.base.Line(level, time.Now())
xopbase.LineThings(line, values)
line := l.LogLine(level)
xopbase.LineThings(line.line, values)
line.Msg(msg)
l.enableFlushTimer()
}

// TODO func (l *Log) Zap() like zap
Expand Down Expand Up @@ -247,40 +247,51 @@ type LogLine struct {
line xopbase.Line
}

func (l *Log) LogLine(level xopconst.Level) LogLine {
// TODO PERFORMANCE: have a sync.Pool of LogLines
return LogLine{
func (l *Log) LogLine(level xopconst.Level) *LogLine {
recycled := l.span.linePool.Get()
if recycled != nil {
// TODO: try using LogLine instead of *LogLine
ll := recycled.(*LogLine)
ll.line.Recycle(level, time.Now())
return ll
}
return &LogLine{
log: l,
line: l.span.base.Line(level, time.Now()),
}
}

func (l *Log) Debug() LogLine { return l.LogLine(xopconst.DebugLevel) }
func (l *Log) Trace() LogLine { return l.LogLine(xopconst.TraceLevel) }
func (l *Log) Info() LogLine { return l.LogLine(xopconst.InfoLevel) }
func (l *Log) Warn() LogLine { return l.LogLine(xopconst.WarnLevel) }
func (l *Log) Error() LogLine { return l.LogLine(xopconst.ErrorLevel) }
func (l *Log) Alert() LogLine { return l.LogLine(xopconst.AlertLevel) }
func (ll *LogLine) Msg(msg string) {
ll.line.Msg(msg)
ll.log.span.linePool.Put(ll)
ll.log.enableFlushTimer()
}

func (l *Log) Debug() *LogLine { return l.LogLine(xopconst.DebugLevel) }
func (l *Log) Trace() *LogLine { return l.LogLine(xopconst.TraceLevel) }
func (l *Log) Info() *LogLine { return l.LogLine(xopconst.InfoLevel) }
func (l *Log) Warn() *LogLine { return l.LogLine(xopconst.WarnLevel) }
func (l *Log) Error() *LogLine { return l.LogLine(xopconst.ErrorLevel) }
func (l *Log) Alert() *LogLine { return l.LogLine(xopconst.AlertLevel) }

// TODO: generate these
// TODO: the rest of the set
func (ll LogLine) Msg(msg string) { ll.line.Msg(msg); ll.log.enableFlushTimer() }
func (ll LogLine) Msgf(msg string, v ...interface{}) { ll.Msg(fmt.Sprintf(msg, v...)) }
func (ll LogLine) Msgs(v ...interface{}) { ll.Msg(fmt.Sprint(v...)) }
func (ll LogLine) Int(k string, v int) LogLine { ll.line.Int(k, int64(v)); return ll }
func (ll LogLine) Int8(k string, v int8) LogLine { ll.line.Int(k, int64(v)); return ll }
func (ll LogLine) Int16(k string, v int16) LogLine { ll.line.Int(k, int64(v)); return ll }
func (ll LogLine) Int32(k string, v int32) LogLine { ll.line.Int(k, int64(v)); return ll }
func (ll LogLine) Int64(k string, v int64) LogLine { ll.line.Int(k, v); return ll }
func (ll LogLine) Uint(k string, v uint) LogLine { ll.line.Uint(k, uint64(v)); return ll }
func (ll LogLine) Uint8(k string, v uint8) LogLine { ll.line.Uint(k, uint64(v)); return ll }
func (ll LogLine) Uint16(k string, v uint16) LogLine { ll.line.Uint(k, uint64(v)); return ll }
func (ll LogLine) Uint32(k string, v uint32) LogLine { ll.line.Uint(k, uint64(v)); return ll }
func (ll LogLine) Uint64(k string, v uint64) LogLine { ll.line.Uint(k, v); return ll }
func (ll LogLine) Str(k string, v string) LogLine { ll.line.Str(k, v); return ll }
func (ll LogLine) Bool(k string, v bool) LogLine { ll.line.Bool(k, v); return ll }
func (ll LogLine) Time(k string, v time.Time) LogLine { ll.line.Time(k, v); return ll }
func (ll LogLine) Error(k string, v error) LogLine { ll.line.Error(k, v); return ll }
func (ll *LogLine) Msgf(msg string, v ...interface{}) { ll.Msg(fmt.Sprintf(msg, v...)) }
func (ll *LogLine) Msgs(v ...interface{}) { ll.Msg(fmt.Sprint(v...)) }
func (ll *LogLine) Int(k string, v int) *LogLine { ll.line.Int(k, int64(v)); return ll }
func (ll *LogLine) Int8(k string, v int8) *LogLine { ll.line.Int(k, int64(v)); return ll }
func (ll *LogLine) Int16(k string, v int16) *LogLine { ll.line.Int(k, int64(v)); return ll }
func (ll *LogLine) Int32(k string, v int32) *LogLine { ll.line.Int(k, int64(v)); return ll }
func (ll *LogLine) Int64(k string, v int64) *LogLine { ll.line.Int(k, v); return ll }
func (ll *LogLine) Uint(k string, v uint) *LogLine { ll.line.Uint(k, uint64(v)); return ll }
func (ll *LogLine) Uint8(k string, v uint8) *LogLine { ll.line.Uint(k, uint64(v)); return ll }
func (ll *LogLine) Uint16(k string, v uint16) *LogLine { ll.line.Uint(k, uint64(v)); return ll }
func (ll *LogLine) Uint32(k string, v uint32) *LogLine { ll.line.Uint(k, uint64(v)); return ll }
func (ll *LogLine) Uint64(k string, v uint64) *LogLine { ll.line.Uint(k, v); return ll }
func (ll *LogLine) Str(k string, v string) *LogLine { ll.line.Str(k, v); return ll }
func (ll *LogLine) Bool(k string, v bool) *LogLine { ll.line.Bool(k, v); return ll }
func (ll *LogLine) Time(k string, v time.Time) *LogLine { ll.line.Time(k, v); return ll }
func (ll *LogLine) Error(k string, v error) *LogLine { ll.line.Error(k, v); return ll }

// AnyImmutable can be used to log something that is not going to be further modified
// after this call.
Expand All @@ -289,7 +300,7 @@ func (ll LogLine) AnyImmutable(k string, v interface{}) LogLine { ll.line.Any(k,
// Any can be used to log something that might be modified after this call. If any base
// logger does not immediately serialize, then the object will be copied using
// github.com/mohae/deepcopy.Copy()
func (ll LogLine) Any(k string, v interface{}) LogLine {
func (ll *LogLine) Any(k string, v interface{}) *LogLine {
if ll.log.shared.ReferencesKept {
// TODO: make copy function configurable
v = deepcopy.Copy(v)
Expand Down
11 changes: 9 additions & 2 deletions xopbase/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,18 @@ type Span interface {
}

type Line interface {
ObjectParts
// TODO: ExternalReference(name string, itemId string, storageId string)
Msg(string)
// TODO: Guage()
// TODO: Event()

ObjectParts

// Msg may only be called once. After calling Msg, the line
// may not be used for anything else unless Recycle is called.
Msg(string)

// Recycle starts the line ready to use again.
Recycle(xopconst.Level, time.Time)
}

type SubObject interface {
Expand Down
28 changes: 16 additions & 12 deletions xopbase/testlogger/testlogger.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ type Line struct {
Timestamp time.Time
Span *Span
Message string
Completed bool
}

func (l *TestLogger) WithMe() xoplog.SeedModifier {
Expand Down Expand Up @@ -122,17 +121,22 @@ func (s *Span) Line(level xopconst.Level, t time.Time) xopbase.Line {
return line
}

func (l *Line) Any(k string, v interface{}) { l.Things.AnyImmutable(k, v) }
func (l *Line) Int(k string, v int64) { l.Things.Int(k, v) }
func (l *Line) Uint(k string, v uint64) { l.Things.Uint(k, v) }
func (l *Line) Str(k string, v string) { l.Things.Str(k, v) }
func (l *Line) Bool(k string, v bool) { l.Things.Bool(k, v) }
func (l *Line) Error(k string, v error) { l.Things.Error(k, v) }
func (l *Line) Time(k string, v time.Time) { l.Things.Time(k, v) }
func (l Line) Any(k string, v interface{}) { l.Things.AnyImmutable(k, v) }
func (l Line) Int(k string, v int64) { l.Things.Int(k, v) }
func (l Line) Uint(k string, v uint64) { l.Things.Uint(k, v) }
func (l Line) Str(k string, v string) { l.Things.Str(k, v) }
func (l Line) Bool(k string, v bool) { l.Things.Bool(k, v) }
func (l Line) Error(k string, v error) { l.Things.Error(k, v) }
func (l Line) Time(k string, v time.Time) { l.Things.Time(k, v) }
func (l *Line) Recycle(level xopconst.Level, t time.Time) {
l.Level = level
l.Timestamp = t
l.Things = xop.Things{}
l.Message = ""
}

func (l *Line) Msg(m string) {
func (l Line) Msg(m string) {
l.Message = m
l.Completed = true
text := m
// TODO: replace with higher performance version
// TODO: move encoding somewhere else
Expand Down Expand Up @@ -172,6 +176,6 @@ func (l *Line) Msg(m string) {
defer l.Span.testLogger.lock.Unlock()
l.Span.lock.Lock()
defer l.Span.lock.Unlock()
l.Span.testLogger.Lines = append(l.Span.testLogger.Lines, l)
l.Span.Lines = append(l.Span.Lines, l)
l.Span.testLogger.Lines = append(l.Span.testLogger.Lines, &l)
l.Span.Lines = append(l.Span.Lines, &l)
}

0 comments on commit 1b9555b

Please sign in to comment.