Go 语言零基础入门:标准库 log 包完全教程

Go 语言零基础入门:标准库 log 包完全教程

作为 Go 开发者,日志是我们排查问题、监控程序运行的核心工具。Go 语言内置了开箱即用的标准库 log,无需安装任何第三方包,一行代码就能打印日志,非常适合零基础入门和小型项目使用。

这篇文章会从零开始,带你全面掌握 Go 标准日志库的所有核心用法,每个代码示例都附带运行结果 + 结果解释,看完就能直接在项目中落地使用。

一、什么是 log 包?

log 是 Go 语言标准库自带的日志包 ,位于 log 目录下,核心作用:

  1. 打印程序运行日志、错误信息、调试信息
  2. 支持输出到控制台、文件、自定义输出流
  3. 自带时间、文件名、行号等日志前缀
  4. 轻量无依赖,所有 Go 环境直接使用

它的定位是轻量基础日志工具,适合学习、小工具、微服务基础日志打印,是 Go 开发者必须掌握的基础技能。


二、快速入门:第一个日志程序

1. 导入包

使用前只需要导入标准库:

go 复制代码
import "log"

2. 最简单的日志打印

go 复制代码
package main

// 导入日志包
import "log"

func main() {
	// 打印普通日志
	log.Println("程序启动成功!")
	log.Println("当前正在执行核心逻辑")
}
运行结果
复制代码
2025/12/18 10:00:00 程序启动成功!
2025/12/18 10:00:00 当前正在执行核心逻辑
结果解释
  1. Go 标准日志默认自带时间戳2025/12/18 10:00:00),无需手动配置
  2. log.Println() 会自动换行,和 fmt.Println() 用法一致
  3. 直接运行即可输出,无需任何初始化配置

三、log 包核心函数(必学)

log 包提供了 3 组最常用的打印函数,分别对应普通日志、格式化日志、致命错误日志,零基础优先掌握这几组。

1. 普通打印:Print/Println/Printf

这是最常用的日志函数,和 fmt 包用法几乎一致:

  • Print():直接打印,不自动换行
  • Println():打印并自动换行
  • Printf():格式化打印(支持占位符)
go 复制代码
package main

import "log"

func main() {
	name := "Go日志教程"
	version := 1.0

	// 普通打印
	log.Print("这是 Print 日志")
	// 换行打印
	log.Println("这是 Println 日志")
	// 格式化打印(和 fmt.Printf 用法一样)
	log.Printf("课程名称:%s,版本:%.1f", name, version)
}
运行结果
复制代码
2025/12/18 10:02:30 这是 Print 日志2025/12/18 10:02:30 这是 Println 日志
2025/12/18 10:02:30 课程名称:Go日志教程,版本:1.0
结果解释
  1. log.Print() 不会自动换行,所以两条日志连在了一起
  2. log.Println() 自动换行,格式更清晰
  3. log.Printf() 支持 %s(字符串)、%f(浮点数)等占位符,格式化输出变量

2. 致命错误日志:Fatal/Fatalln/Fatalf

作用 :打印日志后,直接终止程序 (等价于 print() + os.Exit(1))。

适合:程序遇到无法恢复的严重错误(如配置文件丢失、数据库连接失败)。

go 复制代码
package main

import "log"

func main() {
	// 打印错误信息并退出程序
	log.Fatalln("数据库连接失败,程序退出!")
	
	// 这行代码永远不会执行
	log.Println("程序继续运行")
}
运行结果
复制代码
2025/12/18 10:03:10 数据库连接失败,程序退出!
结果解释
  1. 执行 log.Fatalln() 后,程序直接退出
  2. 后面的 log.Println("程序继续运行") 完全不会执行
  3. 退出码为 1,代表程序异常退出

3. 恐慌日志:Panic/Panicln/Panicf

作用 :打印日志,然后触发 panic(程序崩溃,可被 recover 捕获)。

适合:代码逻辑异常、空指针、数组越界等运行时错误。

go 复制代码
package main

import "log"

func main() {
	log.Panicln("发生严重逻辑错误!")
}
运行结果
复制代码
2025/12/18 10:04:20 发生严重逻辑错误!
panic: 发生严重逻辑错误!

