addTenant api 和 rpc 的实现
上一篇咱们说到咱们还剩下 addTenant 性能还未实现,不晓得有没有兄弟感兴趣去试验一波的,本篇文章进行简要补充
依据上一篇文章剖析,其实咱们只须要执行如下几步即可:
- 编写 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 .
- 批改 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 的文件中,做的是服务的启动
zrpc.MustNewServer 实际上是调用 go-zero 的 zrpc 包 的 NewServer 函数,传入的参数是
- c RpcServerConf,咱们 rpc 服务的配置,就是咱们我的项目中的 etc/tenant.yaml
明天不聊对于 RpcServerConf 的构造,咱们重点说说 logx
- register internal.RegisterFn 注册服务的回调函数
NewServer 函数做了如下几件事件:
- RpcServerConf 配置数据的有效性查看
<!—->
- 初始化 metrics 的 options
<!—->
- 设置服务名,注册 etcd 服务,服务名就是上述配置文件中的 Name 字段
<!—->
- c.SetUp() 启动整个服务
对于 logx 日志组件的启动就是在 c.SetUp() 中实现
Logx 根本的数据结构
持续看到 logx.SetUp() 中的具体实现,函数须要传入的数据结构是这样的 LogConf
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
服务中,名称将被主动设置为rest
或zrpc
的名称。
<!—->
-
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
,info
和error
日志被抛弃,只有severe
日志被写入
<!—->
Compress
: 是否压缩日志文件,只在file
模式下工作
<!—->
KeepDays
:日志文件被保留多少天,在给定的天数之后,过期的文件将被主动删除。对console
模式没有影响
<!—->
StackCooldownMillis
:多少毫秒后再次写入堆栈跟踪。用来防止堆栈跟踪日志过多
另外对于 SetUp 函数做了如下几件事:
- 设定日志等级
<!—->
- 初始化工夫格局
<!—->
- 依据编码方式初始化存储日志编码类型
<!—->
- 依据设定的模式来初始化 Writer 句柄
Logx 的默认接口实现
对于 logx 打印日志的具体接口定义在:logx 包的 logger.go 文件中
对于上述接口,依据须要传递的参数咱们能够分为如下几类:
Error
,Info
,Slow
: 将任何类型的信息写进日志,应用fmt.Sprint(...)
来转换为string
<!—->
Errorf
,Infof
,Slowf
: 将指定格局的信息写入日志
<!—->
Errorv
,Infov
,Slowv
: 将任何类型的信息写入日志,用json marshal
编码
<!—->
Errorw
,Infow
,Sloww
: 写日志,并带上给定的key:value
字段
<!—->
WithContext
:将给定的 ctx 注入日志信息,例如用于记录trace-id
和span-id
<!—->
WithDuration
: 将指定的工夫写入日志信息中,字段名为duration
例如接口名后缀带有 w 的,是须要咱们传入 key:value 的,例如传入的构造是这样的:
实际上咱们能够看到在 logx 源码中,其实有很多文件都曾经依据本人的应用状况去实现了上述 Logger 接口
举一个 traceLogger 的例子
实际上咱们能够间接看到,咱们之前实现的 GetTenant rpc 办法
咱们能够看到当调用了NewGetTenantLogic 办法之后,实际上是会调用 logx.WithContext(ctx) 初始化一个 traceLogger 的句柄
traceLogger 实现了上述 Logger 接口, 因而,当咱们须要在 rpc 中打印日志的时候,咱们能够这样来应用
这个时候,实际上是调用的 traceLogger 对应的实现代码
咱们能够看到,打印进去的日志,是咱们所冀望的信息
此处的字段对应含意是这样的:
- Timestamp
工夫戳
- Level
日志等级
- Duration
工夫距离
- Caller
日志调用者
- Content
具体的日志信息
认真查看上述日志,咱们能够发现还有 trace 和 span 字段也打印进去了,然而 logEntry 为什么没有定义呢
咱们略微追一下代码,不难看出,是 traceLogger 外部的 info 函数进行日志信息的拼接
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) 办法就能够了
官网也给了咱们例子,例如咱们实现输入的日志往 kafka 外面吐,咱们就能够这样
实现自定义接口
实现自定义接口,咱们其实方才看 traceLogger 的实现形式,咱们就能领悟到,traceLogger 去实现 Logger 接口中的办法,并且退出本人自定义的逻辑,例如加上了 trace 和 span
那么对于咱们自定义接口,其实也是非常容易的,照葫芦画瓢即可了
\
感激浏览,欢送交换,点个赞,关注一波 再走吧
欢送点赞,关注,珍藏
敌人们,你的反对和激励,是我保持分享,提高质量的能源
好了,本次就到这里
技术是凋谢的,咱们的心态,更应是凋谢的。拥抱变动,背阴而生,致力向前行。
我是 阿兵云原生,欢送点赞关注珍藏,下次见~
\