译|Let’s talk about logging

简介: 译|Let’s talk about logging

本文受 Nate Finch started on the Go Forum 的一个话题启发。本文专注于 Go,但是如果你能看透,我认为这里提出的想法是广泛适用的。

Why no love ?

Go 的 log package 没有日志级别,你必须自己手动添加 debug、info、warn 和 error 等前缀。另外,Go 的 日志类型无法以包为基础打开或者关闭这些不同级别。通过比较,让我们看一些第三方的替代品:

Google 的 glog 提供以下级别:

  • Info
  • Warning
  • Error
  • Fatal (终止程序)

看看另外一个库, 我们为 Juju 开发的 loggo,提供以下级别:

  • Trace
  • Debug
  • Info
  • Warning
  • Error
  • Critical

Loggo 还提供了根据每个包调整日志的详细程度的功能。

因此,以上两个示例显然受到其他语言的其他日志库的影响。实际上,它们的命令行可以追溯到 syslog(3),甚至更早。我认为他们是错的。

我站相反的立场。我认为_所有_日志库都不好,因为它提供了_太多_的功能。一系列令人困惑的选择,使程序员必须清楚地思考如何与未来的读者沟通,而读者将要使用他们的日志。

我认为成功的日志包需要的功能要少得多,当然需要的级别也更少。

Let’s talk about warnings

我们从最简单的一个开始。没有人需要 warning 的日志级别。

没有人阅读 warning,因为按照定义,没有出错。也许将来会出问题,但这听起来像是别人的问题。

此外,如果你在使用某种分级日志,那么为什么将级别设置为 warning? 你可以将级别设置为 info 或 error。将级别设置为 warning 是承认你可能正在以 warninng 级别打印错误日志

消除 warning 级别,因为它既可能是信息性的消息,也可能是错误的情况。(潜台词:语义不明确)

Let’s talk about fatal

Fatal 级别,有效打印消息日志,然后调用 os.Exit(1)。原则上,这意味着:

  • 其他goroutines中的defer语句不会运行。
  • 缓冲区不刷新。
  • 临时文件和目录不会被删除。

实际上,log.Fatal 的详细程度要比 panic 少,但在语义上却等同于它。

普遍认为,库不应该使用 panic1,但是如果调用 log.Fatal2 具有相同的效果,那么当然也应该将其定为非法。

解决此清理问题的建议是,可以通过在日志系统中注册 shutdown handler,但如此导致日志系统与发生清理操作的每个位置之间紧密耦合。它也违反了关注点分离。

不要以 Fatal 级别写日志,而要将错误返回给调用方。如果错误一直冒泡到 main.main, 那么退出之前,是处理所有清理操作的正确位置。

Let’s talk about error

错误处理和日志密切相关,因此从表面上看,以 error 级别进行日志打印应该很容易解释。但,我不同意。

在 Go 中,如果函数或方法调用返回错误值,实际上您有两个选择:

  • 处理错误
  • 将错误返回给您的呼叫者(您可以选择包装错误,但这对于本次讨论并不重要)

如果您选择通过打印日志来处理错误,那么按照定义,你已经处理了它,错误就不存在了。打印错误处理错误的行为,意味着不再适合将其打印为错误日志。

让我尝试用以下代码片段说服您:

err := somethingHard()
if err != nil {
        log.Error("oops, something was too hard", err)
        return err // what is this, Java ?
}

您永远不应该在 error 级别打印任何内容的日志,因为您应该处理错误,或者将其传递回调用方。

准确地说,我并不是说您不应该将发生的情况打印日志

if err := planA(); err != nil {
        log.Infof("could't open the foo file, continuing with plan b: %v", err)
        planB()
}

但实际上 log.Infolog.Error 有异曲同工之妙。

我并不是说不要打印错误日志!相反,问题是,最小的日志API是什么?当提到错误时,我相信绝大多数打印日志为 error 级别的项目,都是通过这种简单地方式完成的,因为它们与错误相关。实际上,它们只是提供信息,意味着可以从API中删除以 error 级别打印日志。

What’s left ?

我们已经排除了 warning,认为不应该以 error 级别打印任何内容的日志,并且表明只有应用程序的顶层应该具有某种 log.Fatal 行为。还剩什么 ?

我认为只有两种东西您应该打印日志:

  1. 开发人员在开发或调试软件时会关心的东西。
  2. 用户在使用您的软件时关心的东西。

显然,分别是 debug 和 info 级别。

log.Info 应该简单地将该行写入日志输出。不应有将其关闭的选项,因为仅应告知用户对他们有用的事情。如果发生_无法_处理的错误,它将冒泡到 main.main, 程序终止的地方。必须在最后一条日志消息前面插入 fatal 前缀,或直接用 fmt.Fprintf 写入 os.Stderr 所带来的小小不便,不足以解释日志包需要添加 log.Fatal 方法。

log.Debug,则完全不同。由开发人员或支持工程师控制。在开发过程中,调试语句应足够多,而不必求助于 trace 或 debug2 级别。日志包应支持细粒度的控制,以启用或禁用调试,并且仅在该包或可能更精细的范围内的语句调试。

Wrapping up

如果这是推特民意调查,请您选择

  • 打印日志很重要
  • 打印日志很难

但是事实是,打印日志是两者兼而有之。解决这个问题的方法_必须_是解构和残酷地消除不必要的干扰。

你怎么看?这仅仅是疯狂到足以工作,还是纯粹是疯狂的?

