在使用grpc时,有报错往往是一件很头疼的事情。虽然grpc的每个方法报错都会返回一些错误信息,但很多时候这些错误信息并不能引导我们直接发现问题的根本(尤其是排查一些连接层面的偶现问题时)。好在grpc的源码里也是有日志的,通过grpc源码中的日志,我们不但可以更深入的了解grpc的运行过程,也可以在遇到报错时更快速的定位问题。本篇我们就来研究一下,如何开启grpc的日志,并将其写入我们服务本身的日志文件中。
如何开启grpc日志
对于grpc这种使用者众多的开源项目,有问题最好的办法就是先看readme文件~
grpc的readme告诉我们,grpc的日志是环境变量控制的,想要开启日志,就要修改下面这两个环境变量。:
export GRPC_GO_LOG_VERBOSITY_LEVEL=99
export GRPC_GO_LOG_SEVERITY_LEVEL=info
我们先试试看效果如何,以grpc源码中提供的helloworld项目为例:
可以看到,在修改了两个环境变量之后,再次运行client.go,grpc源码中的日志都打印到了屏幕上,通过这些日志我们可以看到grpc从地址解析,到负载均衡,再到连接的创建与关闭的全过程。
日志是拿到了,可是打印到屏幕上,这显然不是我们想要的结果,所以我们还得再深入研究一下这个日志是怎么打印出来的。
首先,既然开启了上面两个环境变量就能使日志打印出来,那么grpc源码中和日志相关的代码肯定读取了这两个环境,因此我们先来搜索一下源码中包含这两个环境变量的地方:
// newLoggerV2 creates a loggerV2 to be used as default logger.
// All logs are written to stderr.
func newLoggerV2() LoggerV2 {
errorW := ioutil.Discard
warningW := ioutil.Discard
infoW := ioutil.Discard
logLevel := os.Getenv("GRPC_GO_LOG_SEVERITY_LEVEL")
switch logLevel {
case "", "ERROR", "error": // If env is unset, set level to ERROR.
errorW = os.Stderr
case "WARNING", "warning":
warningW = os.Std