From fe792bcb4bdeec42ff0900f9d197382fe15c02ff Mon Sep 17 00:00:00 2001 From: bryan Date: Sun, 6 Apr 2025 10:42:33 +0800 Subject: [PATCH] optimize log format --- log.go | 145 +++++++++++++++++++++++++++++++--------------------- log_test.go | 7 +-- 2 files changed, 91 insertions(+), 61 deletions(-) diff --git a/log.go b/log.go index 17d7d3e..48e7a8e 100644 --- a/log.go +++ b/log.go @@ -58,9 +58,10 @@ var ( type LogLevel int type Logger struct { - module string - golog *log.Logger - loglevel LogLevel + module string + golog *log.Logger + loglevel LogLevel + calldepth int } type LogidCreator interface { @@ -102,6 +103,11 @@ func (log *Logger) SetLogLevelByName(newlv string) (oldlv string) { return ErrLogLevel } +// SetCalldepth adjust the call depth +func (log *Logger) SetCalldepth(calldepth int) { + log.calldepth = calldepth +} + func (log *Logger) Print(prefix string, v interface{}) { var str = "" if pkg, err := json.Marshal(v); err != nil { @@ -161,16 +167,23 @@ func (log *Logger) Panicf(format string, v ...interface{}) { } func (log *Logger) Fatal(v ...interface{}) { - log.logwrite(FATAL, 3, "%s", fmt.Sprintln(v...)) + log.logwrite(FATAL, 3, "%s", fmt.Sprint(v...)) +} + +func (log *Logger) Printf(format string, v ...interface{}) { + log.logwrite(DEBUG, 3, format, v...) } func (log *Logger) Println(v ...interface{}) { - log.logwrite(DEBUG, 3, "%s", fmt.Sprintln(v...)) + log.logwrite(DEBUG, 3, "%s", fmt.Sprint(v...)) } func (log *Logger) GetLogidStr(format string) string { if logidCreator != nil { - return fmt.Sprintf(format, logidCreator.GetLogid()) + logid := logidCreator.GetLogid() + if logid != "" { + return fmt.Sprintf(format, logid) + } } return "" } @@ -179,50 +192,49 @@ func (log *Logger) logwrite(typ LogLevel, calldepth int, format string, v ...int if typ > log.loglevel { return } - + if mylog == log { + calldepth = calldepth + 1 + } + calldepth += log.calldepth var ( - idstr = log.GetLogidStr("[%s]") - prestr = formatHeader(calldepth) + "" + idstr + "$ " + idstr = log.GetLogidStr(" [%s]") + header = formatHeader(calldepth) + "$" + idstr ) format = strings.Trim(format, "\n") switch typ { - case PANIC: - log.golog.SetPrefix("\x1b[31m" + "PANI ") - case FATAL: - log.golog.SetPrefix("\x1b[31m" + "FATA ") - case WARNING: - log.golog.SetPrefix("\x1b[32m" + "WARN ") - case ERROR: - log.golog.SetPrefix("\x1b[33m" + "ERRO ") case INFO: - log.golog.SetPrefix("INFO ") + log.golog.SetPrefix("\x1b[2m" + "INFO " + header + "\x1b[0m" + " ") case NOTICE: - log.golog.SetPrefix("NOTI ") + log.golog.SetPrefix("\x1b[2m" + "NOTI " + header + "\x1b[0m" + " ") case DEBUG: - log.golog.SetPrefix("DBUG ") + log.golog.SetPrefix("\x1b[2m" + "DBUG " + header + "\x1b[0m" + " ") + case PANIC: + log.golog.SetPrefix("\x1b[31m" + "PANI " + header + "\x1b[0m" + " ") + case FATAL: + log.golog.SetPrefix("\x1b[31m" + "FATA " + header + "\x1b[0m" + " ") + case ERROR: + log.golog.SetPrefix("\x1b[41m" + "ERRO " + header + "\x1b[0m" + " ") + case WARNING: + log.golog.SetPrefix("\x1b[33m" + "WARN " + header + "\x1b[0m" + " ") default: - log.golog.SetPrefix("UNKN ") - } - - if mylog == log { - calldepth = calldepth + 1 + log.golog.SetPrefix("\x1b[33m" + "UNKN " + header + "\x1b[0m" + " ") } if typ == FATAL || typ == WARNING || typ == ERROR { - log.golog.Output(calldepth, prestr+fmt.Sprintf(format+"\x1b[0m\n", v...)) + log.golog.Output(calldepth, "\x1b[31m"+fmt.Sprintf(format, v...)+"\x1b[0m") + } else if typ == INFO || typ == DEBUG { + log.golog.Output(calldepth, fmt.Sprintf(format, v...)) } else if typ == NOTICE { calldepth = calldepth + 2 - log.golog.Output(calldepth, prestr+fmt.Sprintf(format+"\n", v...)) + log.golog.Output(calldepth, fmt.Sprintf(format, v...)) } else if typ == PANIC { - stack := strings.Replace(string(debug.Stack()), "\n", "\n== ", -1) - stack = str.SkipLine(stack, calldepth*2+1) - v = append(v, stack) - panicstr := fmt.Sprintf(prestr+format+"\x1b[0m. Panic stack:\n%s\n", v...) - log.golog.Output(calldepth, panicstr) - panic(ErrLogPanic) + stackstr := strings.Replace(string(debug.Stack()), "\n", "\n== ", -1) + stackstr = "\n== Panic stack:\n" + str.SkipLine(stackstr, calldepth*2+1) + log.golog.Output(calldepth, fmt.Sprintf(format, v...)+stackstr) + panic(fmt.Sprintf(format, v...)) } else { - log.golog.Output(calldepth, prestr+fmt.Sprintf(format+"\n", v...)) + panic(ErrLogLevel) } } @@ -236,7 +248,7 @@ func formatHeader(calldepth int) string { year, month, day, hour, min, sec, now.Nanosecond()/1e6) // log position - _, file, line, ok := runtime.Caller(calldepth + 1) + _, file, line, ok := runtime.Caller(calldepth) if !ok { file = "???" line = 0 @@ -250,61 +262,78 @@ func formatHeader(calldepth int) string { } // Case 2: filename long enough, just return filename + var fileline = "" for i = len(file) - 1; i >= 0; i-- { if file[i] == '/' { - header = file[i:] + ":" + linestr + fileline = file[i:] + ":" + linestr i-- break } } - if len(header) >= MAX_LENGTH && i > 0 { - header = "…" + header[:4] + "…" + header[len(header)-MAX_LENGTH+6:] - return nowstr + header - } else if len(header) >= MAX_LENGTH && i <= 0 { - header = header[:4] + "…" + header[len(header)-MAX_LENGTH+5:] - return nowstr + header + if len(fileline) >= MAX_LENGTH && i > 0 { + //fileline = fileline[:4] + "*" + fileline[len(fileline)-MAX_LENGTH+6:] + return nowstr + fileline + } else if len(fileline) >= MAX_LENGTH && i <= 0 { + //fileline = fileline[:4] + "…" + fileline[len(fileline)-MAX_LENGTH+5:] + return nowstr + fileline } - // Case 3: try complex middle path with 'width=6' - tempheader := formatHeaderPath(file, i, 6) + header + // Case 3: try complex middle path + header = fileline + tempheader := formatHeaderPath(file, i, 20, 2) + header if len(tempheader) > MAX_LENGTH { - tempheader = "…" + tempheader[len(tempheader)-MAX_LENGTH+1:] + //tempheader = "…" + tempheader[len(tempheader)-MAX_LENGTH+1:] + tempheader = tempheader[len(tempheader)-MAX_LENGTH:] return nowstr + tempheader } - // Case 4: try complex middle path with 'width=8' - tempheader = formatHeaderPath(file, i, 8) + header + // Case 4: try complex middle path + tempheader = formatHeaderPath(file, i, 20, 3) + header if len(tempheader) > MAX_LENGTH { - tempheader = "…" + tempheader[len(tempheader)-MAX_LENGTH+1:] + //tempheader = "…" + tempheader[len(tempheader)-MAX_LENGTH+1:] + tempheader = tempheader[len(tempheader)-MAX_LENGTH:] return nowstr + tempheader } - // Case 5: try complex middle path with 'width=10' - tempheader = formatHeaderPath(file, i, 10) + header + // Case 5: try complex middle path + tempheader = formatHeaderPath(file, i, 20, 4) + header if len(tempheader) > MAX_LENGTH { - tempheader = "…" + tempheader[len(tempheader)-MAX_LENGTH+1:] + //tempheader = "…" + tempheader[len(tempheader)-MAX_LENGTH+1:] + tempheader = tempheader[len(tempheader)-MAX_LENGTH:] return nowstr + tempheader } - // Case 6: fallback + // Case 6: try complex middle path + tempheader = formatHeaderPath(file, i, 20, 5) + header + if len(tempheader) > MAX_LENGTH { + //tempheader = "…" + tempheader[len(tempheader)-MAX_LENGTH+1:] + tempheader = tempheader[len(tempheader)-MAX_LENGTH:] + return nowstr + tempheader + } + + // Case 7: fallback return nowstr + tempheader } -func formatHeaderPath(file string, i, width int) (paths string) { - ii, iw := i, i +func formatHeaderPath(file string, i, maxwidth, fullstep int) (paths string) { + ii, iw, step := i, i, 1 for i := ii; i >= 0; i-- { if file[i] == '/' { - if iw-i > width { + step++ + if step < fullstep { + // dirname should not cut + paths = file[i:iw+1] + paths + } else if iw-i > maxwidth { // dirname lenght more then width - paths = file[i:i+width] + "." + paths + paths = file[i:i+maxwidth] + paths // paths = file[i:i+width] + "..." + paths } else { // dirname lenght less then width paths = file[i:iw+1] + paths } //fmt.Println("w", iw-i, "width", width, "paths", paths) - if width > 2 { + if step >= fullstep { // decrease width - width-- + maxwidth = 2 } iw = i - 1 continue diff --git a/log_test.go b/log_test.go index 6df58ee..97aa25c 100644 --- a/log_test.go +++ b/log_test.go @@ -3,7 +3,8 @@ package log import "testing" func TestLog(t *testing.T) { - Println("aaa", 1,3) - Fatal("aaa", 1,3) - Fatalf("aaa=%d", 1) + Println("aaa", 1, 3, 6) + Fatal("aaa", 1, 3) + Fatalf("aaa=%d", 1) + Panicf("aaa=%d", 1) }