log
1 基础
package main
import "log"
func main() {
log.Printf("Printf")
log.Println("Println")
log.Print("Print")
}2 定制
3 实现
最后更新于
package main
import "log"
func main() {
log.Printf("Printf")
log.Println("Println")
log.Print("Print")
}最后更新于
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
)package main
import "log"
func main() {
log.SetPrefix("logger: ") // 设置前缀
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile) // 设置输出选项
log.Println(log.Flags()) // 获取输出选项
log.Println(log.Prefix()) // 获取输出前缀
log.Printf("Printf")
log.Println("Println")
log.Fatalf("yes")
}
/*
logger: 2024/11/27 19:57:44 log.go:8: 19
logger: 2024/11/27 19:57:44 log.go:9: logger:
logger: 2024/11/27 19:57:44 log.go:10: Printf
logger: 2024/11/27 19:57:44 log.go:11: Println
logger: 2024/11/27 19:57:44 log.go:12: yes
*/package main
import (
"bytes"
"io"
"log"
"os"
)
func main() {
buf1 := &bytes.Buffer{}
buf2 := os.Stdout
buf3, _ := os.OpenFile("test.log", os.O_CREATE|os.O_RDWR, os.ModePerm)
// func New(out io.Writer, prefix string, flag int) *Logger
logger := log.New(io.MultiWriter(buf1, buf2, buf3), "NewLogger\t", log.Lmicroseconds|log.Lshortfile)
logger.Fatalf(" NewLogger Test")
}
// NewLogger 20:14:43.363719 log.go:18: NewLogger Testvar std = New(os.Stderr, "", LstdFlags)
func Fatalf(format string, v ...any) {
std.Output(2, fmt.Sprintf(format, v...))
os.Exit(1)
}func (l *Logger) output(pc uintptr, calldepth int, appendOutput func([]byte) []byte) error {
if l.isDiscard.Load() {
return nil
}
now := time.Now() // get this early.
// Load prefix and flag once so that their value is consistent within // this call regardless of any concurrent changes to their value. prefix := l.Prefix()
flag := l.Flags()
var file string
var line int
if flag&(Lshortfile|Llongfile) != 0 {
if pc == 0 {
var ok bool
_, file, line, ok = runtime.Caller(calldepth)
if !ok {
file = "???"
line = 0
}
} else {
fs := runtime.CallersFrames([]uintptr{pc})
f, _ := fs.Next()
file = f.File
if file == "" {
file = "???"
}
line = f.Line
}
}
buf := getBuffer()
defer putBuffer(buf)
formatHeader(buf, now, prefix, flag, file, line)
*buf = appendOutput(*buf)
if len(*buf) == 0 || (*buf)[len(*buf)-1] != '\n' {
*buf = append(*buf, '\n')
}
l.outMu.Lock()
defer l.outMu.Unlock()
_, err := l.out.Write(*buf)
return err
}