goroutine 1 [running]:
log.Panicln(0x14000010000?, 0x1?, 0x1?)
结果解释
  1. 先打印日志信息
  2. 然后抛出 panic 崩溃信息,包含崩溃的代码位置
  3. panic 可以用 recover() 捕获修复,而 Fatal 不能

四、自定义日志格式(进阶)

默认日志只有时间,我们可以自定义日志前缀、显示文件名/行号、自定义分隔符,让日志更清晰。

1. 设置日志前缀

log.SetPrefix() 给所有日志加统一前缀,方便区分服务/模块。

go 复制代码
package main

import "log"

func main() {
	// 设置日志前缀
	log.SetPrefix("[订单服务] ")
	
	log.Println("订单创建成功")
	log.Println("订单支付完成")
}
运行结果
复制代码
[订单服务] 2025/12/18 10:05:00 订单创建成功
[订单服务] 2025/12/18 10:05:00 订单支付完成
结果解释
  1. 所有日志前面都加上了统一前缀 [订单服务]
  2. 多模块项目中,可通过前缀快速区分日志来源

2. 设置日志选项(显示行号、文件名)

log.SetFlags() 开启高级日志信息,支持的参数:

  • log.Ldate:日期(默认)
  • log.Ltime:时间(默认)
  • log.Lmicroseconds:微秒精度
  • log.Llongfile:完整文件路径+行号
  • log.Lshortfile:文件名+行号(推荐)
  • log.LUTC:使用 UTC 时间
  • log.LstdFlags:默认格式(日期+时间)

示例:开启文件名 + 行号 + 时间

go 复制代码
package main

import "log"

func main() {
	// 设置格式:日期 + 时间 + 文件名+行号
	log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
	
	log.Println("这是带行号的日志")
}
运行结果
复制代码
2025/12/18 10:10:00 main.go:8 这是带行号的日志
结果解释
  1. 日志中新增了 main.go:8,代表代码在 main.go 文件第 8 行
  2. 调试报错时,能直接定位到代码位置,大幅提升效率

3. 组合使用:前缀 + 格式

go 复制代码
package main

import "log";

func main() {
	// 1. 设置前缀
	log.SetPrefix("[用户服务] ")
	// 2. 设置格式
	log.SetFlags(log.LstdFlags | log.Lshortfile)
	
	log.Println("用户登录成功")
}
运行结果
复制代码
[用户服务] 2025/12/18 10:12:10 main.go:10 用户登录成功
结果解释
  1. 同时包含服务前缀 + 时间 + 文件名+行号 + 日志内容
  2. 格式完整,生产环境调试非常实用

五、日志输出到文件(实战必备)

默认日志打印在控制台,生产环境需要把日志保存到文件log 包支持直接输出到文件。

完整示例:日志写入文件

go 复制代码
package main

import (
	"log"
	"os";
)

func main() {
	// 1. 创建/打开日志文件
	logFile, err := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		log.Fatalln("日志文件创建失败:", err)
	}
	defer logFile.Close()

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

	// 3. 打印日志
	log.Println("程序启动")
	log.Println("业务逻辑执行中")
	log.Println("程序退出")
}
运行结果(控制台无输出)
复制代码
(控制台空白)
结果解释
  1. 控制台不会打印任何内容,所有日志写入 app.log 文件

  2. 打开 app.log 文件,内容如下:

    2025/12/18 10:13:20 程序启动
    2025/12/18 10:13:20 业务逻辑执行中
    2025/12/18 10:13:20 程序退出

  3. os.O_APPEND 表示追加写入,不会覆盖之前的日志


六、创建自定义日志器(多日志隔离)

如果你的项目有多个模块 (订单、用户、支付),需要分开打印日志,可以创建多个独立日志器

使用 log.New() 创建自定义 Logger:

go 复制代码
package main

import (
	"log"
	"os";
)

