本文主要研究一下golang的log
const ( Ldate = 1 << iota // the date in the local time zone: 2009/01/23 Ltime // the time in the local time zone: 01:23:23 Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime. Llongfile // full file name and line number: /a/b/c/d.go:23 Lshortfile // final file name element and line number: d.go:23. overrides Llongfile LUTC // if Ldate or Ltime is set, use UTC rather than the local time zone Lmsgprefix // move the "prefix" from the beginning of the line to before the message LstdFlags = Ldate | Ltime // initial values for the standard logger )
这几个flags可以用来设置log的pattern
type Logger struct { mu sync.Mutex // ensures atomic writes; protects the following fields prefix string // prefix on each line to identify the logger (but see Lmsgprefix) flag int // properties out io.Writer // destination for output buf []byte // for accumulating text to write } func New(out io.Writer, prefix string, flag int) *Logger { return &Logger{out: out, prefix: prefix, flag: flag} } func (l *Logger) SetOutput(w io.Writer) { l.mu.Lock() defer l.mu.Unlock() l.out = w } func (l *Logger) Output(calldepth int, s string) error { now := time.Now() // get this early. var file string var line int l.mu.Lock() defer l.mu.Unlock() if l.flag&(Lshortfile|Llongfile) != 0 { // Release lock while getting caller info - it's expensive. l.mu.Unlock() var ok bool _, file, line, ok = runtime.Caller(calldepth) if !ok { file = "???" line = 0 } l.mu.Lock() } l.buf = l.buf[:0] l.formatHeader(&l.buf, now, file, line) l.buf = append(l.buf, s...) if len(s) == 0 || s[len(s)-1] != '\n' { l.buf = append(l.buf, '\n') } _, err := l.out.Write(l.buf) return err } func (l *Logger) Printf(format string, v ...interface{}) { l.Output(2, fmt.Sprintf(format, v...)) } func (l *Logger) Print(v ...interface{}) { l.Output(2, fmt.Sprint(v...)) } func (l *Logger) Println(v ...interface{}) { l.Output(2, fmt.Sprintln(v...)) } func (l *Logger) Fatal(v ...interface{}) { l.Output(2, fmt.Sprint(v...)) os.Exit(1) } func (l *Logger) Fatalf(format string, v ...interface{}) { l.Output(2, fmt.Sprintf(format, v...)) os.Exit(1) } func (l *Logger) Fatalln(v ...interface{}) { l.Output(2, fmt.Sprintln(v...)) os.Exit(1) } func (l *Logger) Panic(v ...interface{}) { s := fmt.Sprint(v...) l.Output(2, s) panic(s) } func (l *Logger) Panicf(format string, v ...interface{}) { s := fmt.Sprintf(format, v...) l.Output(2, s) panic(s) } func (l *Logger) Panicln(v ...interface{}) { s := fmt.Sprintln(v...) l.Output(2, s) panic(s) } func (l *Logger) SetFlags(flag int) { l.mu.Lock() defer l.mu.Unlock() l.flag = flag } func (l *Logger) SetPrefix(prefix string) { l.mu.Lock() defer l.mu.Unlock() l.prefix = prefix } func (l *Logger) Writer() io.Writer { l.mu.Lock() defer l.mu.Unlock() return l.out }
package main import ( "encoding/json" "errors" "io" "log" "os" "time" ) var logFile *os.File func init() { log.SetFlags(log.Ldate | log.Lmicroseconds | log.Lshortfile) log.SetPrefix("demo-app ") var err error logFile, err = os.OpenFile("/tmp/demo.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) if err != nil { log.Fatalln("Failed to open log file") } mw := io.MultiWriter(os.Stdout, logFile) log.SetOutput(mw) } type Cart struct { UserId int `json:"userId"` SkuId int `json:"skuId"` } func closeLogFile() { if logFile != nil { log.Println("closing log file") logFile.Close() } } func main() { defer closeLogFile() // log.Panicln("print and then exit with status 2") // log.Fatalln("print and then exit with status 1") log.Println("hello") log.Printf("hello %s", "abc") //print with var str1 := "abc" str2 := "cdf" log.Println("print with auto space:", str1, "append", str2) //print error err1 := errors.New("demo error") log.Println("error:", err1) //print time now1 := time.Now() log.Println("print time:", now1) log.Println("print time with format:", now1.Format(time.RFC3339)) //print struct cart := Cart{ UserId: 1, SkuId: 123, } log.Println("print struct:", cart) //print json jsonByte, err := json.Marshal(cart) if err != nil { log.Fatalln("error:", err) } log.Println("print cart json:", string(jsonByte)) //log to file }
输出实例
demo-app 2020/12/03 23:54:27.245848 main.go:42: hello demo-app 2020/12/03 23:54:27.245974 main.go:43: hello abc demo-app 2020/12/03 23:54:27.245981 main.go:48: print with auto space: abc append cdf demo-app 2020/12/03 23:54:27.245996 main.go:52: error: demo error demo-app 2020/12/03 23:54:27.246015 main.go:56: print time: 2020-12-03 23:54:27.246001 +0800 CST m=+0.000260928 demo-app 2020/12/03 23:54:27.246022 main.go:57: print time with format: 2020-12-03T23:54:27+08:00 demo-app 2020/12/03 23:54:27.246047 main.go:64: print struct: {1 123} demo-app 2020/12/03 23:54:27.246109 main.go:71: print cart json: {"userId":1,"skuId":123} demo-app 2020/12/03 23:54:27.246116 main.go:33: closing log file