一、日志输出
log模块有三个日志输出函数,分别为:
- Print \ Printf \ Println
- Panic \ Panicf \ Panicln
- Fatal \ Fatalf \ Fatalln
- Printf对应普通日志,可以多条持续记录
- Panic打印后,会抛出异常,可以使用recover捕获;抛出异常后,后面的代码将不再执行。
- Fatal打印日志后,直接调用os.Exit(1) 退出程序。
1.1 普通日志
package main
import (
"log"
"os"
)
func main() {
log.Print("这是一条普通日志")
log.Printf("格式化日志: %d", 100)
log.Println("带换行的日志9")
}
1.2 Paic日志
注意:log.Panic("触发panic")执行后,程序将抛出异常,后面的代码不会执行。
defer声明的函数是延迟函数,在main函数执行完后调用,此时,可以捕获main抛出的异常。
执行好,
package main
import (
"fmt"
"log"
"os"
)
func main() {
defer func() {
if err := recover(); err != nil {
log.Println("捕获到 panic:", err)
}
}()
//输出日志并触发 panic,可被 recover 捕获, 触发后, 后面的代码将不执行。
log.Panic("触发panic")
log.Println("此条日志不会打印")
}
1.3 致命日志
注意:log.Fatal("程序终止") 执行后,程序将退出。
package main
import (
"log"
"os"
)
func main() {
log.Fatal("程序终止") // 输出日志并退出,状态码1
log.Fatalf("错误代码: %d", 404) // 同上,支持格式化
log.Fatalln("终止日志")
}
二、设置前缀、输出位置、日志格式
2.1 SetPrefix和Prefix
SetPrefix函数用于设置前缀, Prefix函数用于获取前缀
package main
import (
"fmt"
"log"
)
func main() {
log.SetPrefix("[APP] ") // 设置前缀
fmt.Println("当前前缀: ", log.Prefix())
}
2.2 设置日志输出位置
2.2.1 设置单文件输出
package main
import (
"log"
"os"
)
func main() {
file, _ := os.Create("app.log")
defer file.Close()
log.SetOutput(file)
log.Println("这条日志写入文件")
}
2.2.2 设置多方式输出
package main
import (
"io"
"log"
"os"
)
func main() {
// 输出到控制台和文件
file, _ := os.Create("fileLog.txt")
multiWrite := io.MultiWriter(os.Stdout, file)
log.SetOutput(multiWrite)
log.Println("同时输出到控制台和文件")
}
2.3 设置日志格式
常用标志常量:
- Ldate:显示日期(如 2006/01/02)
- Ltime:显示时间(如 15:04:05)
- Lmicroseconds:显示微秒
- Llongfile:完整文件名(如 /app/main.go:20)
- Lshortfile:短文件名(如 main.go:20)
- LUTC:使用 UTC 时间
package main
import "log"
func main() {
//自定义日志格式
log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds | log.Lshortfile)
log.Println("自定义格式")
}
三、自定义日志对象
通过 log.New
创建独立日志实例,避免全局设置冲突。
package main
import (
"log"
"os"
)
func main() {
// 自定义日志对象
logger := log.New(os.Stdout, "[APP] ", log.Ldate|log.Ltime|log.Lshortfile)
logger.Print("自定义日志")
file, _ := os.Create("custom.log")
logger.SetOutput(file)
logger.Println("写入文件")
}
四、模拟日志级别
标准库 log
不支持内置级别,但可通过前缀模拟。
package main
import (
"log"
"os"
)
func main() {
// 模拟日志级别
infoLog := log.New(os.Stdout, "[INFO]", log.LstdFlags)
errorLog := log.New(os.Stderr, "[ERROR]", log.LstdFlags|log.Lshortfile)
infoLog.Println("服务启动成功")
errorLog.Println("数据库连接失败")
}