Go 语言标准库之 log 包
Go语言内置的 log 包实现了简单的日志服务,本文介绍了 log 包的基本使用。
Logger 类型
log 包定义了Logger
类型,该类型提供了一些格式化输出的方法,具体定义如下:
// Logger 类型表示一个活动状态的记录日志的对象,生成一行行的输出写入 io.Writer 接口,每一条日志操作会调用一次 io.Writer 接口的 Write 方法
// Logger 对象可以被多个线程安全的同时使用,它会保证对 io.Writer 接口的顺序访问
type Logger struct {
// contains filtered or unexported fields
}
// 创建一个 Logger 对象。参数 out 设置日志信息写入的目的地;参数 prefix 会添加到每一条生成的日志前面;参数 flag 定义日志的属性(时间、文件等等)
func New(out io.Writer, prefix string, flag int) *Logger
// 下列选项定义了 Logger 类型的日志的输出选项 flag,这些输出选项文本会作为每一条日志的前缀
const (
// 字位共同控制输出日志信息的细节。不能控制输出的顺序和格式。
// 在所有项目后会有一个冒号:2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message
Ldate = 1 << iota // 日期:2009/01/23
Ltime // 时间:01:23:23
Lmicroseconds // 微秒分辨率:01:23:23.123123(用于增强Ltime位)
Llongfile // 文件全路径名+行号: /a/b/c/d.go:23
Lshortfile // 文件无路径名+行号:d.go:23(会覆盖掉Llongfile)
LstdFlags = Ldate | Ltime // 标准 logger 的初始值
)
// 返回 logger 的输出选项 flag
func (l *Logger) Flags() int
// 设置 logger 的输出选项 flag
func (l *Logger) SetFlags(flag int)
// 设置 logger 的输出前缀 prefix
func (l *Logger) Prefix() string
// 设置 logger 的输出前缀 prefix
func (l *Logger) SetPrefix(prefix string)
// 写入输出一次日志事件。参数 s 包含在 Logger 根据选项生成的前缀之后要打印的文本,如果 s 末尾没有换行会添加换行符
// calldepth 用于恢复PC,出于一般性而提供,但目前在所有预定义的路径上它的值都为 2
func (l *Logger) Output(calldepth int, s string) error
// 设置 logger 的日志信息写入的目的地
func (l *Logger) SetOutput(w io.Writer)
// 调用 l.Output() 将生成的格式化字符串输出到 logger,参数用和 fmt.Printf 相同的方法处理
func (l *Logger) Printf(format string, v ...interface{})
// 调用 l.Output() 将生成的格式化字符串输出到 logger,参数用和 fmt.Print 相同的方法处理
func (l *Logger) Print(v ...interface{})
// 调用 l.Output 将生成的格式化字符串输出到 logger,参数用和 fmt.Println 相同的方法处理
func (l *Logger) Println(v ...interface{})
// 等价先后调用 l.Printf(v...) 和 os.Exit(1)
func (l *Logger) Fatalf(format string, v ...interface{})
// 等价先后调用 l.Print(v...) 和 os.Exit(1)
func (l *Logger) Fatal(v ...interface{})
// 等价先后调用 l.Println(v...) 和 os.Exit(1)
func (l *Logger) Fatalln(v ...interface{})
// 等价先后调用 l.Printf(v...) 和 panic(...)
func (l *Logger) Panicf(format string, v ...interface{})
// 等价先后调用 l.Print(v...) 和 panic(...)
func (l *Logger) Panic(v ...interface{})
// 等价先后调用 l.Println(v...) 和 panic(...)
func (l *Logger) Panicln(v ...interface{})
☕️ 示例代码
package main
import (
"io"
"log"
"os"
)
func main() {
logFile, err := os.Create("xxx_info.log")
if err != nil {
log.Fatalln("open file error!")
}
defer logFile.Close()
// 将日志会同时输出到文件和 os.Stdout
multiWriter := io.MultiWriter(os.Stdout, logFile)
infoLog := log.New(multiWriter, "[info]", log.Ldate|log.Ltime|log.Lshortfile)
infoLog.Println("A info message here")
infoLog.Fatalln("exit")
}
// xxx_info.log 和终端界面内容显示如下:
// [info]2022/06/24 15:40:54 main.go:20: A info message here
// [info]2022/06/24 15:40:54 main.go:21: exit
标准 logger
log 包提供一个预定义的标准Logger
,可以直接调用函数Print系列(Print|Printf|Println)
、Fatal系列(Fatal|Fatalf|Fatalln)
和Panic系列(Panic|Panicf|Panicln)
进行日志输出,比自行创建一个Logger
对象更容易使用。
// log 包提供的标准 logger,日志信息默认输出到 os.Stderr,LstdFlags 值为 Ldate | Ltime
var std = New(os.Stderr, "", LstdFlags)
func Default() *Logger { return std }
// 返回标准 logger 的输出选项 flag
func Flags() int
// 设置标准 logger 的输出选项 flag
func SetFlags(flag int)
// 设置标准 logger 的输出前缀 prefix
func Prefix() string
// 设置标准 logger 的输出前缀 prefix
func SetPrefix(prefix string)
// 写入输出一次日志事件。参数 s 包含在标准 logger 根据选项生成的前缀之后要打印的文本,如果 s 末尾没有换行会添加换行符。
// calldepth 用于恢复PC,出于一般性而提供,但目前在所有预定义的路径上它的值都为 2
func Output(calldepth int, s string) error
// 设置标准 logger 的日志信息写入的目的地
func SetOutput(w io.Writer)
// 调用 Output() 将生成的格式化字符串输出到标准 logger,参数用和 fmt.Printf 相同的方法处理
func Printf(format string, v ...interface{})
// 调用 Output() 将生成的格式化字符串输出到标准 logger,参数用和 fmt.Print 相同的方法处理
func Print(v ...interface{})
// 调用 Output 将生成的格式化字符串输出到标准 logger,参数用和 fmt.Println 相同的方法处理
func Println(v ...interface{})
// 等价先后调用 Printf(v...) 和 os.Exit(1)
func Fatalf(format string, v ...interface{})
// 等价先后调用 Print(v...) 和 os.Exit(1)
func Fatal(v ...interface{})
// 等价先后调用 Println(v...) 和 os.Exit(1)
func Fatalln(v ...interface{})
// 等价先后调用 Printf(v...) 和 panic(...)
func Panicf(format string, v ...interface{})
// 等价先后调用 Print(v...) 和 panic(...)
func Panic(v ...interface{})
// 等价先后调用 Println(v...) 和 panic(...)
func Panicln(v ...interface{})
☕️ 示例代码
package main
import (
"io"
"log"
"os"
)
func main() {
logFile, err := os.Create("xxx_info.log")
if err != nil {
log.Fatalln("open file error!")
}
defer logFile.Close()
// 将日志会同时输出到文件和 os.Stderr
multiWriter := io.MultiWriter(os.Stdout, logFile)
log.SetOutput(multiWriter)
log.SetPrefix("[info]")
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
log.Println("A info message here")
log.Fatalln("exit")
}
// xxx_info.log 和终端界面内容显示如下:
// [info]2022/06/24 15:40:54 main.go:20: A info message here
// [info]2022/06/24 15:40:54 main.go:21: exit