Go 包是否应该使用 log.Fatal 以及何时使用?

2024-02-19

到目前为止我已经避免使用log.Fatal,但我最近偶然发现了这些问题;代码覆盖率 https://stackoverflow.com/questions/33873305/how-to-get-100-code-coverage-in-golang and 使用日志致命测试 https://stackoverflow.com/questions/30688554/how-to-test-go-function-containing-log-fatal.

100 个代码覆盖率问题的评论之一说:

...在绝大多数情况下log.Fatal应该只在 main 或 init 函数中使用(或者可能有些东西只能直接从它们调用)”

这引起了我的思考,所以我开始查看 Go 提供的标准库代码。有很多例子表明test库中的代码利用log.Fatal这看起来不错。测试代码之外还有一些示例,例如net/http https://golang.org/src/net/http/transport.go?h=log.Fatal#L408,如下图所示:

// net/http/transport.go 
func (t *Transport) putIdleConn(pconn *persistConn) bool {
    ...
    for _, exist := range t.idleConn[key] {
        if exist == pconn {
            log.Fatalf("dup idle pconn %p in freelist", pconn)
        }
    }
    ...
}

如果最好的做法是避免使用log.Fatal,为什么它在标准库中使用,我本以为只是返回一个错误。这对图书馆的用户来说似乎不公平os.Exit被调用并且不给应用程序提供任何清理的机会。

我可能很天真,因此我的问题作为更好的做法似乎是调用log.Panic这是可以恢复的,我理论上长期运行稳定的应用程序可能有机会浴火重生。

那么 Go 的最佳实践是关于什么时候应该使用 log.Fatal 的呢?


