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

参考

  1. Go语言标准库log介绍
  2. Golang中使用log(一):Golang 标准库提供的Log
posted @ 2022-06-24 16:14  呵呵233  阅读(417)  评论(0编辑  收藏  举报