log things

master
Jordan Orelli 5 years ago
parent 31ed54c71e
commit bd13f6b43c

@ -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
}

@ -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)

114
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 }) }

@ -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}
}

Loading…
Cancel
Save