可能只有我这么想,但这就是我的使用方式log.Fatal。根据 UNIX 约定,遇到错误的进程应尽早失败并返回非零退出代码。这引导我遵循以下使用指南log.Fatal when…

  1. …我的任何一个都发生错误func init(),因为这些分别发生在处理导入时或调用主函数之前。相反,我只做不直接影响库或 cmd 应该做的工作单元的事情。例如,我设置日志记录并检查我们是否有健全的环境和参数。如果我们有无效标志,则无需运行 main,对吧?如果我们无法提供适当的反馈,我们应该尽早告知。
  2. …发生了我知道无法恢复的错误。假设我们有一个程序,可以创建命令行上给出的图像文件的缩略图。如果此文件不存在或由于权限不足而无法读取,则没有理由继续,并且此错误无法恢复。所以我们遵守惯例并失败了。
  3. …过程中发生的错误可能是不可逆的。我知道,这是一个软定义。让我举例说明一下。假设我们有一个实现cp,并且开始以非交互方式递归复制目录。现在,假设我们在目标目录中遇到一个文件,该文件与要复制到那里的文件具有相同的名称(但内容不同)。由于我们无法要求用户决定要做什么,并且我们无法复制该文件,因此我们遇到了问题。因为当我们以退出代码零完成时,用户会假设源目录和目标目录是精确的副本,所以我们不能简单地跳过有问题的文件。但是,我们不能简单地覆盖它,因为这可能会破坏信息。这是我们无法从用户的每个明确请求中恢复的情况,所以我会使用log.Fatal说明情况,特此遵循尽早失败的原则。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Go 包是否应该使用 log.Fatal 以及何时使用? 的相关文章

  • 在 Go 中将 float 转换为 int 时如何舍入到最近的 int

    将 float 转换为 int 时 小数点将被丢弃 有什么干净的方法可以将其四舍五入到最接近的整数 x int 3 6 应等于 4 而不是 3 int f 0 5 如果 gt 5 将导致向上舍入
  • go:找到模块但不包含包

    我正在尝试安装 go 的网络包 但收到 不包含包错误 终端截图 我咨询过 go 模块 latest 已找到但不包含包 https stackoverflow com questions 62974985 go module latest f
  • 通过 API Gateway 使用表单数据将图像发布到 Lambda 函数会导致文件无效

    I ve a 用 Go 编写的 Lambda 函数 https github com mhausenblas imgn blob master functions app uploadimg main go应该允许图像文件上传 通过 HTM
  • 使用 Golang 通道处理 HTTP 请求

    我正在尝试构建一个简单的 Golang Appengine 应用程序 它使用通道来处理每个 http 请求 原因是我希望每个请求执行合理的大型内存计算 并且每个请求都以线程安全的方式执行 即来自并发请求的计算不会混合 这一点很重要 本质上
  • golang:使用 gin 路由器服务 net.Conn

    我有一个处理传入 TCP 连接的函数 func Handle conn net Conn error 另外 我有一个初始化的 gin 路由器 带有已实现的句柄 router gin New router GET router POST Th
  • 在 Go 中修改导入的库

    我的问题 弹性节拍 https www elastic co products beats是一个用 Go 编写的日志传送程序的开源项目 它具有多种日志输出功能 包括控制台 Elasticsearch 和 Redis 我想将我自己的输出添加到
  • 使用 google.protobuf.Timestamp 在 Go 中解析带有时区偏移的日期时间戳

    我正在创建一个将使用 GRPC 和 protobuf 的 Go 应用程序 我的 RPC 服务应获取包含类型的消息google protobuf Timestamp 解析它并最终将其保存在数据库中或对其执行更多操作 我对什么被认为是该类型的有
  • 在 Go 中使用互斥锁

    我想了解互斥体是如何工作的 据我目前的理解 它是为了进行原子操作并同步对某些数据的访问 我在这里构建了一个队列数据结构的示例 https github com arnauddri algorithms blob master data st
  • Golang 优雅地关闭 HTTP 服务器并进行错误处理

    我正在让我的 HTTP 服务器正常关闭 我从帖子中获取了提示here https stackoverflow com questions 39320025 how to stop http listenandserve 并且到目前为止已经像
  • 在 Go 中生成随机、固定长度的字节数组

    我有一个字节数组 固定长度为4 token make byte 4 我需要将每个字节设置为随机字节 我怎样才能以最有效的方式做到这一点 这math rand就我而言 方法不提供随机字节函数 也许有一种内置的方法 或者我应该生成一个随机字符串
  • 检查值是否实现接口的说明

    我读过 Effective Go 和其他类似这样的问答 golang接口合规性编译类型检查 https stackoverflow com questions 17994519 golang interface compliance com
  • 为什么奇数的切片容量与偶数的切片行为不同

    我注意到 当容量为奇数时 切片的容量会以不同的方式表现 更具体地说 当向切片添加元素时 切片的容量为doubled当原始容量为偶数时 但当原容量为奇数时 容量为增加一 然后加倍 例子 s make int 28 28 s append s
  • 如何在 Go 应用程序中处理打开/关闭数据库连接?

    我的 Web API 应用程序中有一组函数 他们对 Postgres 数据库中的数据执行一些操作 func CreateUser db err sql Open postgres user postgres password passwor
  • GoQt 致命错误:QAbstractAnimation:没有这样的文件或目录

    我尝试编译 Qt 来开发桌面应用程序 我按照 Qt 网站上的官方 wiki 指南的说明进行操作 当我尝试go run示例文件夹中的示例 我收到错误 去运行 home pinkya rabbit workspace go1programs s
  • GOPATH值设置

    我用go1 3 1 windows amd64 msi安装go 安装后GOROOT是默认设置 我发现 D Programs Go bin 在 PATH 中 然后我创建一个 GOPATH 环境变量 使用 go get 命令时 出现错误 软件包
  • 鸭子在 Go 中打字

    我想写一个Join函数接受任意对象String 方法 package main import fmt strings type myint int func i myint String string return fmt Sprintf
  • 模板中的 bson.ObjectId

    我有一个具有 bson ObjectId 类型的结构 例如如下所示 type Test struct Id bson ObjectId Name string Foo string 我想在 html 模板中呈现它 Name Food a h
  • 解组转义 XML

    在 Go 中 我将如何解码此 XML 响应 我尝试过建立一个自定义UnMarshal方法在我的Answerstruct 但我运气不太好
  • GoLang ssh:尽管将其设置为 nil,但仍出现“必须指定 HosKeyCallback”错误

    我正在尝试使用 GoLang 连接到远程服务器 在客户端配置中 除了用户和密码之外 我将 HostKeyCallback 设置为 nil 以便它接受每个主机 config ssh ClientConfig User user HostKey
  • 在 Go 中初始化嵌入结构

    我有以下内容struct其中包含一个net http Request type MyRequest struct http Request PathParams map string string 现在我想初始化匿名内部结构http Req

随机推荐