go基于grpc构建微服务框架-结构化日志输出

go基于grpc构建微服务框架-结构化日志输出

大家好,又见面了,我是你们的朋友全栈君。

1.结构化日志的意义

1.1 日志格式化

日志主要用于跟踪服务的运行信息,作为后端攻城狮,一般都会有一种想法,平时的时候希望日志越少越好,出问题的时候又总是抱怨,怎么才tmd这点日志,还在关键的地方没打印.

因此,日志很重要,将日志进行格式化也很重要,日志格式化主要是为了方便后续进行分析.如通过将错误码格式化到日志中,我们可以对收集后的日志分析接口的调用健康状态,将接口耗时格式化后上报,可以监控延时高的操作,并查询出关联日志进行分析.

所以只要是格式化输出,很容易有很多应用.

1.2 日志库应该有的特性

  • 高性能

这里主要是两方面,每次操作的耗时,以及每次操作分配的内存,作为日志库,两个指标都应该要极低.

  • 日志等级过滤

能通过调节日志等级打印不同级别的日志.

  • 采样率

能够设置采样率,防止服务请求增加时输出的日志量剧增,从而影响服务性能.

  • 自动切分文件

自动按一定大小切分文件,定期归档,保存一定数量文件.

基于以上几点,选择uber开源的日志库 zap.

2.集成到grpc中

2.1 思路

grpc 定义了grpclog包,并定义了LoggerV2的接口,因此,只要通过zap实现LoggerV2的接口,并通过SetLoggerV2(l LoggerV2)接口将实现的对象设置到grpclog包中,那么grpc将使用zap进行日志输出,同时上层应用也可以使用grpclog进行业务日志打印.

2.2 实现

完整代码以及使用示例见 grpc-wrapper

type ZapLogger struct {
    logger *zap.Logger
}

//创建封装了zap的对象,该对象是对LoggerV2接口的实现
func NewZapLogger(logger *zap.Logger) *ZapLogger {
    return &ZapLogger{
        logger: logger,
    }
}
func (zl *ZapLogger) Info(args ...interface{}) {
    zl.logger.Sugar().Info(args...)
}

func (zl *ZapLogger) Infoln(args ...interface{}) {
    zl.logger.Sugar().Info(args...)
}
func (zl *ZapLogger) Infof(format string, args ...interface{}) {
    zl.logger.Sugar().Infof(format, args...)
}

func (zl *ZapLogger) Warning(args ...interface{}) {
    zl.logger.Sugar().Warn(args...)
}

func (zl *ZapLogger) Warningln(args ...interface{}) {
    zl.logger.Sugar().Warn(args...)
}

func (zl *ZapLogger) Warningf(format string, args ...interface{}) {
    zl.logger.Sugar().Warnf(format, args...)
}

func (zl *ZapLogger) Error(args ...interface{}) {
    zl.logger.Sugar().Error(args...)
}

func (zl *ZapLogger) Errorln(args ...interface{}) {
    zl.logger.Sugar().Error(args...)
}

func (zl *ZapLogger) Errorf(format string, args ...interface{}) {
    zl.logger.Sugar().Errorf(format, args...)
}

func (zl *ZapLogger) Fatal(args ...interface{}) {
    zl.logger.Sugar().Fatal(args...)
}

func (zl *ZapLogger) Fatalln(args ...interface{}) {
    zl.logger.Sugar().Fatal(args...)
}

// Fatalf logs to fatal level
func (zl *ZapLogger) Fatalf(format string, args ...interface{}) {
    zl.logger.Sugar().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
}

3.最终效果

go基于grpc构建微服务框架-结构化日志输出

可以看到,日志以json格式输出,并显示了日志打印时的代码行数,同时当出现error时进行了调用栈的追踪.

参考

grpc
zap.
grpc-wrapper

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/107566.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • springboot+redis+jedis实现分布式锁小Demo

    springboot+redis+jedis实现分布式锁小Demo

    2021年7月12日
    90
  • Java哈希表以及哈希冲突

    Java哈希表以及哈希冲突文章目录Java哈希表概念冲突避免冲突哈希函数的设计方法常见哈希函数负载因子调节解决哈希冲突两种常见的方法是:闭散列和开散列哈希表和java类集的关系Java哈希表概念顺序结构以及平衡树中,元素关键码与其存储位置之间没有对应的关系,因此在查找一个元素时,必须要经过关键码的多次比较。顺序查找时间复杂度为O(N),平衡树中为树的高度,即O(logN),搜索的效率取决于搜索过程中元素的比较次…

    2022年6月22日
    33
  • Mac安装yarn

    Mac安装yarn1.全局安装yarnnpmi-gyran#查看安装是否成功yarn–version2.设置淘宝镜像,下载速度更快yarnconfigsetregistryhttps://registry.npm.taobao.com3.配置环境变量echo”PATH=$PATH:~/.yarn/bin”>>~/.bash_profile&&source.bash_profile…

    2022年5月26日
    354
  • navicat连接mysql失败是什么原因?_mysql1045错误代码

    navicat连接mysql失败是什么原因?_mysql1045错误代码1:2003错误不能连接到mysql服务解决方法:在Windows服务中将mysql服务手动打开或右键设置为开机延迟启动(连接失败一次后再连接即可成功连接)后续待补充

    2022年10月14日
    2
  • 你太强了我只能躺啊哈哈哈(超我太强的原因)

    大家好,我是二哥呀!之前在送书的时候做了一个小调查,问题是:“你是怎么认识二哥的?”我以为从知乎上了解的多一些,没想到,CSDN上的最多,看来二哥还是在CSDN上更有影响力一些,这个结果多少让我感到有些意外,因为我最近在知乎上更新得更勤快一些。写这篇文章的时候,我去CSDN上看了一眼我的主页。访问量突破了900万!按照目前的增长速度来看,年底突破1000万访问量应该没啥大问题。另外还有一些数据我觉得也挺牛逼的:原创文章数量957篇;作者总榜第12名;作者周榜第

    2022年4月10日
    40
  • 怎么把python中的列表转化为字符串(python成长记录)

    怎么把python中的列表转化为字符串(python成长记录)怎么把python中的列表转化为字符串(python成长记录)1,列表中非字符串的元素的转换方法一:使用列表推导式转换list1=[‘happy’,1,6,’sad’]list1=[str(i)foriinlist1]print(list1)结果为[‘happy’,’1′,’6′,’sad’]方法二:使用map高级函数转换list1=[‘happy’,1,6,…

    2022年5月30日
    37

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号