微服务框架 go-zero logx 日志组件剖析
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 addTenantpost /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 linersp,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
那么对于我们自定义接口,其实也是非常容易的,照葫芦画瓢即可了
\
感谢阅读,欢迎交流,点个赞,关注一波 再走吧
欢迎点赞,关注,收藏
朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力
好了,本次就到这里
技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。
我是阿兵云原生,欢迎点赞关注收藏,下次见~
可以进入地址进行体验和学习:https://xxetb.xet.tech/s/3lucCI
相关文章:

微服务框架 go-zero logx 日志组件剖析
addTenant api 和 rpc 的实现 上一篇我们说到咱们还剩下 addTenant 功能还未实现,不知道有没有兄弟感兴趣去实验一波的,本篇文章进行简要补充 根据上一篇文章分析,其实我们只需要执行如下几步即可: 编写 tenant.api,…...

基于Java+SpringBoot+Vue前后端分离图书电子商务网站设计和实现
博主介绍:✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专…...

C# Winfrom通过COM接口访问和控制Excel应用程序,将Excel数据导入DataGridView
1.首先要创建xlsx文件 2.在Com中添加引用 3. 添加命名空间 using ApExcel Microsoft.Office.Interop.Excel; --这样起个名字方面后面写 4.样例 //点击操作excelDataTable dt new DataTable();string fileName "D:\desktop\tmp\test.xlsx";ApExcel.Application exA…...

Linux-tomcat环境搭建、jpress部署实践、nginx反向代理
♥️作者:小刘在C站 ♥️个人主页: 小刘主页 ♥️努力不一定有回报,但一定会有收获加油!一起努力,共赴美好人生! ♥️学习两年总结出的运维经验,以及思科模拟器全套网络实验教程。专栏…...

SQLmap使用
文章目录 利用sqlmap 注入得到cms网站后台管理员账密获取数据库名称获取cms数据库的表名获取users表中的字段(内容)获取username字段和password字段的内容 salmap破解psot请求数据包salmap获取getshell 利用sqlmap 注入得到cms网站后台管理员账密 获取数…...

【Flutter】Flutter 使用 infinite_scroll_pagination 实现无限滚动分页
【Flutter】Flutter 使用 infinite_scroll_pagination 实现无限滚动分页 文章目录 一、前言二、安装和基本使用1. 添加依赖2. 基础配置和初始化 三、实际业务中的用法1. 与 API 集成2. 错误处理 四、完整示例1. 创建一个无限滚动列表2. 使用在你的应用中3. 完整代码示例 五、总…...

python爬虫的js逆向入门到进阶教程文章分享汇总~持续更新
目录 一、内容介绍二 、专栏内容-持续更新1、JS逆向入门2、Js逆向进阶3、爬虫基础知识4、工具与安装5、漫星内容分享 三、星球使用四、b站up主视频推荐 一、内容介绍 二 、专栏内容-持续更新 1、JS逆向入门 2023-08-25》11.常见加密>xx音乐RSA加密 https://articles.zsxq.c…...

面试常问:水平居中和垂直居中的方法
水平居中 文本居中 如果元素为行内元素,可以将父元素的text-align属性设置为center,这样子元素就会水平居中对齐 .text{text-align: center; }固定宽度的居中 如果元素宽度已知并固定,可以通过将左右margin设置为auto来实现水平居中。 .…...

第七届“蓝帽杯”初赛取证题目分享
前言: 刚刚打完比赛,准备晚上写一下wp,刚好整理一下题目,ctf的题目一般都有,取证不一定,所以我整理一下,方便大家复盘。 题目: 1:【APK取证】涉案apk的包名是ÿ…...

go语言学习之有关变量的知识
文章目录 变量的学习1.变量的使用步骤2.变量的注意事项3.变量使用的三种方式:4.程序中 号的使用5.变量的数据类型1)int数据类型2)小数类型浮点型3)**字符类型**4)**字符串(String)类型**5&…...

