From bd13f6b43c9f522fcfb824b8a54fd477a99129e9 Mon Sep 17 00:00:00 2001 From: Jordan Orelli Date: Tue, 21 Jan 2020 05:34:04 +0000 Subject: [PATCH] log things --- event.go | 12 +++--- line.go | 7 ++++ log.go | 114 ++++++++++++++++++++++++++++++++++++++++++++++--------- tag.go | 24 ------------ 4 files changed, 109 insertions(+), 48 deletions(-) diff --git a/event.go b/event.go index bc140e4..1fceeb1 100644 --- a/event.go +++ b/event.go @@ -11,18 +11,18 @@ import ( // Event is exported to support the implementation of custom log writers. Most // users should not need to handle this type directly. type Event struct { - // severity of the event - Level Level - // time at which the event occured Time time.Time + // severity of the event + Level Level + // where the event occurred in the system Path *Path - // message to be logged - Text string - // key-value pairs to log as extra metadata Tags *Tags + + // message to be logged + Text string } diff --git a/line.go b/line.go index 4a8ea1f..658c1e2 100644 --- a/line.go +++ b/line.go @@ -9,6 +9,10 @@ import ( "time" ) +// LineWriter is an EventWriter that writes one event per line. Event that have +// multiline messages will have the newlines in their messages replaced with \n +// sequences. This is the default EventWriter and is designed to be reasonably +// safe and practical for most users. type LineWriter struct { pool sync.Pool out struct { @@ -70,6 +74,9 @@ func (l *LineWriter) WriteEvent(e *Event) { l.pool.Put(buf) } +// writeTags is a helper for LineWriter's WriteEvent method. writeTags writes +// tags in the order in which they were added to the list of tags; the oldest +// tag is always written first. func writeTags(buf *bytes.Buffer, tags *Tags) { if tags.parent != nil { writeTags(buf, tags.parent) diff --git a/log.go b/log.go index 095d65c..7ed273d 100644 --- a/log.go +++ b/log.go @@ -5,7 +5,6 @@ import ( ) type Log struct { - lvl Level dw EventWriter iw EventWriter ew EventWriter @@ -14,20 +13,14 @@ type Log struct { tags *Tags } -type Options struct { - Debug EventWriter - Info EventWriter - Error EventWriter -} - -var defaults Options - -func init() { - defaults.Debug = NullWriter{} -} - -func NewLog() *Log { - return new(Log) +func NewLog(name string, options ...Option) *Log { + l := &Log{ + path: NewPath(name), + } + for _, opt := range options { + opt.apply(l) + } + return l } func format(t string, args ...interface{}) string { @@ -37,19 +30,104 @@ func format(t string, args ...interface{}) string { return fmt.Sprintf(t, args...) } +func (l *Log) event(lvl Level, t string, args ...interface{}) *Event { + return &Event{ + Time: l.clock.Now(), + Level: lvl, + Path: l.path, + Tags: l.tags, + Text: format(t, args...), + } +} + func (l *Log) Debug(t string, args ...interface{}) { + if l.dw != nil { + l.dw.WriteEvent(l.event(Debug, t, args...)) + } } func (l *Log) Info(t string, args ...interface{}) { + if l.iw != nil { + l.iw.WriteEvent(l.event(Info, t, args...)) + } } func (l *Log) Error(t string, args ...interface{}) { + if l.ew != nil { + l.ew.WriteEvent(l.event(Error, t, args...)) + } } func (l *Log) Child(name string) *Log { - return l + return &Log{ + dw: l.dw, + iw: l.iw, + ew: l.ew, + path: l.path.Child(name), + clock: l.clock, + tags: l.tags, + } } -func (l *Log) Tag(key string, value interface{}) *Log { - return l +// Tag creates a new Tags struct having the given key as its final key, with no +// associated value. All existing keys continue to exist. +func (l *Log) Tag(key string) *Log { + return &Log{ + dw: l.dw, + iw: l.iw, + ew: l.ew, + path: l.path, + clock: l.clock, + tags: &Tags{key: key, parent: l.tags}, + } +} + +// TagInt creates a new Tags struct having the given key-value pair as the +// final key-value pair. All existing key-value pairs continue to exist. +func (l *Log) TagInt(key string, v int) *Log { + return &Log{ + dw: l.dw, + iw: l.iw, + ew: l.ew, + path: l.path, + clock: l.clock, + tags: &Tags{key: key, value: v, parent: l.tags}, + } +} + +// TagString creates a new Tags struct having the given key-value pair as the +// final key-value pair. All existing key-value pairs continue to exist. +func (l *Log) TagString(key, v string) *Log { + return &Log{ + dw: l.dw, + iw: l.iw, + ew: l.ew, + path: l.path, + clock: l.clock, + tags: &Tags{key: key, value: v, parent: l.tags}, + } } + +// TagFloat creates a new Tags struct having the given key-value pair as the +// final key-value pair. All existing key-value pairs continue to exist. +func (l *Log) TagFloat(key string, v float64) *Log { + return &Log{ + dw: l.dw, + iw: l.iw, + ew: l.ew, + path: l.path, + clock: l.clock, + tags: &Tags{key: key, value: v, parent: l.tags}, + } +} + +type Option interface{ apply(*Log) } + +type optionFn func(*Log) + +func (fn optionFn) apply(l *Log) { fn(l) } + +func DebugWriter(w EventWriter) Option { return optionFn(func(l *Log) { l.dw = w }) } +func InfoWriter(w EventWriter) Option { return optionFn(func(l *Log) { l.iw = w }) } +func ErrorWriter(w EventWriter) Option { return optionFn(func(l *Log) { l.ew = w }) } +func UserClock(c Clock) Option { return optionFn(func(l *Log) { l.clock = c }) } diff --git a/tag.go b/tag.go index 6e8c3e8..b658abb 100644 --- a/tag.go +++ b/tag.go @@ -13,27 +13,3 @@ type Tags struct { value interface{} parent *Tags } - -// Tag creates a new Tags struct having the given key as its final key, with no -// associated value. All existing keys continue to exist. -func (t *Tags) Tag(key string) *Tags { - return &Tags{key: key, parent: t} -} - -// TagInt creates a new Tags struct having the given key-value pair as the -// final key-value pair. All existing key-value pairs continue to exist. -func (t *Tags) TagInt(key string, v int) *Tags { - return &Tags{key: key, value: v, parent: t} -} - -// TagString creates a new Tags struct having the given key-value pair as the -// final key-value pair. All existing key-value pairs continue to exist. -func (t *Tags) TagString(key, v string) *Tags { - return &Tags{key: key, value: v, parent: t} -} - -// TagFloat creates a new Tags struct having the given key-value pair as the -// final key-value pair. All existing key-value pairs continue to exist. -func (t *Tags) TagFloat(key string, v float64) *Tags { - return &Tags{key: key, value: v, parent: t} -}