diff --git a/log.go b/log.go index 4438edc..8a05c39 100644 --- a/log.go +++ b/log.go @@ -86,10 +86,12 @@ type Logger struct { debug_tmpl *template.Template warn_tmpl *template.Template info_tmpl *template.Template + subs []*Logger } -func Default() *Logger { +func New(name string) *Logger { l := &Logger{ + system: name, err: os.Stderr, out: os.Stdout, color: true, @@ -112,6 +114,10 @@ func (l *Logger) Sub(sys string) *Logger { warn_tmpl: l.warn_tmpl, info_tmpl: l.info_tmpl, } + if l.subs == nil { + l.subs = make([]*Logger, 0) + } + l.subs = append(l.subs, ret) return ret } @@ -134,15 +140,36 @@ func (l *Logger) SetErrOutput(err io.Writer) { l.err = err } +func (l *Logger) SetErrOutputAll(err io.Writer) { + for _, v := range getAllOffsprings(l) { + v.err = err + } +} + func (l *Logger) SetOutput(out io.Writer) { l.out = out } +func (l *Logger) SetOutputAll(out io.Writer) { + for _, v := range getAllOffsprings(l) { + v.out = out + } +} + func (l *Logger) Reload() error { l.guessColor() return l.ParseTmpl() } +func (l *Logger) ReloadAll() error { + for _, v := range getAllOffsprings(l) { + if err := v.Reload(); err != nil { + return err + } + } + return nil +} + func NewLogFormater() *LogFormater { return &LogFormater{ ErrTmplStr: DEFAULT_ERR, @@ -156,7 +183,6 @@ func (l *Logger) DefaultFuncMap() template.FuncMap { funcMap := template.FuncMap{ "Time": func() string { return time.Now().Format("2006/01/02 15:04:05") }, } - setColorMap(funcMap, l.color) return funcMap } @@ -164,22 +190,25 @@ func (l *Logger) ParseTmpl() error { if l.funcMap == nil { l.funcMap = l.DefaultFuncMap() } - err_tmpl, err := template.New("err_tmpl").Funcs(l.funcMap).Parse(l.formatter.ErrTmplStr) + funcMap := copyFuncMap(l.funcMap) + setColorMap(funcMap, l.color) + + err_tmpl, err := template.New("err_tmpl").Funcs(funcMap).Parse(l.formatter.ErrTmplStr) if err != nil { return err } l.err_tmpl = err_tmpl - warn_tmpl, err := template.New("warn_tmpl").Funcs(l.funcMap).Parse(l.formatter.WarnTmplStr) + warn_tmpl, err := template.New("warn_tmpl").Funcs(funcMap).Parse(l.formatter.WarnTmplStr) if err != nil { return err } l.warn_tmpl = warn_tmpl - info_tmpl, err := template.New("info_tmpl").Funcs(l.funcMap).Parse(l.formatter.InfoTmplStr) + info_tmpl, err := template.New("info_tmpl").Funcs(funcMap).Parse(l.formatter.InfoTmplStr) if err != nil { return err } l.info_tmpl = info_tmpl - debug_tmpl, err := template.New("debug_tmpl").Funcs(l.funcMap).Parse(l.formatter.DebugTmplStr) + debug_tmpl, err := template.New("debug_tmpl").Funcs(funcMap).Parse(l.formatter.DebugTmplStr) if err != nil { return err } diff --git a/log_test.go b/log_test.go index b630231..03c12a6 100644 --- a/log_test.go +++ b/log_test.go @@ -1,11 +1,13 @@ package log import ( + "io" "os" "testing" ) func TestDev(t *testing.T) { + LEVEL = Lerror | Ldebug | Lwarn | Linfo PROD = false // log.system = "dev" Error("d", "sdf", "sdfsdf") @@ -97,3 +99,24 @@ func TestToFile(t *testing.T) { l.Info("d", "sdf", "sdfsdf") l.InfoF(H{"Test": "set"}, "d", "sdf", "sdfsdf") } + +func TestApplyChild(t *testing.T) { + PROD = true + l := Sub("parent") + l1 := l.Sub("child1") + l2 := l.Sub("child2") + l3 := l.Sub("child3") + l1.Info("child1") + l2.Info("child2") + l3.Info("child3") + l.SetOutputAll(io.Discard) + l.ReloadAll() + l1.Info("child1-discard") + l2.Info("child2-discard") + l3.Info("child3-discard") + SetOutputAll(os.Stdout) + ReloadAll() + l1.Info("child1-stdout") + l2.Info("child2-stdout") + l3.Info("child3-stdout") +} diff --git a/std.go b/std.go index 9631b95..15568a1 100644 --- a/std.go +++ b/std.go @@ -1,11 +1,41 @@ package log -var std = Default() +import "io" + +var std = New("") func Sub(sys string) *Logger { return std.Sub(sys) } +func SetColor(c bool) { + std.SetColor(c) +} + +func SetErrOutput(err io.Writer) { + std.SetErrOutput(err) +} + +func SetErrOutputAll(err io.Writer) { + std.SetErrOutputAll(err) +} + +func SetOutput(out io.Writer) { + std.SetOutput(out) +} + +func SetOutputAll(out io.Writer) { + std.SetOutputAll(out) +} + +func Reload() error { + return std.Reload() +} + +func ReloadAll() error { + return std.ReloadAll() +} + func ErrorF(fields H, v ...interface{}) { if PROD { std.output(terror, 3, "", fields, v...) diff --git a/util.go b/util.go index 563c4ef..923d8ff 100644 --- a/util.go +++ b/util.go @@ -3,6 +3,7 @@ package log import ( "fmt" "runtime" + "text/template" ) func caller(depth int) string { @@ -27,3 +28,22 @@ func stack() string { buf = make([]byte, 2*len(buf)) } } + +func getAllOffsprings(l *Logger) []*Logger { + if l.subs == nil || len(l.subs) == 0 { + return []*Logger{l} + } + loggers := []*Logger{} + for i := range l.subs { + loggers = append(loggers, getAllOffsprings(l.subs[i])...) + } + return loggers +} + +func copyFuncMap(source template.FuncMap) template.FuncMap { + dest := template.FuncMap{} + for k, v := range source { + dest[k] = v + } + return dest +}