Go 中的 log 包
log 包是 Go 语言标准库中的日志库,用于记录程序的运行信息。它提供了简单的日志记录功能,适合开发阶段的调试和生产环境的基本日志输出需求。
log 包的核心功能
- 输出日志信息到标准输出或文件。
- 提供多种日志级别(通过扩展,如 log.Logger)。
- 支持自定义日志前缀和时间戳格式。
- 易于集成到更复杂的日志系统中。
log 包的常用函数
- log.Print:输出日志信息(类似 fmt.Print)。
- log.Println:输出日志信息并在末尾添加换行符(类似 fmt.Println)。
- log.Printf:按指定格式输出日志信息(类似 fmt.Printf)。
- log.Fatal:输出日志信息后调用 os.Exit(1) 终止程序。
- log.Panic:输出日志信息后引发 panic。
示例代码:
package mainimport "log"func main() {log.Print("这是一条普通日志")log.Println("这是一条带换行的日志")log.Printf("这是一条格式化日志:变量值为 %d", 42)// Fatal 和 Panic 示例(请注释其中之一以避免程序中断)// log.Fatal("这是一条致命日志,程序将在日志后退出")// log.Panic("这是一条会引发 panic 的日志")
}
输出示例:
2024/12/09 12:00:00 这是一条普通日志
2024/12/09 12:00:00 这是一条带换行的日志
2024/12/09 12:00:00 这是一条格式化日志:变量值为 42
自定义日志功能
log 包允许创建自定义的 Logger 实例,可以指定输出目标、前缀和日志标志。
- log.New:创建新的 Logger 实例。
- log.Flags:设置日志格式标志(如日期、时间、微秒、文件行号)。
- log.SetOutput:更改日志输出位置(如文件)。
示例代码:自定义日志前缀和输出文件
package mainimport ("log""os"
)func main() {// 打开日志文件file, err := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)if err != nil {log.Fatalf("无法打开日志文件: %v", err)}defer file.Close()// 创建自定义 Loggerlogger := log.New(file, "INFO: ", log.Ldate|log.Ltime|log.Lshortfile)// 记录日志logger.Println("应用程序启动")logger.Printf("当前状态:%s", "运行中")// 错误日志示例logger.SetPrefix("ERROR: ")logger.Println("发生错误,无法连接数据库")
}
输出日志文件内容:
INFO: 2024/12/09 12:00:00 main.go:20: 应用程序启动
INFO: 2024/12/09 12:00:00 main.go:21: 当前状态:运行中
ERROR: 2024/12/09 12:00:00 main.go:24: 发生错误,无法连接数据库
企业级使用案例
在企业应用中,log 包通常与其他工具(如多模块日志记录、远程日志收集等)结合使用。以下示例展示了一个基于 log 包的多级日志记录器:
示例代码:多级日志记录
package mainimport ("log""os"
)// Logger 定义多级日志记录器
type Logger struct {Info *log.LoggerError *log.Logger
}func NewLogger(infoFile, errorFile string) (*Logger, error) {// 打开日志文件infoLog, err := os.OpenFile(infoFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)if err != nil {return nil, err}errorLog, err := os.OpenFile(errorFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)if err != nil {infoLog.Close()return nil, err}return &Logger{Info: log.New(infoLog, "INFO: ", log.Ldate|log.Ltime|log.Lshortfile),Error: log.New(errorLog, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile),}, nil
}func main() {logger, err := NewLogger("info.log", "error.log")if err != nil {log.Fatalf("无法创建日志记录器: %v", err)}logger.Info.Println("服务启动成功")logger.Error.Println("数据库连接失败:超时")
}
输出示例:
info.log
文件:
INFO: 2024/12/09 12:00:00 main.go:30: 服务启动成功
error.log
文件:
ERROR: 2024/12/09 12:00:00 main.go:31: 数据库连接失败:超时
总结
- log 包提供了基础的日志记录功能,适合简单的日志需求。
- 通过 log.New 和 log.SetOutput,可以实现更灵活的日志记录方式。
- 在企业中,通常需要将 log 包与日志管理系统(如 ELK、Fluentd)结合使用,实现更高级的日志处理。
代码案例
package _caseimport ("log""os"
)func init() {log.SetFlags(log.Ldate | log.Ltime | log.Llongfile)log.SetOutput(os.Stderr)
}func LogCase() {//log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)log.Println("带有日期、时间和文件信息的日志:")a, b := -1, -11_, err := sum(a, b)if err != nil {log.Println(err)log.Fatal(err) // fatal 打印日志后会导致程序的退出}
}