Notes

  1. 一些库可能使用 panic/recover 作为内部控制流机制,但最重要的原则是它们一定不能让这些控制流操作泄漏到程序包边界之外。
  2. 具有讽刺意味的是,尽管缺少 debug 级别的输出,但 Go 标准日志包同时具有 FatalPanic 功能。在此程序包中,导致程序突然退出的功能数量超过了没有退出功能的数量。

原文:https://dave.cheney.net/2015/11/05/lets-talk-about-logging

本文作者 : cyningsun

本文地址https://www.cyningsun.com/09-27-2019/lets-talk-about-logging-cn.html

版权声明 :本博客所有文章除特别声明外,均采用 CC BY-NC-ND 3.0 CN 许可协议。转载请注明出处!

# Golang

  1. 译|There Are No Reference Types in Go
  2. Go 语言没有引用类型,指针也与众不同
  3. 译|What “accept interfaces, return structs” means in Go
  4. 如何用好 Go interface
  5. 一个优雅的 LRU 缓存实现
相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
目录
相关文章
|
安全 JavaScript 前端开发
JDK1.8的重要的新特性与功能
Java Development Kit (JDK) 1.8,也称为Java 8,是Java平台的一个重大更新,于2014年3月发布。它引入了多项新特性、新的API和性能提升
1614 3
|
8月前
|
弹性计算 监控 Cloud Native
云原生时代,“信任”才是开发者的核心基础设施:4个技术维度筑牢增长底盘
在云原生时代,信任已成为技术发展的基础设施。本文深入剖析为何“信任”决定开源项目、API与云产品的成败,并从行为一致、承诺可验证、错误修复、输出稳定四大技术维度,揭示构建长期信任的实操路径,助力开发者实现可持续增长。
414 1
|
9月前
|
数据挖掘 BI API
微店店铺所有商品API接口指南
微店商品API支持通过店铺ID获取全部商品信息,提供分页、状态筛选与多维度排序功能,适用于商品管理、数据统计及跨平台同步。返回商品ID、标题、价格、库存、主图等详细信息,助力高效运营。
|
9月前
|
安全 搜索推荐 机器人
具身智能:零基础入门睿尔曼机械臂(一)——从硬件准备到首次运行全攻略
本教程带你零基础入门睿尔曼协作机器人,涵盖RM65、RM75、RML63等全系列机型。从开箱识别核心部件、接口功能,到单人快速组装、安全接线开机,再到有线/无线连接示教器及简单拖动示教操作,步骤清晰,图文并茂。助你50秒完成启动,快速实现轨迹复现,规范关机保护设备,轻松上手协作机器人应用。
2056 0
|
6月前
|
存储 弹性计算 安全
2026年阿里云服务器租用价格:包年、包月、按量付费收费标准与活动价格
阿里云2026年推出多款特惠云服务器,其中经济型e实例2核2G配置99元/年,u1实例2核4G配置199元/年,轻量应用服务器2核2G峰值200M带宽抢购价38元/年。新老用户均可购买99元云服务器,199元云服务器限企业用户。此外,阿里云还提供加99元解锁弹性数据库和高效存储保障的套餐优惠,以及特惠建站套餐和特惠上云套餐。GPU服务器新人专享包月5折起,包年4折起优惠。购买前建议领取优惠券以降低购买成本。
|
存储 监控 安全
阿里云携手庆视互联数据迁云,助力全球业务升级
在庆视互联全球业务版图不断扩大的过程中,庆视互娱面临着部分区域数据无法上传的困境,并且对存储成本提出了新的要求。面对这一系列难题,庆视互联选择与阿里云携手,通过互联网直接以切片形式上传数据至阿里云对象存储服务(OSS),共同探索数据迁云的高效路径。
661 2
阿里云携手庆视互联数据迁云,助力全球业务升级
|
机器学习/深度学习 人工智能 安全
制造业工业4.0落地案例:AMR如何提升车间效率?
第四次工业革命为制造业带来了巨大的机遇与挑战。本文综合分析了工业4.0在制造业应用中的优势与局限,为企业更清晰地理解潜在障碍与收益提供参考。以自主移动机器人替代传统叉车为例,通过在主入口服务器、制造执行系统与仓储管理系统之间采用先进的API通信协议,不仅实现了物料搬运的智能化,还显著节省了工艺时间。通过对约15个工位的时间研究,记录到每班次节省约1.14小时。同时,时间与成本分析被用于支持企业的决策流程。成本分析基于5年周期构建了OPEX和CAPEX模型。在三种模型中,自主移动机器人的CAPEX模型被证明节省了30%的成本。
729 3
|
人工智能 图形学
PhysGen3D:清华等高校联合推出,单图秒变交互式3D场景
PhysGen3D是清华等高校联合开发的创新框架,通过单张图像重建3D场景并模拟物理行为,实现从静态图像到动态交互的突破性转换。
615 15
PhysGen3D:清华等高校联合推出,单图秒变交互式3D场景
|
XML 前端开发 测试技术
Postman
Postman是一款功能强大的API开发和测试工具,被广泛应用于软件开发的各个阶段
1090 57
|
云计算
公安部备案“网络接入服务商”和“域名商”所属地区管辖选择和填写说明
在阿里云进行公安部备案时,网络接入服务商选“阿里云计算有限公司”,区域为“浙江省杭州市余杭区”,接入方式为“租赁虚拟空间”,。域名注册若也在阿里云(原万网),服务商同样填写阿里云,区域不变
8899 4