Golang Go语言中日志应该统一输出到 os.Stdout,还是 os.Stderr??

发布于 1周前 作者 zlyuanteng 来自 Go语言

看网上很多例子,日志统一输出到 os.Stderr 。
当然也有 os.Stdout 的。

想请教下,在实际环境上,这两者的不同。


Golang Go语言中日志应该统一输出到 os.Stdout,还是 os.Stderr??
20 回复

生产的时候哪个都不用,走日志库发送到中央日志系统。

更多关于Golang Go语言中日志应该统一输出到 os.Stdout,还是 os.Stderr??的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


个人觉得,看软件的输出类型。
比如你的程序是服务型的(比如一个 http 服务),不靠控制台做输出或不输出管道,则 stdout 或 stderr 都可以。
如果是工具型的(比如 grep 、ffmpeg ),通过控制台输出结果的,那么日志就应该输出到 stderr ,避免和正常的 stdout 混淆了。

stdout 吧, 基本都是这么做的吧, 而且现在容器化, 也都是这么做的

我觉得应用程序亲自发到中心有点不太好。调试的时候还需要抑制这个行为

最优雅的还是 env 或者配置文件支持类似 DSN 那样的配置,支持 stdout 也支持远端集中日志,以及 format 是 json 还是 line 啥的

推荐 os.Stdout ,这样还可以用管道,让别的程序实时二次加工 /过滤你的 log 内容。

生产环境下一般往 socket 或者 file

让日志库去实现好了,应用只是调用不关心细节

stdout ,逻辑分层,输出日志就输出日志,后续的收集、分类存储没必要耦合

统一 stdout ,然后日志打印加上日志级别用于过滤

系统正常日志,输出到 os.Stdout, 系统错误日志输出到 os.Stderr , linux 上命令行程序的日志都是这个规则。

stderr 也可以,加个 2>&1 就行

这其实就是个约定问题,你可以看一下为什么系统要设计 stdout 和 stderr 两个通道,然后再看一下自己项目的设计如何利用这两个通道。

如果你打算用 systemd 、docker 等管理服务日志,用 stdout 问题不大
如果本身有 CLI 交互的就得换 stderr 了

stdout 啊,因为 go 的 panic 会输出到 stderr ,你需要单独捕获 panic 的日志的话,就不要向 stderr 里面输出任何业务信息。

1 、如果服务是容器化的,建议将容器的日志输出到 stdout 和 stderr ,这里主要有这么 2 个原因吧:( 1 )方便日志的集中管理。将容器日志输出 stdout 和 stderr 可以很方便的通过管道重定向到其它的日志管理平台,这样一来的话所有容器的日志可以集中存储和分析 ( 2 )容器化标准化。将日志输出 stdout 和 stderr 有助于将容器设计为只负责应用程序进程本身,而不用关心日志的具体实现,比如我们可以通过 sidecar 的方式收集封装服务日志

2 、具体是输出 stdout 还是 stderr ,我个人觉得可以根据日志级别来决定,比如 nginx 中有两类很重的日志:access.log 、error.log ,前者表示正常的访问日志,后者表示错误日志,一般情况我觉得我们的业务系统可以参考 nginx 的设计建立这两类日志

在Go语言中,关于日志应该统一输出到os.Stdout还是os.Stderr的问题,实际上取决于日志的用途和系统的需求。

os.Stdout(标准输出)通常用于正常的程序输出,比如程序的运行结果或数据。而os.Stderr(标准错误)则用于错误消息和诊断信息。这一区分在Unix和类Unix系统中尤为重要,因为它们允许用户通过重定向或管道将标准输出和标准错误分开处理。

对于日志来说,如果日志信息主要是用于记录程序的运行状态和调试信息,并且希望这些信息能够与程序的正常输出分开处理,那么将日志输出到os.Stderr是更合适的选择。这样做的好处是,在需要时,用户可以很容易地将日志信息与程序的正常输出分离,便于分析和调试。

然而,如果日志信息被视为程序输出的一部分,或者日志和程序输出需要合并处理,那么将日志输出到os.Stdout也是可以接受的。

综上所述,选择os.Stdout还是os.Stderr主要取决于日志的用途和系统的需求。在大多数情况下,将日志输出到os.Stderr可能更为合适,因为它更符合Unix和类Unix系统的惯例,也便于用户将日志信息与程序的其他输出分开处理。但具体选择还需根据实际应用场景来决定。

回到顶部