美文网首页
微服务框架 go-zero logx 日志组件剖析

微服务框架 go-zero logx 日志组件剖析

作者: 阿兵云原生 | 来源:发表于2023-08-25 23:22 被阅读0次

    addTenant api 和 rpc 的实现

    上一篇我们说到咱们还剩下 addTenant 功能还未实现,不知道有没有兄弟感兴趣去实验一波的,本篇文章进行简要补充

    根据上一篇文章分析,其实我们只需要执行如下几步即可:

    1. 编写 tenant.api,提供外部 addTenant 的 http 接口
    • 编写 tenant.api

    提供一个 POST http 的接口 / api /tenant/addtenant

    type (
            AddTenantReq {
                    Name string `json:"name"`
                    Addr string `json:"addr"`
            }
            AddTenantRsp {
                    Id string `json:"id"`
            }
    )
    service tenant {
            @handler addTenant
            post /api/tenant/addtenant(AddTenantReq) returns (AddTenantRsp)
    
    • goctl 生成 api 代码
    goctl api go -api tenant.api  -dir .
    
    1. 修改 api 的配置和逻辑层,让 api 层去调用之前写好的 rpc 接口 即可

    对于配置可以模仿上一篇文章 order.api 的配置进行修改,另外只需要调整 addTenant 的 logic 层即可

    func (l *AddTenantLogic) AddTenant(req *types.AddTenantReq) (*types.AddTenantRsp, error) {
       // todo: add your logic here and delete this line
       rsp,err :=l.svcCtx.TenantRpc.AddTenant(l.ctx, &tenant.AddTenantReq{
          Name: req.Name,
          Addr: req.Addr,
       })
       if err !=nil{
          return nil,err
       }
       return &types.AddTenantRsp{Id: rsp.Id},nil
    }
    

    具体的代码案例可以访问地址:https://github.com/qingconglaixueit/my_test_Demo

    下面我们来看是 go-zero 中 日志组件 logx 的剖析

    logx 日志组件剖析

    对于 logx 日志组件,分别从如下几个方面来聊一聊我的理解,如果描述有不当的地方,还请多加评论多加交流

    • Go-zero 中 logx 是如何使用的?
    • Logx 基本的数据结构
    • Logx 的默认接口实现
    • Logx 日志存储位置,以及自定义存储日志位置的实现
    • Logx 实现自定义接口的方式

    Go-zero 中 logx 是如何使用的?

    我们以之前的 demo ,关于 tenant 的 rpc 部分作为例子,追踪一下代码,是如何走到日志部分的逻辑的

    可以看到在 tenant.go 的文件中,做的是服务的启动

    [图片上传失败...(image-5b9bae-1693063255050)]

    [图片上传失败...(image-18c67c-1693063255050)]

    zrpc.MustNewServer 实际上是调用 go-zero 的 zrpc 包 的 NewServer 函数,传入的参数是

    • c RpcServerConf , 我们 rpc 服务的配置,就是咱们项目中的 etc/tenant.yaml

    [图片上传失败...(image-d093fd-1693063255050)]

    今天不聊关于 RpcServerConf 的结构,咱们重点说说 logx

    • register internal.RegisterFn 注册服务的回调函数

    NewServer 函数做了如下几件事情:

    • RpcServerConf 配置数据的有效性检查
    • 初始化 metrics 的 options
    • 设置服务名,注册 etcd 服务,服务名就是上述配置文件中的 Name 字段
    • c.SetUp() 启动整个服务

    对于 logx 日志组件的启动就是在 c.SetUp() 中完成

    [图片上传失败...(image-53e893-1693063255050)]

    Logx 基本的数据结构

    继续看到 logx.SetUp() 中的具体实现 , 函数需要传入的数据结构是这样的 LogConf

    [图片上传失败...(image-37766b-1693063255050)]

    type LogConf struct {
       ServiceName         string `json:",optional"`
       Mode                string `json:",default=console,options=[console,file,volume]"`
       Encoding            string `json:",default=json,options=[json,plain]"`
       TimeFormat          string `json:",optional"`
       Path                string `json:",default=logs"`
       Level               string `json:",default=info,options=[info,error,severe]"`
       Compress            bool   `json:",optional"`
       KeepDays            int    `json:",optional"`
       StackCooldownMillis int    `json:",default=100"`
    }
    
    • ServiceName:设置服务名称,可选。在 volume 模式下,该名称用于生成日志文件。在 rest/zrpc 服务中,名称将被自动设置为 restzrpc 的名称。
    • Mode:输出日志的模式,默认是 console

      • console 模式将日志写到 stdout/stderr
      • file 模式将日志写到 Path 指定目录的文件中
      • volume 模式在 docker 中使用,将日志写入挂载的卷中
    • Encoding: 指示如何对日志进行编码,默认是 json

      • json模式以 json 格式写日志
      • plain模式用纯文本写日志,并带有终端颜色显示
    • TimeFormat:自定义时间格式,可选。默认是 2006-01-02T15:04:05.000Z07:00
    • Path:设置日志路径,默认为 logs
    • Level: 用于过滤日志的日志级别。默认为 info

      • info,所有日志都被写入
      • error, info 的日志被丢弃
      • severe, infoerror 日志被丢弃,只有 severe 日志被写入
    • Compress: 是否压缩日志文件,只在 file 模式下工作
    • KeepDays:日志文件被保留多少天,在给定的天数之后,过期的文件将被自动删除。对 console 模式没有影响
    • StackCooldownMillis:多少毫秒后再次写入堆栈跟踪。用来避免堆栈跟踪日志过多

    另外对于 SetUp 函数做了如下几件事:

    [图片上传失败...(image-752a32-1693063255050)]

    • 设定日志等级
    • 初始化时间格式
    • 根据编码方式初始化存储日志编码类型
    • 根据设定的模式来初始化 Writer 句柄

    Logx 的默认接口实现

    对于 logx 打印日志的具体接口定义在:logx 包的 logger.go 文件中

    [图片上传失败...(image-2b415c-1693063255050)]

    对于上述接口,根据需要传递的参数我们可以分为如下几类:

    • Error, Info, Slow: 将任何类型的信息写进日志,使用 fmt.Sprint(...) 来转换为 string
    • Errorf, Infof, Slowf: 将指定格式的信息写入日志
    • Errorv, Infov, Slowv: 将任何类型的信息写入日志,用 json marshal 编码
    • Errorw, Infow, Sloww: 写日志,并带上给定的 key:value 字段
    • WithContext:将给定的 ctx 注入日志信息,例如用于记录 trace-idspan-id
    • WithDuration: 将指定的时间写入日志信息中,字段名为 duration

    例如接口名后缀带有 w 的,是需要咱们传入 key:value 的,例如传入的结构是这样的:

    [图片上传失败...(image-fa7f05-1693063255050)]

    实际上我们可以看到在 logx 源码中,其实有很多文件都已经根据自己的使用情况去实现了上述 Logger 接口

    [图片上传失败...(image-7cdfff-1693063255050)]

    举一个 traceLogger 的例子

    实际上我们可以直接看到,我们之前实现的 GetTenant rpc 方法

    [图片上传失败...(image-3e7adb-1693063255050)]

    [图片上传失败...(image-85d02f-1693063255050)]

    我们可以看到当调用了NewGetTenantLogic 方法之后,实际上是会调用 logx.WithContext(ctx) 初始化一个 traceLogger 的句柄

    traceLogger 实现了上述 Logger 接口, 因此,当我们需要在 rpc 中打印日志的时候,我们可以这样来使用

    [图片上传失败...(image-da7df4-1693063255050)]

    这个时候,实际上是调用的 traceLogger 对应的实现代码

    [图片上传失败...(image-746831-1693063255050)]

    我们可以看到,打印出来的日志,是我们所期望的信息

    此处的字段对应含义是这样的:

    [图片上传失败...(image-d35dea-1693063255050)]

    • Timestamp

    时间戳

    • Level

    日志等级

    • Duration

    时间间隔

    • Caller

    日志调用者

    • Content

    具体的日志信息

    仔细查看上述日志,我们可以发现还有 trace 和 span 字段也打印出来了,但是 logEntry 为什么没有定义呢

    咱们稍微追一下代码,不难看出,是 traceLogger 内部的 info 函数进行日志信息的拼接

    [图片上传失败...(image-56ed41-1693063255050)]

    [图片上传失败...(image-15c785-1693063255050)]

    Logx 自定义存储日志位置 和 实现自定义接口的方式

    Logx 自定义存储日志位置 和 实现自定义接口的方式其实我在这里就不需要过多的解释了,简单说明一下实现手段就可以了,有必要的话咱们可以查看 go-zero 官方文档 https://go-zero.dev/cn/docs/component/logx/

    自定义存储日志位置

    对于咱们需要修改日志的输出位置,实际上我们可以仔细思考一下,对于日志的数据,go-zero 还是使用的 golang io 包中的 Writer 接口

    咱们只需要定义对象,去实现 Writer 接口 中的 Write(p []byte) (n int, err error) 方法就可以了

    [图片上传失败...(image-255a4-1693063255050)]

    官网也给了我们例子,例如咱们实现输出的日志往 kafka 里面吐,我们就可以这样

    [图片上传失败...(image-8aa469-1693063255050)]

    实现自定义接口

    实现自定义接口,咱们其实刚才看 traceLogger 的实现方式,我们就能领悟到, traceLogger 去实现 Logger 接口中的方法,并且加入自己自定义的逻辑,例如加上了 trace 和 span

    那么对于我们自定义接口,其实也是非常容易的,照葫芦画瓢即可了

    \

    感谢阅读,欢迎交流,点个赞,关注一波 再走吧

    欢迎点赞,关注,收藏

    朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

    [图片上传失败...(image-f5fa7e-1693063255050)]

    好了,本次就到这里

    技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

    我是阿兵云原生,欢迎点赞关注收藏,下次见~

    \

    相关文章

      网友评论

          本文标题:微服务框架 go-zero logx 日志组件剖析

          本文链接:https://www.haomeiwen.com/subject/inpbmdtx.html