|
|
|
package blammo
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Log struct {
|
|
|
|
dw EventWriter
|
|
|
|
iw EventWriter
|
|
|
|
ew EventWriter
|
|
|
|
path *Path
|
|
|
|
clock Clock
|
|
|
|
tags *Tags
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewLog(name string, options ...Option) *Log {
|
|
|
|
l := &Log{
|
|
|
|
path: NewPath(name),
|
|
|
|
clock: SystemClock{},
|
|
|
|
}
|
|
|
|
for _, opt := range options {
|
|
|
|
opt.apply(l)
|
|
|
|
}
|
|
|
|
return l
|
|
|
|
}
|
|
|
|
|
|
|
|
func format(t string, args ...interface{}) string {
|
|
|
|
if len(args) == 0 {
|
|
|
|
return t
|
|
|
|
}
|
|
|
|
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 &Log{
|
|
|
|
dw: l.dw,
|
|
|
|
iw: l.iw,
|
|
|
|
ew: l.ew,
|
|
|
|
path: l.path.Child(name),
|
|
|
|
clock: l.clock,
|
|
|
|
tags: l.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 (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 }) }
|