算法通过村第8关【青铜】| 二叉树的经典算法题
二叉树的双指针 1.相同的树 思路:递归的挨个比较是否相同 class Solution {public boolean isSameTree(TreeNode p, TreeNode q) {if((p null&&q!null) || (p ! null && q null) || (p!null&&q!null&&p.val ! q.val)){return f…...

Open3D 点云均值滤波
目录 一、算法原理1、均值滤波2、参考文献二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、算法原理 1、均值滤波 对待处理的当前采样点,选择一个模板,该模板由其邻近的若干个数据点组成,…...

C语言指针入门详解
一、指针简介 指针(Pointer)是C语言的一个重要知识点,其使用灵活、功能强大,是C语言的灵魂指针与底层硬件联系紧密,使用指针可操作数据的地址,实现数据的间接访问指针就是地址,通过访问此地址来获取该地址存储的数据 …...

软件工程(十四) 设计模式之结构型模式(二)
1、组合模式 简要说明 将对象组合成树形结构以表示“整体-部分”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。 速记关键字 树形目录结构 类图如下 由类图其实可以看出,组合模式就是将具有父子关系的结构,组装形成一棵树,并且根据规范,树干节点和叶子节…...

不解压的方式直接更新jar包内部的内容
前言 如果线上直接更新一个class,可以不用解压,直接利用jar命令直接更新jar报的资源和内容 更新jar包内容文件 Jar 工具提供了一个 u 选项,你可以通过修改其清单或添加文件来更新现有 JAR 文件的内容。 添加文件的基本命令具有以下格式&am…...

软件工程(八) UML之类图与对象图
1、类图与对象图 1.1、类图与对象图的概念 类图(class diagram)描述一组类、接口、协作和它们之间的关系 对象图(object diagram)描述一组对象及它们之间的关系、对象图描述了在类图中所建立的事物实例的静态快照。 1.2、类图与对象图的区别 类图和对象图基本上是一样…...

【Unity3D赛车游戏】【五】Unity中汽车加速效果是如何优化的?
👨💻个人主页:元宇宙-秩沅 👨💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨💻 本文由 秩沅 原创 👨💻 收录于专栏:Uni…...

龙智案例:某大型零售企业如何打造高速、现代化的ITSM体系
在2023 DevOps国际峰会北京站的现场,我们对话了龙智咨询顾问胡若愚,他为我们奖助了一位零售业的大型客户是如何在数字化浪潮中,凭借龙智提供的Jira Service Management产品及服务,打造现代化ITSM平台,提升客户满意度。…...

jdk 03.stream
01.集合处理数据的弊端 当我们在需要对集合中的元素进行操作的时候,除了必需的添加,删除,获取外,最典型的操作就是集合遍历 package com.bobo.jdk.stream; import java.util.ArrayList; import java.util.Arrays; import java.ut…...

“华为杯”研究生数学建模竞赛2018年-【华为杯】C题:对恐怖袭击事件记录数据的量化分析
目录 摘 要: 一、 问题背景与重述 1.1 问题背景 1.2 问题重述 二、 问题分析...

java8的reduce方法
在 Java 8 中,reduce 是一个流操作方法,用于将流中的元素按照指定的操作进行归约(reduce)操作,最终得到一个结果。 reduce 方法有三种重载形式: T reduce(T identity, BinaryOperator<T> accumulato…...

Mac发现有的软件不能上网的破解之法
1、Mac上打开终端 terminal ,获取 root 权限。 sudo -i 2、编辑 hosts 文件 vim /private/etc/hosts 3、找到被禁止软件的数据请求域名,然后删除相关行,快捷件dd,然后:wq保存退出 比如百度 127.0.0.1 pan.baidu.com ##sec 印…...

定时检测接口是否正常飞书告警脚本
第一版 支持多个接口地址,循环检测,定时每分钟执行一次脚本 告警效果 脚本 飞书机器人创建忽略跳过,各大协作平台大同小异拿出机器人hook地址 #!/bin/bash URL_LIST=(https://gatewaxxxxxxxxxxxxxxxxxx https://sandbox-gatexxxxxxxxxxxxxxxxxx)for URL in ${URL_LIST[*...

【MySQL】2、MySQL数据库的管理
常用 describe user; Field:字段名称 Type:数据类型 Null :是否允许为空 Key :主键 Type:数据类型 Null :是否允许为空key :主键 Default :默认值 Extra :扩展属性,例如:标志符列(标识了种子,增量/步长)1 2 id:1 3 5 …...

8086汇编test指令学习
Test指令将两个操作数进行逻辑与运算,并根据运算结果设置相关的标志位。Test的两个操作数不会被改变。运算结果在设置过相关标记位后会被丢弃。 TEST AX,BX 与 AND AX,BX 命令有相同效果,只是Test指令不改变AX和BX的内容,而AND指令会把结果保…...

简单js逆向案例(2)
文章目录 前文分析完整代码结尾 前文 本文章中所有内容仅供学习交流,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 分析 目标网址 aHR0cHM6Ly9zZWFyY2guYmlkY2VudGV…...

azure data studio SQL扩展插件开发笔记
node.js环境下拉取脚手架 npm install -g yo generator-azuredatastudio yo azuredatastudio 改代码 运行 调试扩展,在visual studio code中安装插件即可 然后visual studio code打开进行修改运行即可 image.png 运行后自动打开auzre data studio了, 下面…...

【二分】搜索旋转数组
文章目录 不重复数组找最小值,返回下标重复数组找最小值,返回下标不重复数组找target,返回下标重复数组找target,返回bool重复数组找target,返回下标 不重复数组找最小值,返回下标 class Solution {public …...
APSIM模型应用与参数优化、批量模拟
APSIM (Agricultural Production Systems sIMulator)模型是世界知名的作物生长模拟模型之一。APSIM模型有Classic和Next Generation两个系列模型,能模拟几十种农作物、牧草和树木的土壤-植物-大气过程,被广泛应用于精细农业、水肥管理、气候变化、粮食安…...

QT使用QXlsx实现对Excel sheet的相关操作 QT基础入门【Excel的操作】
准备:搭建环境引用头文件QT中使用QtXlsx库的三种方法 QT基础入门【Excel的操作】_吻等离子的博客-CSDN博客 #include "xlsxdocument.h"QTXLSX_USE_NAMESPACE // 添加Xlsx命名空间(https://github.com/dbzhang800/QtXlsxWriter) or QXLSX_USE_NAMESPACE // 添加Xl…...