内容简介:what 包含一组简单易用的日志记录函数,适用于跟踪代码中的各种类型的活动。what 可以打印当前函数名称,快速 Printf:格式化日期,并转储(dump)数据结构。最重要的是,默认情况下,what 相关的代码不会编译进生成环境的二进制文件中(除非你希望如此)。因此说,what 这个库是调试级别的日志记录,仅适用于开发人员。为什么会有这么一个库出现?库作者总结了两个主要原因。
简介
what 包含一组简单易用的日志记录函数,适用于跟踪代码中的各种类型的活动。what 可以打印当前函数名称,快速 Printf:格式化日期,并转储(dump)数据结构。
最重要的是,默认情况下,what 相关的代码不会编译进生成环境的二进制文件中(除非你希望如此)。因此说,what 这个库是调试级别的日志记录,仅适用于开发人员。
背景
为什么会有这么一个库出现?库作者总结了两个主要原因。
原因一:只需要两个日志级别
作者看到了 Dave Cheney 的 旧博文 。早在 2015 年,Dave 就对日志级别的用途进行了批判性研究。常见的日志记录包使用日志级别,例如 Info、Warning、Error、Fatal,甚至添加更多级别,例如 Trace,Debug 或 Critical。在一一讨论了所有这些日志级别之后,Dave 得出结论,你将只需要两个日志级别:Debug 和 Info。
为什么选择这两个?主要区别是目标受众。
- Debug 输出供开发人员在开发软件时使用
- Info 输出适用于该软件的用户
作者认为减少日志级别的想法与 Go 提倡的简单性非常吻合。实际上,Go 的标准日志包根本没有日志级别。
原因二:调试日志仅供开发人员使用
通过日志进行调试,特别是并发程序,是一种常用的手段。出于两点考虑,作者希望调试日志相关代码不会被编译进生成环境的二进制文件中:
- 性能考虑:每个日志调用都需要检查是否启用了调试日志记录。尽管这只是一个简单的 if 语句,但对于大量的调试日志调用,它可以累加起来,可能还是不能忽略;
- 安全考虑:调试日志记录会泄漏出大量信息,其中一些可能是敏感信息,而你不希望它们被撬开,不想线上环境出现。
因此,理想的调试库将提供的日志功能,应仅存在于测试二进制文件中,而不存在于生产二进制文件中。
作者在网上搜索之后,发现没有类似的日志库,因此决定编写一个。
what 包的设计思路
设计该包时考虑了下面两点:
- 提供的功能很少,名称选择上,尽量为有意义且易于记忆的;
-
可以为特定的日志函数和特定的软件包打开和关闭日志记录。想象一下,你已经在代码中添加了许多调用,但是对于下一个测试,你仅对从
what.Happens
和what.Iscalls
获取调试日志感兴趣,并且仅对于包mypkg
以减少噪音,则可以通过构建标签(build tag)和环境变量轻松实现。
下面一起看看相关的细节。
函数
该库尽可能将日志函数的数量保持在较小的水平,以便易于使用和记忆。同时添加了有助于减少样板代码的函数(例如额外的 if 语句)。让我们详细看看。
what.Happens
what.Happens()
与 log.Printf()
等效。它采用与 Printf() 相同的参数,即格式字符串和基于格式字符串中占位符的零个或多个值。
使用它来查看代码中发生的情况。
例如:
what.Happens("Connecting to %s", url)
输出如下:
2020-04-20 20:20:03 main.main: Connecting to https://studygolang.com
what.If
what.If()
类似于 what.Happens()
,但仅在第一个参数为 true 时才记录日志。
一般用它来记录有趣或异常的事情。
例如:
what.If(!found, "Loop finished, %s not found", searchString)
输出如下:
2020-04-20 20:20:03 studygolang.com/mypackage.Search: Loop finished, enlightenment not found
what.Is
what.Is()
会 dump 变量的内容。对结构体输出特别有用。
例如:
client := &http.Client{ Timeout: 10 * time.Second, } what.Is(client)
输出如下:
(*http.Client)(0xc000112e40)({ Transport: (http.RoundTripper) <nil>, CheckRedirect: (func(*http.Request, []*http.Request) error) <nil>, Jar: (http.CookieJar) <nil>, Timeout: (time.Duration) 10s })
what.Func
what.Func()
打印其调用者的名称,以及该调用方所在的文件名和行号。
例如:
func main() { what.Func() }
输出如下:
2020/04/20 20:20:31 Func main.main in line 12 of file /Users/xuxinhua/project/golang/what/main.go
启用和禁用
使用 -tags
标志在编译时启用 what 日志记录。
全部启用
要启用所有调试日志记录,请使用 -tags
编译你的代码:
go build -tags what
启用特定函数
要启用 Happens()/If(),Is(),Func() 或 Package() 中的任何一个,请将各自的构建标签或标签组合传递给 -tags
:
Function | tag |
---|---|
Happens,If | whathappens |
Is | whatis |
Func | whatfunc |
Package | whatpackage |
例如:
go build -tags whathappens,whatis
启用特定的包
很多时候,what 的调用会分散在多个包中,你可能只想获取特定包的调试日志,以专注于重要事情。这种场景下,Go 的构建标签机制没法解决,不过可以通过称为 WHAT
的环境变量来完成。
要启用特定的包进行调试日志记录,请将 WHAT 设置为导入包或导入包列表。
启动时环境变量只能读取一次,因此,如果在代码运行时更改该值,是无效的,必须重新启动后,更改才会被使用。
例如:
export WHAT=path/to/my/pkg1,github.com/studygolang/studygolang/global
每个条目都是包导入路径,就像在 import 指令中使用它一样。
生成环境禁用
what 包遵循最初描述的仅使用两个日志级别( info
和 debug
)的哲学。what 包是 debug 部分。它旨在帮助开发人员运行时观察其代码并跟踪意外行为,然后将这些代码排除在生产二进制文件之外。
对于生产环境中的任何日志输出,请使用标准的 log
包(当然,你也可以使用你喜欢的日志库),并请记住,你的代码的日志是给用户看,而不只是给开发人员看。让他们知道你的代码目前在做什么,帮助他们跟踪进展,并找出为什么此时应用程序卡住了。请勿在生产环境日志中写入超详细信息,否则您的用户将要求使用日志级别以防止产生噪音。
最后来一个简单但完整的例子
package main import ( "log" "net/http" "time" "appliedgo.net/what" ) func main() { log.Println("Start") what.Func() what.Package() what.Happens("Create HTTP client") client := &http.Client{ Timeout: 10 * time.Second, } what.Is(client) what.Happens("Client has a %f seconds timeout", client.Timeout.Seconds()) what.If(client.Jar == nil, "client has no cookie jar") log.Println("Done.") }
在本地创建一个文件夹,比如 what,将以上代码拷贝粘贴到 what 文件夹下的 main.go 文件中。
在 what 目录下执行:
$ go mod init what
接着执行:
go run -tags what main.go
将看到如下输出:
2020/04/20 20:33:12 Start 2020/04/20 20:33:12 Func main.main in line 14 of file /Users/xuxinhua/project/golang/what/main.go 2020/04/20 20:33:12 Package main 2020/04/20 20:33:12 main.main: Create HTTP client (*http.Client)(0xc00007ee40)({ Transport: (http.RoundTripper) <nil>, CheckRedirect: (func(*http.Request, []*http.Request) error) <nil>, Jar: (http.CookieJar) <nil>, Timeout: (time.Duration) 10s }) 2020/04/20 20:33:12 main.main: Client has a 10.000000 seconds timeout 2020/04/20 20:33:12 main.main: client has no cookie jar 2020/04/20 20:33:12 Done.
如果只是执行 go run main.go 则输出:
2020/04/20 20:41:04 Start 2020/04/20 20:41:04 Done.
你还可以增加新的包,通过 WHAT 环境变量来控制你想要的行为。
总结
这个库很简洁,开发调试还是不错的,其中的命名方式也很友好,库本身也值得学习学习。
差点忘了贴上该库的源码地址: https://github.com/appliedgocode/what 。
欢迎关注我的公众号:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- [译] 专为初学者设计:最小的神经网络
- Zorin OS 12.2 发布,专为 Linux 新手设计
- Ligolo:一款专为渗透测试人员设计的反向隧道
- Zorin OS 12.3 发布,专为 Linux 新手设计
- Firefox 推出新的扩展,专为隔离 Facebook 跟踪
- RhykeJS ——专为开启“实验室功能”的手势密码库
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
大连接
[美] 尼古拉斯•克里斯塔基斯(Nicholas A. Christakis)、[美] 詹姆斯•富勒(James H. Fowler) / 简学 / 中国人民大学出版社 / 2013-1 / 59.90元
[内容简介] 1. 本书是继《六度分隔》之后,社会科学领域最重要的作品。作者发现:相距三度之内是强连接,强连接可以引发行为;相聚超过三度是弱连接,弱连接只能传递信息。 2. 本书讲述了社会网络是如何形成的以及对人类现实行为的影响,如对人类的情绪、亲密关系、健康、经济的运行和政治的影响等,并特别指出,三度影响力(即朋友的朋友的朋友也能影响到你)是社会化网络的强连接原则,决定着社会化网络的......一起来看看 《大连接》 这本书的介绍吧!