From 9ad94eccad50bfd99202542617d0125c7bef36fd Mon Sep 17 00:00:00 2001 From: John Date: Sat, 1 Jun 2019 11:01:57 +0800 Subject: [PATCH] add json output support for glog --- g/os/glog/glog_logger.go | 117 +++++++++++++++++++--------------- g/os/glog/glog_logger_api.go | 118 +++++++++++++++++------------------ g/util/gconv/gconv.go | 1 + geg/os/glog/glog_category.go | 2 +- geg/os/glog/glog_debug.go | 3 +- geg/os/glog/glog_json.go | 16 +++++ 6 files changed, 145 insertions(+), 112 deletions(-) create mode 100644 geg/os/glog/glog_json.go diff --git a/g/os/glog/glog_logger.go b/g/os/glog/glog_logger.go index 6a9379d59..f0620fe11 100644 --- a/g/os/glog/glog_logger.go +++ b/g/os/glog/glog_logger.go @@ -3,8 +3,6 @@ // This Source Code Form is subject to the terms of the MIT License. // If a copy of the MIT was not distributed with this file, // You can obtain one at https://github.com/gogf/gf. -// -// @author john, zseeker package glog @@ -16,6 +14,7 @@ import ( "github.com/gogf/gf/g/os/gfpool" "github.com/gogf/gf/g/os/gtime" "github.com/gogf/gf/g/text/gregex" + "github.com/gogf/gf/g/util/gconv" "io" "os" "runtime" @@ -80,19 +79,10 @@ func New() *Logger { // Clone returns a new logger, which is the clone the current logger. func (l *Logger) Clone() *Logger { - logger := &Logger { - parent : l, - path : l.path, - file : l.file, - level : l.level, - flags : l.flags, - prefix : l.prefix, - btSkip : l.btSkip, - btStatus : l.btStatus, - headerPrint : l.headerPrint, - stdoutPrint : l.stdoutPrint, - } - return logger + logger := Logger{} + logger = *l + logger.parent = l + return &logger } // SetLevel sets the logging level. @@ -226,67 +216,98 @@ func (l *Logger) SetPrefix(prefix string) { } // print prints to defined writer, logging file or passed . -func (l *Logger) print(std io.Writer, s string) { - // Custom writer has the most high priority. +func (l *Logger) print(std io.Writer, level string, format string, value...interface{}) { + buffer := bytes.NewBuffer(nil) if l.headerPrint { - s = l.format(s) + // Time. + timeFormat := "" + if l.flags & F_TIME_DATE > 0 { + timeFormat += "2006-01-02 " + } + if l.flags & F_TIME_TIME > 0 { + timeFormat += "15:04:05 " + } + if l.flags & F_TIME_MILLI > 0 { + timeFormat += "15:04:05.000 " + } + if len(timeFormat) > 0 { + buffer.WriteString(time.Now().Format(timeFormat)) + } + // Caller path. + callerPath := "" + if l.flags & F_FILE_LONG > 0 { + callerPath = l.getLongFile() + ": " + } + if l.flags & F_FILE_SHORT > 0 { + callerPath = gfile.Basename(l.getLongFile()) + ": " + } + if len(callerPath) > 0 { + buffer.WriteString(callerPath) + } + // Prefix. + if len(l.prefix) > 0 { + buffer.WriteString(l.prefix + " ") + } } + if len(level) > 0 { + buffer.WriteString(level + " ") + } + if len(format) > 0 { + buffer.WriteString(fmt.Sprintf(format, value...)) + } else { + for k, v := range value { + if k > 0 { + buffer.WriteByte(' ') + } + buffer.WriteString(gconv.String(v)) + } + } + buffer.WriteString(ln) + if l.writer == nil { if f := l.getFilePointer(); f != nil { defer f.Close() - if _, err := io.WriteString(f, s); err != nil { + if _, err := io.WriteString(f, buffer.String()); err != nil { fmt.Fprintln(os.Stderr, err.Error()) } } // Allow output to stdout? if l.stdoutPrint { - if _, err := std.Write([]byte(s)); err != nil { + if _, err := std.Write(buffer.Bytes()); err != nil { fmt.Fprintln(os.Stderr, err.Error()) } } } else { - if _, err := l.writer.Write([]byte(s)); err != nil { + if _, err := l.writer.Write(buffer.Bytes()); err != nil { fmt.Fprintln(os.Stderr, err.Error()) } } } // printStd prints content without backtrace. -func (l *Logger) printStd(s string) { - l.print(os.Stdout, s) +func (l *Logger) printStd(level string, format string, value...interface{}) { + l.print(os.Stdout, level, "", value...) } // printStd prints content with backtrace check. -func (l *Logger) printErr(s string) { +func (l *Logger) printErr(level string, format string, value...interface{}) { if l.btStatus == 1 { - s = l.appendBacktrace(s) + if s := l.GetBacktrace(); s != "" { + value = append(value, ln + "Backtrace:" + ln + s) + } } // In matter of sequence, do not use stderr here, but use the same stdout. - l.print(os.Stdout, s) -} - -// appendBacktrace appends backtrace to the . -func (l *Logger) appendBacktrace(s string, skip...int) string { - trace := l.GetBacktrace(skip...) - if trace != "" { - backtrace := "Backtrace:" + ln + trace - if len(s) > 0 { - if s[len(s)-1] == byte('\n') { - s = s + backtrace + ln - } else { - s = s + ln + backtrace + ln - } - } else { - s = backtrace - } - } - return s + l.print(os.Stdout, level, format, value...) } // PrintBacktrace prints the caller backtrace, // the optional parameter specify the skipped backtrace offset from the end point. func (l *Logger) PrintBacktrace(skip...int) { - l.Println(l.appendBacktrace("", skip...)) + if s := l.GetBacktrace(skip...); s != "" { + l.Println("Backtrace:" + ln + s) + } else { + l.Println() + } } // GetBacktrace returns the caller backtrace content, @@ -350,8 +371,8 @@ func (l *Logger) getLongFile() string { } -// format formats the content according the flags. -func (l *Logger) format(content string) string { +// header returns the header according logger's settings. +func (l *Logger) header() string { buffer := bytes.NewBuffer(nil) // Time. timeFormat := "" @@ -382,8 +403,6 @@ func (l *Logger) format(content string) string { if len(l.prefix) > 0 { buffer.WriteString(l.prefix + " ") } - // Content. - buffer.WriteString(content) return buffer.String() } diff --git a/g/os/glog/glog_logger_api.go b/g/os/glog/glog_logger_api.go index 9ef5c0c2a..a77bd1442 100644 --- a/g/os/glog/glog_logger_api.go +++ b/g/os/glog/glog_logger_api.go @@ -13,205 +13,201 @@ import ( // Print prints with newline using fmt.Sprintln. // The param can be multiple variables. -func (l *Logger) Print(v ...interface{}) { - l.printStd(fmt.Sprintln(v...)) +func (l *Logger) Print(v...interface{}) { + l.printStd("", "", v...) } // Printf prints with format using fmt.Sprintf. // The param can be multiple variables. -func (l *Logger) Printf(format string, v ...interface{}) { - l.printStd(fmt.Sprintf(format + ln, v...)) +func (l *Logger) Printf(format string, v...interface{}) { + l.printStd("", format, v...) } // See Print. -func (l *Logger) Println(v ...interface{}) { +func (l *Logger) Println(v...interface{}) { l.Print(v...) } // Deprecated. // Use Printf instead. -func (l *Logger) Printfln(format string, v ...interface{}) { - l.printStd(fmt.Sprintf(format + ln, v...)) +func (l *Logger) Printfln(format string, v...interface{}) { + l.printStd("", format, v...) } // Fatal prints the logging content with [FATA] header and newline, then exit the current process. -func (l *Logger) Fatal(v ...interface{}) { - l.printErr("[FATA] " + fmt.Sprintln(v...)) +func (l *Logger) Fatal(v...interface{}) { + l.printErr("[FATA]", "", v...) os.Exit(1) } // Fatalf prints the logging content with [FATA] header, custom format and newline, then exit the current process. -func (l *Logger) Fatalf(format string, v ...interface{}) { - l.printErr("[FATA] " + fmt.Sprintf(format + ln, v...)) +func (l *Logger) Fatalf(format string, v...interface{}) { + l.printErr("[FATA]", format, v...) os.Exit(1) } // Deprecated. // Use Fatalf instead. -func (l *Logger) Fatalfln(format string, v ...interface{}) { - l.printErr("[FATA] " + fmt.Sprintf(format + ln, v...)) +func (l *Logger) Fatalfln(format string, v...interface{}) { + l.Fatalf(format, v...) os.Exit(1) } // Panic prints the logging content with [PANI] header and newline, then panics. -func (l *Logger) Panic(v ...interface{}) { - s := fmt.Sprintln(v...) - l.printErr("[PANI] " + s) - panic(s) +func (l *Logger) Panic(v...interface{}) { + l.printErr("[PANI]", "", v...) + panic(fmt.Sprint(v...)) } // Panicf prints the logging content with [PANI] header, custom format and newline, then panics. -func (l *Logger) Panicf(format string, v ...interface{}) { - s := fmt.Sprintf(format + ln, v...) - l.printErr("[PANI] " + s) - panic(s) +func (l *Logger) Panicf(format string, v...interface{}) { + l.printErr("[PANI]", format, v...) + panic(fmt.Sprintf(format, v...)) } // Deprecated. // Use Panicf instead. -func (l *Logger) Panicfln(format string, v ...interface{}) { - s := fmt.Sprintf(format + ln, v...) - l.printErr("[PANI] " + s) - panic(s) +func (l *Logger) Panicfln(format string, v...interface{}) { + l.Panicf(format, v...) } // Info prints the logging content with [INFO] header and newline. -func (l *Logger) Info(v ...interface{}) { +func (l *Logger) Info(v...interface{}) { if l.checkLevel(LEVEL_INFO) { - l.printStd("[INFO] " + fmt.Sprintln(v...)) + l.printStd("[INFO]", "", v...) } } // Infof prints the logging content with [INFO] header, custom format and newline. -func (l *Logger) Infof(format string, v ...interface{}) { +func (l *Logger) Infof(format string, v...interface{}) { if l.checkLevel(LEVEL_INFO) { - l.printStd("[INFO] " + fmt.Sprintf(format + ln, v...)) + l.printStd("[INFO]", format, v...) } } // Deprecated. // Use Infof instead. -func (l *Logger) Infofln(format string, v ...interface{}) { +func (l *Logger) Infofln(format string, v...interface{}) { if l.checkLevel(LEVEL_INFO) { - l.printStd("[INFO] " + fmt.Sprintf(format + ln, v...) + ln) + l.Infof(format, v...) } } // Debug prints the logging content with [DEBU] header and newline. -func (l *Logger) Debug(v ...interface{}) { +func (l *Logger) Debug(v...interface{}) { if l.checkLevel(LEVEL_DEBU) { - l.printStd("[DEBU] " + fmt.Sprintln(v...)) + l.printStd("[DEBU]", "", v...) } } // Debugf prints the logging content with [DEBU] header, custom format and newline. -func (l *Logger) Debugf(format string, v ...interface{}) { +func (l *Logger) Debugf(format string, v...interface{}) { if l.checkLevel(LEVEL_DEBU) { - l.printStd("[DEBU] " + fmt.Sprintf(format + ln, v...)) + l.printStd("[DEBU]", format, v...) } } // Deprecated. // Use Debugf instead. -func (l *Logger) Debugfln(format string, v ...interface{}) { +func (l *Logger) Debugfln(format string, v...interface{}) { if l.checkLevel(LEVEL_DEBU) { - l.printStd("[DEBU] " + fmt.Sprintf(format + ln, v...) + ln) + l.Debugf(format, v...) } } // Notice prints the logging content with [NOTI] header and newline. // It also prints caller backtrace info if backtrace feature is enabled. -func (l *Logger) Notice(v ...interface{}) { +func (l *Logger) Notice(v...interface{}) { if l.checkLevel(LEVEL_NOTI) { - l.printErr("[NOTI] " + fmt.Sprintln(v...)) + l.printErr("[NOTI]", "", v...) } } // Noticef prints the logging content with [NOTI] header, custom format and newline. // It also prints caller backtrace info if backtrace feature is enabled. -func (l *Logger) Noticef(format string, v ...interface{}) { +func (l *Logger) Noticef(format string, v...interface{}) { if l.checkLevel(LEVEL_NOTI) { - l.printErr("[NOTI] " + fmt.Sprintf(format + ln, v...)) + l.printErr("[NOTI]", format, v...) } } // Deprecated. // Use Noticef instead. -func (l *Logger) Noticefln(format string, v ...interface{}) { +func (l *Logger) Noticefln(format string, v...interface{}) { if l.checkLevel(LEVEL_NOTI) { - l.printErr("[NOTI] " + fmt.Sprintf(format + ln, v...) + ln) + l.Noticef(format, v...) } } // Warning prints the logging content with [WARN] header and newline. // It also prints caller backtrace info if backtrace feature is enabled. -func (l *Logger) Warning(v ...interface{}) { +func (l *Logger) Warning(v...interface{}) { if l.checkLevel(LEVEL_WARN) { - l.printErr("[WARN] " + fmt.Sprintln(v...)) + l.printErr("[WARN]", "", v...) } } // Warningf prints the logging content with [WARN] header, custom format and newline. // It also prints caller backtrace info if backtrace feature is enabled. -func (l *Logger) Warningf(format string, v ...interface{}) { +func (l *Logger) Warningf(format string, v...interface{}) { if l.checkLevel(LEVEL_WARN) { - l.printErr("[WARN] " + fmt.Sprintf(format + ln, v...)) + l.printErr("[WARN]", format, v...) } } // Deprecated. // Use Warningf instead. -func (l *Logger) Warningfln(format string, v ...interface{}) { +func (l *Logger) Warningfln(format string, v...interface{}) { if l.checkLevel(LEVEL_WARN) { - l.printErr("[WARN] " + fmt.Sprintf(format + ln, v...) + ln) + l.Warningf(format, v...) } } // Error prints the logging content with [ERRO] header and newline. // It also prints caller backtrace info if backtrace feature is enabled. -func (l *Logger) Error(v ...interface{}) { +func (l *Logger) Error(v...interface{}) { if l.checkLevel(LEVEL_ERRO) { - l.printErr("[ERRO] " + fmt.Sprintln(v...)) + l.printErr("[ERRO]", "", v...) } } // Errorf prints the logging content with [ERRO] header, custom format and newline. // It also prints caller backtrace info if backtrace feature is enabled. -func (l *Logger) Errorf(format string, v ...interface{}) { +func (l *Logger) Errorf(format string, v...interface{}) { if l.checkLevel(LEVEL_ERRO) { - l.printErr("[ERRO] " + fmt.Sprintf(format + ln, v...)) + l.printErr("[ERRO]", format, v...) } } // Deprecated. // Use Errorf instead. -func (l *Logger) Errorfln(format string, v ...interface{}) { +func (l *Logger) Errorfln(format string, v...interface{}) { if l.checkLevel(LEVEL_ERRO) { - l.printErr("[ERRO] " + fmt.Sprintf(format + ln, v...) + ln) + l.Errorf(format, v...) } } // Critical prints the logging content with [CRIT] header and newline. // It also prints caller backtrace info if backtrace feature is enabled. -func (l *Logger) Critical(v ...interface{}) { +func (l *Logger) Critical(v...interface{}) { if l.checkLevel(LEVEL_CRIT) { - l.printErr("[CRIT] " + fmt.Sprintln(v...)) + l.printErr("[CRIT]", "", v...) } } // Criticalf prints the logging content with [CRIT] header, custom format and newline. // It also prints caller backtrace info if backtrace feature is enabled. -func (l *Logger) Criticalf(format string, v ...interface{}) { +func (l *Logger) Criticalf(format string, v...interface{}) { if l.checkLevel(LEVEL_CRIT) { - l.printErr("[CRIT] " + fmt.Sprintf(format + ln, v...)) + l.printErr("[CRIT]", format, v...) } } // Deprecated. // Use Criticalf instead. -func (l *Logger) Criticalfln(format string, v ...interface{}) { +func (l *Logger) Criticalfln(format string, v...interface{}) { if l.checkLevel(LEVEL_CRIT) { - l.printErr("[CRIT] " + fmt.Sprintf(format + ln, v...) + ln) + l.Criticalf(format, v...) } } diff --git a/g/util/gconv/gconv.go b/g/util/gconv/gconv.go index af64db5c3..6b517ca37 100644 --- a/g/util/gconv/gconv.go +++ b/g/util/gconv/gconv.go @@ -137,6 +137,7 @@ func String(i interface{}) string { case bool: return strconv.FormatBool(value) case string: return value case []byte: return string(value) + case []rune: return string(value) default: if f, ok := value.(apiString); ok { // If the variable implements the String() interface, diff --git a/geg/os/glog/glog_category.go b/geg/os/glog/glog_category.go index 8a0d0d9c0..3df48a275 100644 --- a/geg/os/glog/glog_category.go +++ b/geg/os/glog/glog_category.go @@ -9,7 +9,7 @@ import ( func main() { path := "/tmp/glog-cat" glog.SetPath(path) - glog.StdPrint(false).Cat("cat1").Cat("cat2").Println("test") + glog.Stdout(false).Cat("cat1").Cat("cat2").Println("test") list, err := gfile.ScanDir(path, "*", true) g.Dump(err) g.Dump(list) diff --git a/geg/os/glog/glog_debug.go b/geg/os/glog/glog_debug.go index 259f0f8b4..faa4f1c9e 100644 --- a/geg/os/glog/glog_debug.go +++ b/geg/os/glog/glog_debug.go @@ -3,11 +3,12 @@ package main import ( "github.com/gogf/gf/g/os/glog" "github.com/gogf/gf/g/os/gtime" + "github.com/gogf/gf/g/os/gtimer" "time" ) func main() { - gtime.SetTimeout(3*time.Second, func() { + gtimer.SetTimeout(3*time.Second, func() { glog.SetDebug(false) }) for { diff --git a/geg/os/glog/glog_json.go b/geg/os/glog/glog_json.go new file mode 100644 index 000000000..75ceeb6dc --- /dev/null +++ b/geg/os/glog/glog_json.go @@ -0,0 +1,16 @@ +package main + +import ( + "github.com/gogf/gf/g" + "github.com/gogf/gf/g/os/glog" +) + +func main() { + glog.Debug(g.Map{"uid" : 100, "name" : "john"}) + + type User struct { + Uid int `json:"uid"` + Name string `json:"name"` + } + glog.Debug(User{100, "john"}) +}