在Golang的标准库中,log包提供了基础的日志记录能力,默认情况下日志会输出到控制台的标准错误流,开发者可以通过简单的配置调整日志的输出位置和格式,满足不同的开发需求。

Golang log包基础用法
Golang的log包提供了多个开箱即用的函数,最常用的包括Print、Println、Printf以及对应的Fatal、Panic系列函数,其中Fatal会在输出日志后调用os.Exit(1)终止程序,Panic会触发panic。
下面是基础的控制台日志输出示例:
package main
import (
"log"
)
func main() {
// 基础日志输出,默认输出到控制台
log.Print("这是一条普通日志")
log.Println("这是一条带换行的日志")
log.Printf("这是一条格式化日志,参数值:%d", 100)
}
配置日志输出格式
默认的日志输出只包含日志内容,没有时间戳、文件名等信息,我们可以通过log.SetFlags函数设置日志的前缀格式,常用的标志位如下:
log.Ldate:输出本地日期,格式为2009/01/23log.Ltime:输出本地时间,格式为01:23:23log.Lmicroseconds:输出微秒级时间log.Llongfile:输出完整文件名和行号log.Lshortfile:输出文件名和行号
配置日志格式的代码示例如下:
package main
import (
"log"
)
func main() {
// 设置日志格式:日期+时间+文件名+行号
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
log.Print("配置格式后的日志输出")
}
将日志输出到文件
默认情况下log包的日志输出目标是os.Stderr,也就是控制台的标准错误流,我们可以通过log.SetOutput函数修改输出目标,将日志写入到文件中。
首先需要使用os.OpenFile创建或打开日志文件,设置对应的权限和打开模式,再将文件句柄设置为log的输出目标:
package main
import (
"log"
"os"
)
func main() {
// 打开日志文件,不存在则创建,追加写入,权限为0644
logFile, err := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
log.Fatal("打开日志文件失败:", err)
}
// 程序退出前关闭文件
defer logFile.Close()
// 设置日志输出到文件
log.SetOutput(logFile)
// 设置日志格式
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
log.Print("这条日志会写入到app.log文件中")
}
同时输出到控制台和文件
实际开发中我们往往希望日志既能在控制台实时查看,又能持久化到文件中,这时候可以使用io.MultiWriter将多个输出目标组合起来,作为log的输出对象。
具体实现代码如下:
package main
import (
"io"
"log"
"os"
)
func main() {
// 打开日志文件
logFile, err := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
log.Fatal("打开日志文件失败:", err)
}
defer logFile.Close()
// 创建多路输出器,同时输出到控制台和文件
multiWriter := io.MultiWriter(os.Stderr, logFile)
// 设置日志输出到多路输出器
log.SetOutput(multiWriter)
// 设置日志格式
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
log.Print("这条日志会同时输出到控制台和app.log文件")
}
注意事项
使用Golang标准log包记录日志时需要注意以下几点:
- log包是线程安全的,多个goroutine同时调用日志函数不会出现输出混乱的问题
- 如果日志文件需要按日期切割,标准log包没有内置支持,需要自行实现或者使用第三方日志库如logrus、zap等
- 生产环境中不建议使用
log.Fatal和log.Panic系列函数,避免程序意外终止或者触发不必要的panic - 日志文件的权限设置要合理,避免敏感日志被非授权用户读取