如何使用Golang log设置日志输出格式_Golang log日志格式示例
技术百科
P粉602998670
发布时间:2026-01-01
浏览: 次 Go标准库log仅支持前缀开关和输出重定向,不支持结构化日志;需用zap等专用库实现JSON、level等字段化功能。
Go log.SetFlags() 控制日志前缀和格式
Go 标准库 log 包本身不支持自定义字段(如 JSON、level 字段),但能通过 log.SetFlags() 控制时间、文件名、行号等前缀开关。默认只输出内容,没时间戳——这是新手最常忽略的“日志看起来没格式”的原因。
-
log.Ldate | log.Ltime:输出类似2025/05/12 14:23:56 message -
log.Lshortfile:显示main.go:23;log.Llongfile显示完整路径 - 多个标志用按位或组合:
log.SetFlags(log.Lda
te | log.Ltime | log.Lshortfile) - 设为
0可完全禁用所有前缀,只留原始字符串
Go log.SetOutput() 重定向日志到文件或 stderr
默认输出到 os.Stderr,但容易和错误流混在一起。生产环境通常要写入文件,或区分 info/warn/error 流。注意:直接传 *os.File 是安全的,但别传已关闭的文件句柄,否则后续 log.Print() 会 panic 并报 write /dev/stderr: bad file descriptor。
- 写入文件:
log.SetOutput(newFile),记得用os.OpenFile(..., os.O_CREATE|os.O_APPEND|os.O_WRONLY) - 同时输出到控制台和文件?需封装
io.MultiWriter - 避免在 goroutine 中反复调用
SetOutput—— 它不是并发安全的,且会覆盖全局实例
为什么不要直接用标准 log 做结构化日志
当你需要 {"level":"info","msg":"user login","uid":1001} 这种格式时,log 包无能为力。它不解析内容,只拼接字符串前缀 + fmt.Sprint() 结果。强行用 log.Printf("{\"level\":\"info\",...}") 会导致转义混乱、无法统一字段顺序、缺失堆栈上下文。
- 推荐替代方案:
zap(高性能)、zerolog(零分配)、logrus(易上手) - 如果必须用标准库,可封装一个函数生成 JSON 字符串再交给
log.Print(),但无法享受结构化解析优势 - 注意:
log.SetPrefix()只加固定前缀(如[INFO]),不能动态插入变量
package main
import (
"log"
"os"
)
func main() {
// 启用日期、时间、短文件名
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
// 写入文件而非 stderr
f, _ := os.OpenFile("app.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
log.SetOutput(f)
defer f.Close()
log.Println("server started")
log.Printf("listening on %s", ":8080")
}
标准库 log 的格式能力仅限于前缀开关和输出目标,真要字段化、分级、采样、Hook,得换专用日志库——这点在项目初期就该明确,别等到日志查不出问题才回头重构。
# ai
# 这是
# 多个
# 当你
# 结构化
# 不出
# app
# 重定向
# 设为
# 不支持
# js
# json
# go
# golang
# Error
# 并发
# 堆
# 标准库
# 字符串
# 重构
# 为什么
# 栈
# printf
# 行号
# 封装
# 句柄
# print
# sprint
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Mac的“调度中心”与“空间”怎么用_Mac多桌面
- 如何用::实现工具类方法调用_php静态工具类设计
- Win11怎么看电池循环次数_Win11笔记本电池
- c++如何判断文件是否存在_c++ filesys
- 如何使用Golang sort排序切片_Golan
- 零基础学会Python自动化办公_高效处理Exce
- 如何在 VS Code 中正确配置并使用 NumP
- PHP cURL GET请求:正确设置请求头与身份
- Python字符串操作教程_切片拼接与格式化详解
- Mac怎么设置鼠标滚动速度_Mac鼠标设置详细参数
- Go 语言标准库为何不提供泛型 Contains
- windows如何禁用驱动程序强制签名_windo
- Python文件和流处理指南_高效读写大体积数据文
- Win11怎么设置任务栏透明_Windows11使
- 如何在Golang中实现基础配置管理功能_Gola
- Windows10怎么备份注册表_Windows1
- 如何使用正则表达式批量替换重复的 *- 模式为固定
- Windows 11如何开启文件夹加密(EFS)_
- 如何在 Pandas 中按元素交集合并两列字符串
- Win10怎样设置多显示器_Win10多显示器扩展
- C++如何使用std::optional?(处理可
- php转mp4怎么设置帧率_调整php生成mp4视
- 如何在Golang中处理模块包路径变化_Golan
- php8.4新语法match怎么用_php8.4m
- Golang如何测试HTTP中间件_Golang
- 如何在 Go 同包不同文件中正确引用结构体
- Win11怎么禁用键盘自带键盘_Win11笔记本禁
- 如何使用Golang实现微服务事件驱动_使用消息总
- Win11怎么关闭系统声音_Win11系统提示音静
- 手机php怎么转mp4_手机端php文件转mp4a
- Python列表推导式与字典推导式教程_简化代码高
- 如何使用Golang table-driven f
- Python与OpenAI接口集成实战_生成式AI
- c# F# 的 MailboxProcessor
- c++怎么操作redis数据库_c++ hired
- Windows10电脑怎么设置虚拟内存_Win10
- Win11任务栏天气怎么关闭 Win11隐藏天气小
- Win11怎么忘记WiFi网络_Win11删除已保
- Mac的“预览”如何合并多个PDF_Mac文件处理
- Windows 11怎么设置默认解压软件_Wind
- Python对象生命周期管理_创建销毁说明【指导】
- 如何在 Django 中修改用户密码后保持会话不丢
- Win10如何卸载微软拼音输入法 Win10只保留
- Windows 11如何查看系统激活密钥_Wind
- Windows 11无法安全删除U盘提示设备正在使
- Mac怎么开启“任何来源”_Mac安装未签名应用的
- Win11怎么开启空间音效_Windows11耳机
- php命令行怎么运行_通过CLI模式执行PHP脚本
- PHP主流架构怎么监控运行状态_工具推荐【操作】
- 如何在Golang中捕获JSON序列化错误_Gol

te | log.Ltime | log.Lshortfile)
QQ客服