diff --git a/color.go b/color.go index 53d6674..5d0332a 100644 --- a/color.go +++ b/color.go @@ -12,41 +12,40 @@ func (l *Logger) M(s interface{}, attrs ...color.Attribute) string { if !l.color { return fmt.Sprint(s) } - style := "" + styles := "" for i, v := range attrs { if i >= 3 { break } if i > 0 { - style += ";" + styles += ";" } - style = style + strconv.Itoa(int(v)) + styles = styles + strconv.Itoa(int(v)) } - return fmt.Sprintf("\033[%sm%s\033[0m", style, s) + return fmt.Sprintf("\033[%sm%s\033[0m", styles, s) } -func setColorMap(funcMap template.FuncMap, color bool) { - if color { - funcMap["red"] = func() string { return "\033[91m" } - funcMap["redl"] = func() string { return "\033[31m" } - funcMap["green"] = func() string { return "\033[92m" } - funcMap["yellow"] = func() string { return "\033[93m" } - funcMap["blue"] = func() string { return "\033[94m" } - funcMap["magenta"] = func() string { return "\033[95m" } - funcMap["cyan"] = func() string { return "\033[96m" } - funcMap["white"] = func() string { return "\033[97m" } - funcMap["reset"] = func() string { return "\033[0m" } +func (l *Logger) setColorMap(funcMap template.FuncMap) { + funcMap["M"] = l.M + if l.color { + funcMap["red"] = func(s interface{}) string { return fmt.Sprintf("\033[91m%s\033[0m", s) } + funcMap["redl"] = func(s interface{}) string { return fmt.Sprintf("\033[31m%s\033[0m", s) } + funcMap["green"] = func(s interface{}) string { return fmt.Sprintf("\033[92m%s\033[0m", s) } + funcMap["yellow"] = func(s interface{}) string { return fmt.Sprintf("\033[93m%s\033[0m", s) } + funcMap["blue"] = func(s interface{}) string { return fmt.Sprintf("\033[94m%s\033[0m", s) } + funcMap["magenta"] = func(s interface{}) string { return fmt.Sprintf("\033[95m%s\033[0m", s) } + funcMap["cyan"] = func(s interface{}) string { return fmt.Sprintf("\033[96m%s\033[0m", s) } + funcMap["white"] = func(s interface{}) string { return fmt.Sprintf("\033[97m%s\033[0m", s) } return } - funcMap["red"] = func() string { return "" } - funcMap["redl"] = func() string { return "" } - funcMap["green"] = func() string { return "" } - funcMap["yellow"] = func() string { return "" } - funcMap["blue"] = func() string { return "" } - funcMap["magenta"] = func() string { return "" } - funcMap["cyan"] = func() string { return "" } - funcMap["white"] = func() string { return "" } - funcMap["reset"] = func() string { return "" } + funcMap["red"] = func(s string) string { return s } + funcMap["redl"] = func(s string) string { return s } + funcMap["green"] = func(s string) string { return s } + funcMap["yellow"] = func(s string) string { return s } + funcMap["blue"] = func(s string) string { return s } + funcMap["magenta"] = func(s string) string { return s } + funcMap["cyan"] = func(s string) string { return s } + funcMap["white"] = func(s string) string { return s } } // func diff --git a/log.go b/log.go index 5d307b4..4e4cadb 100644 --- a/log.go +++ b/log.go @@ -1,6 +1,7 @@ package log import ( + "encoding/json" "fmt" "io" "os" @@ -33,24 +34,24 @@ var PROD = true var LEVEL = Lerror | Linfo const ( - DEFAULT_ERR = `{{Time}} [{{red}}ERROR{{reset}}]` + - `{{if .System}}({{cyan}}{{.System}}{{reset}}){{end}} ` + - `{{.Caller}} {{.Message}}{{"\n"}}` + - `{{if .Fields}}{{printf "%v\n" .Fields}}{{end}}` + - `{{if .Stack}}{{redl}}{{.Stack}}{{reset}}{{end}}` - DEFAULT_DEBUG = `{{Time}} [{{magenta}}DEBUG{{reset}}]` + - `{{if .System}}({{cyan}}{{.System}}{{reset}}){{end}} ` + - `{{.Caller}} {{.Message}}{{"\n"}}` + - `{{if .Fields}}{{green}}{{printf "%v\n" .Fields}}{{reset}}{{end}}` + - `{{if .Stack}}{{redl}}{{.Stack}}{{reset}}{{end}}` - DEFAULT_WARN = `{{Time}} [{{yellow}}WARN {{reset}}]` + - `{{if .System}}({{cyan}}{{.System}}{{reset}}){{end}} ` + - `{{.Message}}{{"\n"}}` + - `{{if .Fields}}{{green}}{{printf "%v\n" .Fields}}{{reset}}{{end}}` - DEFAULT_INFO = `{{Time}} [{{blue}}INFO {{reset}}]` + - `{{if .System}}({{cyan}}{{.System}}{{reset}}){{end}} ` + - `{{.Message}}{{"\n"}}` + - `{{if .Fields}}{{green}}{{printf "%v\n" .Fields}}{{reset}}{{end}}` + DEFAULT_ERR = `{{Time}} [{{"ERROR"|red}}]` + + `{{if .System}}({{.System|cyan}}){{end}} ` + + `{{.Caller}} {{.Message}}` + + `{{if .Fields}} {{.Fields|json|green}}{{end}}{{"\n"}}` + + `{{if .Stack}}{{.Stack|redl}}{{end}}` + DEFAULT_DEBUG = `{{Time}} [{{"DEBUG"|magenta}}]` + + `{{if .System}}({{.System|cyan}}){{end}} ` + + `{{.Caller}} {{.Message}}` + + `{{if .Fields}} {{.Fields|json|green}}{{end}}{{"\n"}}` + + `{{if .Stack}}{{.Stack|redl}}{{end}}` + DEFAULT_WARN = `{{Time}} [{{"WARN"|yellow}} ]` + + `{{if .System}}({{.System|cyan}}){{end}} ` + + `{{.Message}}` + + `{{if .Fields}} {{.Fields|json|green}}{{end}}{{"\n"}}` + DEFAULT_INFO = `{{Time}} [{{"INFO"|blue}} ]` + + `{{if .System}}({{.System|cyan}}){{end}} ` + + `{{.Message}}` + + `{{if .Fields}} {{.Fields|json|green}}{{end}}{{"\n"}}` ) type LogFormater struct { @@ -196,6 +197,7 @@ func NewLogFormater() *LogFormater { func (l *Logger) DefaultFuncMap() template.FuncMap { funcMap := template.FuncMap{ "Time": func() string { return time.Now().Format("2006/01/02 15:04:05") }, + "json": func(i interface{}) (string, error) { r, err := json.Marshal(i); return string(r), err }, } return funcMap } @@ -205,7 +207,7 @@ func (l *Logger) ParseTmpl() error { l.funcMap = l.DefaultFuncMap() } funcMap := copyFuncMap(l.funcMap) - setColorMap(funcMap, l.color) + l.setColorMap(funcMap) err_tmpl, err := template.New("err_tmpl").Funcs(funcMap).Parse(l.formatter.ErrTmplStr) if err != nil { diff --git a/log_test.go b/log_test.go index b9c72fd..e7ae661 100644 --- a/log_test.go +++ b/log_test.go @@ -12,78 +12,86 @@ func TestDev(t *testing.T) { LEVEL = Lerror | Ldebug | Lwarn | Linfo PROD = false // log.system = "dev" - Error("d", "sdf", "sdfsdf") - ErrorF(H{"Test": "set"}, "d", "sdf", "sdfsdf") - Debug("d", "sdf", "sdfsdf") - DebugF(H{"Test": "set"}, "d", "sdf", "sdfsdf") - Warn("d", "sdf", "sdfsdf") - WarnF(H{"Test": "set"}, "d", "sdf", "sdfsdf") - Info("d", "sdf", "sdfsdf") - InfoF(H{"Test": "set"}, "d", "sdf", "sdfsdf") + Error("TestDev") + ErrorF(H{"Test": "set"}, "TestDev") + Debug("TestDev") + DebugF(H{"Test": "set"}, "TestDev") + Warn("TestDev") + WarnF(H{"Test": "set"}, "TestDev") + Info("TestDev") + InfoF(H{"Test": "set"}, "TestDev") } func TestProd(t *testing.T) { PROD = true // log.system = "prod" - Error("d", "sdf", "sdfsdf") - ErrorF(H{"Test": "set"}, "d", "sdf", "sdfsdf") - Debug("d", "sdf", "sdfsdf") - DebugF(H{"Test": "set"}, "d", "sdf", "sdfsdf") - Warn("d", "sdf", "sdfsdf") - WarnF(H{"Test": "set"}, "d", "sdf", "sdfsdf") - Info("d", "sdf", "sdfsdf") - InfoF(H{"Test": "set"}, "d", "sdf", "sdfsdf") + Error("TestProd") + ErrorF(H{"Test": "set"}, "TestProd") + Debug("TestProd") + DebugF(H{"Test": "set"}, "TestProd") + Warn("TestProd") + WarnF(H{"Test": "set"}, "TestProd") + Info("TestProd") + InfoF(H{"Test": "set"}, "TestProd") } func TestSubDev(t *testing.T) { PROD = false l := Sub("TestSubDev") - l.Error("d", "sdf", "sdfsdf") - l.ErrorF(H{"Test": "set"}, "d", "sdf", "sdfsdf") - l.Debug("d", "sdf", "sdfsdf") - l.DebugF(H{"Test": "set"}, "d", "sdf", "sdfsdf") - l.Warn("d", "sdf", "sdfsdf") - l.WarnF(H{"Test": "set"}, "d", "sdf", "sdfsdf") - l.Info("d", "sdf", "sdfsdf") - l.InfoF(H{"Test": "set"}, "d", "sdf", "sdfsdf") + l.Error("TestSubDev") + l.ErrorF(H{"Test": "set"}, "TestSubDev") + l.Debug("TestSubDev") + l.DebugF(H{"Test": "set"}, "TestSubDev") + l.Warn("TestSubDev") + l.WarnF(H{"Test": "set"}, "TestSubDev") + l.Info("TestSubDev") + l.InfoF(H{"Test": "set"}, "TestSubDev") } func TestSubProd(t *testing.T) { PROD = true l := Sub("TestSubProd") - l.Error("d", "sdf", "sdfsdf") - l.ErrorF(H{"Test": "set"}, "d", "sdf", "sdfsdf") - l.Debug("d", "sdf", "sdfsdf") - l.DebugF(H{"Test": "set"}, "d", "sdf", "sdfsdf") - l.Warn("d", "sdf", "sdfsdf") - l.WarnF(H{"Test": "set"}, "d", "sdf", "sdfsdf") - l.Info("d", "sdf", "sdfsdf") - l.InfoF(H{"Test": "set"}, "d", "sdf", "sdfsdf") + l.Error("TestSubProd") + l.ErrorF(H{"Test": "set"}, "TestSubProd") + l.Debug("TestSubProd") + l.DebugF(H{"Test": "set"}, "TestSubProd") + l.Warn("TestSubProd") + l.WarnF(H{"Test": "set"}, "TestSubProd") + l.Info("TestSubProd") + l.InfoF(H{"Test": "set"}, "TestSubProd") } func TestCustTmpl(t *testing.T) { PROD = true l := Sub("TestCustTmpl") CustFormater := NewLogFormater() - CustFormater.InfoTmplStr = `{{Time}} [{{blue}}INFO {{reset}}]` + - `{{if .System}}({{cyan}}{{.System}}{{reset}}){{end}} ` + - `key: test, value:{{.Fields.Test}}{{"\n"}}` + CustFormater.InfoTmplStr = `{{Time}} [{{ M "INFO" 104 93 9}} ]` + + `{{if .System}}({{M .System 96}}){{end}} ` + + `Hello, {{.Fields.Name}}. {{.Message}}{{"\n"}}` + CustFormater.ErrTmplStr = `{{Time}} [{{ M "ERROR" 91 43 1}}]` + + `{{if .System}}({{M .System 96}}){{end}} ` + + `NO! {{.Fields.Name}} {{M .Message 31 3}} {{"\n"}}` l.SetTmpl(CustFormater, nil) l.Reload() - l.Error("d", "sdf", "sdfsdf") - l.ErrorF(H{"Test": "set"}, "d", "sdf", "sdfsdf") - l.Debug("d", "sdf", "sdfsdf") - l.DebugF(H{"Test": "set"}, "d", "sdf", "sdfsdf") - l.Warn("d", "sdf", "sdfsdf") - l.WarnF(H{"Test": "set"}, "d", "sdf", "sdfsdf") - l.Info("d", "sdf", "sdfsdf") - l.InfoF(H{"Test": "set"}, "d", "sdf", "sdfsdf") + l.ErrorF(H{"Name": "Brandon"}, "TestCustTmpl") + l.InfoF(H{"Name": "Brandon"}, "TestCustTmpl") + + SetTmpl(CustFormater, nil) + Reload() + + ErrorF(H{"Name": "Brandon"}, "TestCustTmpl std") + InfoF(H{"Name": "Brandon"}, "TestCustTmpl std") + + //reset + SetTmpl(NewLogFormater(), nil) + Reload() } func TestColoring(t *testing.T) { l := Sub("color") l.Error(l.M("Hello", c.BgHiGreen, c.Italic, c.FgWhite), ", ", l.M("world", c.FgBlue, c.BgHiYellow)) l.Error(l.M("Hello", c.FgHiGreen), ", ", l.M("world", c.Underline, c.FgMagenta)) + Error(M("Hello", c.FgHiGreen), ", ", M("world", c.Underline, c.FgMagenta)) } func TestToFile(t *testing.T) { @@ -98,25 +106,17 @@ func TestToFile(t *testing.T) { l.SetErrOutput(f) l.Reload() - l.Error("d", "sdf", "sdfsdf") - l.ErrorF(H{"Test": "set"}, "d", "sdf", "sdfsdf") - l.Debug("d", "sdf", "sdfsdf") - l.DebugF(H{"Test": "set"}, "d", "sdf", "sdfsdf") - l.Warn("d", "sdf", "sdfsdf") - l.WarnF(H{"Test": "set"}, "d", "sdf", "sdfsdf") - l.Info("d", "sdf", "sdfsdf") - l.InfoF(H{"Test": "set"}, "d", "sdf", "sdfsdf") + l.Error("TestToFile") + l.Debug("TestToFile") + l.Warn("TestToFile") + l.Info("TestToFile") l.SetColor(true) l.Reload() - l.Error("d", "sdf", "sdfsdf") - l.ErrorF(H{"Test": "set"}, "d", "sdf", "sdfsdf") - l.Debug("d", "sdf", "sdfsdf") - l.DebugF(H{"Test": "set"}, "d", "sdf", "sdfsdf") - l.Warn("d", "sdf", "sdfsdf") - l.WarnF(H{"Test": "set"}, "d", "sdf", "sdfsdf") - l.Info("d", "sdf", "sdfsdf") - l.InfoF(H{"Test": "set"}, "d", "sdf", "sdfsdf") + l.Error("TestToFile colored") + l.Debug("TestToFile colored") + l.Warn("TestToFile colored") + l.Info("TestToFile colored") } func TestApplyChild(t *testing.T) { diff --git a/std.go b/std.go index c8335bf..aee43b5 100644 --- a/std.go +++ b/std.go @@ -1,9 +1,18 @@ package log -import "io" +import ( + "io" + "text/template" + + "kumoly.io/core/log/color" +) var std = New("") +func M(s interface{}, attrs ...color.Attribute) string { + return std.M(s, attrs...) +} + func Sub(sys string) *Logger { return std.Sub(sys) } @@ -40,6 +49,18 @@ func ReloadAll() error { return std.ReloadAll() } +func DefaultFuncMap() template.FuncMap { + return std.DefaultFuncMap() +} + +func ParseTmpl() error { + return std.ParseTmpl() +} + +func SetTmpl(formatter *LogFormater, funcMap template.FuncMap) { + std.SetTmpl(formatter, funcMap) +} + func ErrorF(fields H, v ...interface{}) { if PROD { std.output(terror, 3, "", fields, v...)