Skip to content

在 Go 中,log 包提供了用于日志记录的基本功能。通过 log 包,可以方便地输出日志信息,进行错误处理和调试。log 包提供了基本的日志记录功能,例如将日志输出到控制台、文件等,并支持不同的日志级别和格式化输出。

1. 基本用法

Go 的 log 包提供了一些简单的功能来进行日志记录。

1.1. 记录日志

go
package main

import (
    "log"
)

func main() {
    log.Println("This is a log message.")
}
  • log.Println():将日志打印到标准输出,默认会添加一个时间戳。
  • log.Print():类似 log.Println(),但是不会添加换行符。
  • log.Printf():支持格式化字符串,类似于 fmt.Printf()
go
log.Printf("User ID: %d", 1234)

1.2. 记录错误日志

通常在处理错误时,log 包也可以用来输出错误信息。

go
err := someFunction()
if err != nil {
    log.Printf("Error: %v", err)
}

1.3. 日志级别

log 包本身并不支持日志级别(例如 INFOWARNERROR),但是可以通过自定义的日志记录函数来实现。

go
log.Println("INFO: This is an informational message.")
log.Println("ERROR: Something went wrong.")

2. 日志的输出位置

默认情况下,log 包将日志输出到标准输出(即终端)。但是,你可以自定义日志的输出位置,比如写入文件或网络。

2.1. 输出到文件

你可以将日志输出到文件中,使用 log.SetOutput() 函数来设置日志输出位置。

go
package main

import (
    "log"
    "os"
)

func main() {
    // 打开或创建文件
    file, err := os.OpenFile("app.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
    if err != nil {
        log.Fatal(err)
    }
    defer file.Close()

    // 设置日志输出到文件
    log.SetOutput(file)

    log.Println("This message will be written to the file.")
}
  • 使用 os.OpenFile() 打开一个文件,并指定文件的模式(os.O_APPEND 表示追加,os.O_CREATE 表示创建文件,os.O_WRONLY 表示写入模式)。
  • 通过 log.SetOutput() 设置日志的输出目的地为文件。

2.2. 输出到自定义的 io.Writer

你也可以将日志输出到任何实现了 io.Writer 接口的地方,比如缓冲区、网络连接等。

go
package main

import (
    "bytes"
    "log"
)

func main() {
    var buf bytes.Buffer
    log.SetOutput(&buf)

    log.Println("This will be written to the buffer.")
    log.Println(buf.String())
}

3. 自定义日志格式

默认情况下,log 包的日志格式是:[时间戳] 消息。你可以自定义日志的前缀和日期格式。

3.1. 设置自定义前缀

go
log.SetPrefix("INFO: ")
log.Println("This is an informational log message.")

3.2. 设置自定义时间格式

默认情况下,log 包的时间戳格式是 2006/01/02 15:04:05。你可以使用 log.SetFlags() 来自定义日志的时间格式。

go
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
log.Println("This log includes the date, time, and file information.")
  • log.Ldate:日期(如 2006/01/02)。
  • log.Ltime:时间(如 15:04:05)。
  • log.Lmicroseconds:带微秒的时间(如 15:04:05.123456)。
  • log.Llongfile:显示完整的文件名和行号。
  • log.Lshortfile:显示相对文件名和行号。

4. 日志的输出方式

你可以使用 log 包进行不同方式的日志输出,例如:

  • 标准日志:使用 log.Println()log.Print() 等输出。
  • 调试日志:通过 log.Printf() 格式化输出。
  • 错误日志:在出现错误时使用 log.Fatal()log.Panic()

4.1. log.Fatal()log.Panic()

  • log.Fatal() 会输出日志并调用 os.Exit(1) 退出程序。
  • log.Panic() 会输出日志并触发 panic
go
log.Fatal("Something went wrong, exiting...")
log.Panic("Something went wrong, panic triggered!")

4.2. 日志与程序退出

  • log.Fatal():会先打印日志消息,再调用 os.Exit(1) 退出程序。程序在 os.Exit() 被调用后将立刻终止,因此任何后续的代码都不会执行。
  • log.Panic():会触发一个 panic,并且该 panic 会在程序的调用栈中传播,最终导致程序崩溃。

5. 日志库扩展与替代方案

虽然 Go 的 log 包提供了基本的日志功能,但它相对简单,并没有日志级别、结构化日志等高级功能。如果你需要更强大的日志功能,可以使用一些第三方库。

5.1. logrus

Logrus 是一个流行的第三方日志库,支持日志级别、钩子、JSON 格式输出等特性。

go
package main

import (
    "github.com/sirupsen/logrus"
)

func main() {
    log := logrus.New()

    log.SetFormatter(&logrus.TextFormatter{
        FullTimestamp: true,
    })

    log.Info("This is an info message")
    log.Warn("This is a warning message")
    log.Error("This is an error message")
}

5.2. zap

Zap 是一个高性能的日志库,适合在高负载场景下使用,支持结构化日志和 JSON 输出。

go
package main

import (
    "go.uber.org/zap"
)

func main() {
    logger, _ := zap.NewProduction()
    defer logger.Sync()

    logger.Info("This is an info message")
    logger.Error("This is an error message")
}

6. 总结

  • Go 的 log 包非常基础,但足够应付大多数日志需求,支持输出到控制台、文件或其他 io.Writer
  • 你可以自定义日志的格式、前缀以及时间戳的显示方式。
  • 使用 log.Fatal()log.Panic() 可以快速退出程序或触发 panic。
  • 对于更复杂的日志需求,可以考虑使用第三方库,如 logruszap,它们支持更丰富的日志功能,如日志级别、结构化日志和 JSON 输出等。

通过适当使用日志记录工具,可以帮助你在开发和调试过程中跟踪程序行为,捕获错误并进行性能分析。