func main() {
	// 1. 创建订单服务日志器
	orderLog := log.New(os.Stdout, "[订单] ", log.LstdFlags|log.Lshortfile)
	// 2. 创建用户服务日志器
	userLog := log.New(os.Stdout, "[用户] ", log.LstdFlags|log.Lshortfile)

	// 分别打印
	orderLog.Println("订单已提交")
	userLog.Println("用户已注册")
}
运行结果
复制代码
[订单] 2025/12/18 10:15:00 main.go:12 订单已提交
[用户] 2025/12/18 10:15:00 main.go:13 用户已注册
结果解释
  1. 两个日志器完全独立,前缀、格式互不影响
  2. 多模块项目中,可轻松区分不同模块的日志
  3. 还可以给不同模块设置不同的日志文件

七、log 包完整使用总结(速查表)

函数/方法 作用 运行特点
log.Println() 普通换行日志 程序继续运行
log.Printf() 格式化普通日志 程序继续运行
log.Fatalln() 打印日志并退出程序 直接终止程序
log.Panicln() 打印日志并触发 panic 程序崩溃,可捕获
log.SetPrefix() 设置日志前缀 全局生效
log.SetFlags() 设置日志格式(日期、行号、文件) 显示更多调试信息
log.SetOutput() 设置日志输出(文件/控制台) 控制台无输出,写入文件
log.New() 创建自定义独立日志器 多模块日志隔离

八、log 包适合什么场景?

推荐使用

  1. Go 语言初学者学习
  2. 小型工具、脚本
  3. 简单微服务、后台服务
  4. 快速调试、打印运行信息

不推荐

  1. 大型分布式系统
  2. 需要结构化日志(JSON)、日志分级(Debug/Info/Warn/Error)
  3. 需要日志切割、远程上报

大型项目推荐:zaplogrus 等第三方日志库,但学习标准 log 包是基础


九、零基础完整实战代码

go 复制代码
package main

import (
	"log"
	"os";
)

func main() {
	// 打开日志文件
	file, err := os.OpenFile("server.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		log.Fatalln("日志文件异常:", err)
	}
	defer file.Close()

	// 自定义日志
	logger := log.New(file, "[Go服务] ", log.Ldate|log.Ltime|log.Lshortfile)

	// 业务日志
	logger.Println("服务器启动成功")
	logger.Printf("监听端口:%d", 8080)
	logger.Println("请求处理完成")
	logger.Fatalln("数据库崩溃,程序终止")
}
运行结果

控制台无输出,server.log 文件内容:

复制代码
[Go服务] 2025/12/18 10:20:10 main.go:18 服务器启动成功
[Go服务] 2025/12/18 10:20:10 main.go:19 监听端口:8080
[Go服务] 2025/12/18 10:20:10 main.go:20 请求处理完成
[Go服务] 2025/12/18 10:20:10 main.go:21 数据库崩溃,程序终止

总结

  1. Go 标准库 log 开箱即用,无需第三方依赖,零基础首选
  2. 核心函数:Print/Printf(普通)、Fatal(退出)、Panic(崩溃)
  3. 可自定义前缀、格式、输出文件,满足基础生产需求
  4. 多模块可用 log.New() 创建独立日志器,实现日志隔离
  5. 每个示例都能直接复制运行,结果清晰易懂

标准日志包是 Go 开发的基础技能,掌握它,你就能轻松给程序添加专业的日志功能啦!

相关推荐
会编程的土豆1 小时前
Go 语言匿名函数详解
c++·golang·xcode
会编程的土豆1 小时前
Go 语言闭包(Closure)详解
c++·golang·xcode
右耳朵猫AI1 小时前
Golang技术周刊 2026年第20周
开发语言·后端·golang
会编程的土豆1 小时前
Redis 常用操作笔记(Go 开发实战)
redis·笔记·golang
喵了几个咪2 小时前
Headless 后端实践:基于Go的企业级多栈管理系统脚手架
开发语言·vue.js·后端·golang·reactjs·gowind
小小龙学IT2 小时前
Go 并发模式深度解析:Fan-out/Fan-in 高效处理大规模数据流
开发语言·后端·golang
OxyTheCrack13 小时前
【Golang】简述make与new内置函数以及两者的区别
开发语言·golang
会编程的土豆16 小时前
Go 方法接收者超清晰笔记(类型名 vs 变量名)
开发语言·笔记·golang
程序员卷卷狗18 小时前
Java转Go面试速记:Go基础22问,一篇理清高频易错点一篇理清高频易错点
java·面试·golang