如何在golang中打印grpc详细日志
最近捣鼓fabric,在一个tls证书问题上纠结挺久,连接orderer服务时候,grpc日志总是冷冰冰的显示这个信息
Orderer Client Status Code: (2) CONNECTION_FAILED. Description
真想请它告诉我,这么个错误码,到底有啥用?!
真是日志用时方恨少,这种时候,我们就需要详细的日志告诉我们到底哪儿出错了是不是?一番百度之后,参考了一篇大神的文章后,终于把问题解决了。
咱们开始上手吧!
思路
grpc包含了grpclog包,用于其日志的处理,同时定义了LoggerV2的接口。
因此,只要实现LoggerV2的接口,并通过SetLoggerV2(l LoggerV2)接口将实现的对象设置到grpclog包中,就可以自定义日志输出,同时上层应用也可以使用grpclog进行业务日志打印。
实现
就拿fabric-sdk-go的源码来举例:
1.添加LoogerV2接口实现
我们可以在util目录下添加文件grpclogger.go,其中内容如下
目录和名字不重要,关键是内容
结构体名称任意,之所以取名
ZapLogger,是因为我参照的文章使用了uber的zaplogger实现(而我们只使用了fabric-sdk-go中的实现)
package util
import (
"github.com/hyperledger/fabric-sdk-go/pkg/common/logging"
)
type ZapLogger struct {
logger logging.Logger
}
// NewZapLogger 创建封装了zap的对象,该对象是对LoggerV2接口的实现
func NewZapLogger(logger *logging.Logger) *ZapLogger {
return &ZapLogger{
logger: *logger,
}
}
// Info returns
func (zl *ZapLogger) Info(args ...interface{}) {
zl.logger.Info(args)
}
// Infoln returns
func (zl *ZapLogger) Infoln(args ...interface{}) {
zl.logger.Info(args...)
}
// Infof returns
func (zl *ZapLogger) Infof(format string, args ...interface{}) {
zl.logger.Infof(format, args...)
}
// Warning returns
func (zl *ZapLogger) Warning(args ...interface{}) {
zl.logger.Warn(args...)
}
// Warningln returns
func (zl *ZapLogger) Warningln(args ...interface{}) {
zl.logger.Warn(args...)
}
// Warningf returns
func (zl *ZapLogger) Warningf(format string, args ...interface{}) {
zl.logger.Warnf(format, args...)
}
// Error returns
func (zl *ZapLogger) Error(args ...interface{}) {
zl.logger.Error(args...)
}
// Errorln returns
func (zl *ZapLogger) Errorln(args ...interface{}) {
zl.logger.Error(args...)
}
// Errorf returns
func (zl *ZapLogger) Errorf(format string, args ...interface{}) {
zl.logger.Errorf(format, args...)
}
// Fatal returns
func (zl *ZapLogger) Fatal(args ...interface{}) {
zl.logger.Fatal(args...)
}
// Fatalln returns
func (zl *ZapLogger) Fatalln(args ...interface{}) {
zl.logger.Fatal(args...)
}
// Fatalf logs to fatal level
func (zl *ZapLogger) Fatalf(format string, args ...interface{}) {
zl.logger.Fatalf(format, args...)
}
// V reports whether verbosity level l is at least the requested verbose level.
func (zl *ZapLogger) V(v int) bool {
return false
}
2、将实现的对象设置到grpclog包中
如前文所述,我们通过SetLoggerV2(l LoggerV2)接口将实现的对象设置到grpclog包中
在将进行grpc操作的方法里,添加相关代码。
这样的文件可以是
# 文件: pkg\fab\comm\connector.go
func (cc *CachingConnector) createConn(ctx context.Context, target string, opts ...grpc.DialOption) (*cachedConn, error)
添加如下代码:
var logger = logging.NewLogger("grpcLogger")
grpclog.SetLoggerV2(util.NewZapLogger(logger))
3、试一试是否成功?
随后,我的程序得到了这样的日志
[grpcLogger] 2019/02/13 18:53:24 UTC - util.(*ZapLogger).Warningf -> WARN grpc:
addrConn.createTransport failed to connect to {ord1-yc-leader-hlf-ord.yc-leader:7050 0 <nil>}.
Err :connection error: desc = "transport: authentication handshake failed:
x509: certificate is valid for ord1-yc-leader-hlf-ord.yc-leader, not ord1-yc-leader-hlf-ord".
Reconnecting...
可以看到,报错原因就很详细了。
大功告成!
参考文章:
如何在golang中打印grpc详细日志的更多相关文章
- iOS中打印系统详细日志
Q:如何打印当前的函数和行号? A:我们可以在打印时使用一些预编译宏作为打印参数,来打印当前的函数和行号.如: 1 NSLog(@"%s:%d obj=%@", __func__, ...
- golang中打印格式化的一些占位符
package main import ( "fmt" ) func main() { var a byte = 255 // byte = uint8 rune = int32 ...
- golang 中 channel 的详细使用、使用注意事项及死锁分析
目录 1.什么是 channel,介绍管道 2.channel 的基本使用 3.channel 的使用场景 4.使用 channel的注意事项及死锁分析 什么是 channel 管道 它是一个数据管道 ...
- 如何在shell中打印出带颜色的字符?
先看如下的效果: 方法: 先看如下的脚本sh3.sh: #!/bin/bash echo "peng" echo "$(color bold yellow) ------ ...
- windows环境变量如何在cmd中打印
在windows的cmd下,用"set"命令可以得到全部的环境变量,如何想得到某个环境变量,直接这样"set path"就可以了. set不仅如何,还有其他功能 ...
- 在EF6.0中打印数据库操作日志
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 如何在Rust中打印变量的类型?
#![feature(core_intrinsics)] fn print_type_of<T>(_: T) { println!("{}", unsafe { std ...
- JNI的native代码中打印日志到eclipse的logcat中
1 添加ndk对log支持若需要添加ndk对log的支持,只需要通过以下2步即可实现. 1.1 修改Android.mk如生成的库文件是“.so文件”,则在Android.mk中添加如下内容:LOCA ...
- Golang中的自动伸缩和自防御设计
Raygun服务由许多活动组件构成,每个组件用于特定的任务.其中一个模块是用Golang编写的,负责对iOS崩溃报告进行处理.简而言之,它接受本机iOS崩溃报告,查找相关的dSYM文件,并生成开发者可 ...
随机推荐
- 一个典型的后台软件系统的设计复盘——(三)打通任督二脉-context
武侠小说练功讲究打通任督二脉.程序设计练到一定程度也讲究打通任督二脉.好奇心强的同学可以搜搜“打通任督二脉有什么感觉”. spring的任督二脉ApplicationContext 最经典的任督二脉莫 ...
- python 字符编码、格式化
数据类型-布尔值一个布尔值只有True.False两种值,要么是True,要么是False 布尔值可以用and.or和not运算 空值是Python里一个特殊的值,用None表示 Python对b ...
- 【转】[C++]实现委托模型
原文地址:http://www.cnblogs.com/zplutor/archive/2011/09/17/2179756.html 我对.Net的委托模型印象很深刻,使用委托,可以快速实现观察者模 ...
- OKEX期现对冲JS源代码分享(基于Fmz, Botvs实现)
什么是期现对冲?此策略风险和收益如何?期现对冲是利用期货和现货之间存在的差价进行套利.因为在交割日的时候,期货会按现货价格成交,当期货和现货一旦出现差价时,就可以通过做空期货做多现货(或做多期货卖出现 ...
- 一直在用的一个javascript网站
http://www.dottoro.com/ 很不错,例子丰富,解释详细,全面:非常好的参考资料站.
- Kill占用指定端口的进程的方法
(1)查询占用指定端口进程的PID 打开cmd命令行,输入netstat -ano|findstr 8080(指定端口号) 最后一列即为占用该端口的进程的PID (2)KILL指定PID的进程 紧接着 ...
- Android进阶笔记16:onInterceptTouchEvent、onTouchEvent与onTouch
1. onTouch方法:onTouch方法是View的 OnTouchListener借口中定义的方法,处理View及其子类被touch是的事件处理.当一个View绑定了OnTouchLister后 ...
- 2018.09.23模拟总结(T2)
T1,T3我就不说啦,反正也不会.主要想讲的是T2. T2用了一个神奇的算法:折半搜索. 因为这个坑爹的数据范围告诉我们暴搜或是状压会TLE,而一半刚好能卡过去. 折半搜索其实跟暴搜没什么区别,就是折 ...
- CQRS轻量级框架【CQRSlite】学习使用小记
前言 这几天在研究DDD和CQRS.快把我绕晕了.发现国外的好文质量还是挺高的.之所以先体验CQRSlite这个小框架,是因为看了一位大神写的文章:https://www.codeproject.co ...
- mysql.sock问题
Can't connect to local MySQL server through socket '/tmp/mysql.sock' 上述提示可能在启动mysql时遇到,即在/tmp/mysql. ...