Go - 实现项目内链路追踪(二)


本文摘自网络,作者,侵删。

上篇文章 Go - 实现项目内链路追踪 分享了,通过 链路 ID 可以将 请求信息、响应信息、调用第三方接口的信息、调试信息、执行的 SQL 信息、执行的 Redis 信息 串起来,记录的具体参数在文件中都有介绍。

这篇文章在上面的基础上,新增 2 个功能点:

  1. 新增将 调用 gRPC 接口信息 记录到 Trace 中;

  2. 新增对记录的敏感信息进行脱敏处理;

调用 gRPC 接口信息

记录参数

Object,结构如下:

type Grpc struct {
 Timestamp   string                 `json:"timestamp"`             // 时间,格式:2006-01-02 15:04:05
 Addr        string                 `json:"addr"`                  // 地址
 Method      string                 `json:"method"`                // 操作方法
 Meta        metadata.MD            `json:"meta"`                  // Mate 信息
 Request     map[string]interface{} `json:"request"`               // 请求信息
 Response    map[string]interface{} `json:"response"`              // 返回信息
 CostSeconds float64                `json:"cost_seconds"`          // 执行时间(单位秒)
 Code        string                 `json:"err_code,omitempty"`    // 错误码
 Message     string                 `json:"err_message,omitempty"` // 错误信息
}

如何收集参数

封装了一个 grpclient 包:

  • 支持设置 DialTimeout;

  • 支持设置 UnaryInterceptor;

  • 支持设置 KeepaliveParams;

  • 支持设置 TransportCredentials;

主要是在拦截器 Interceptor 中进行收集。

示例代码

实例化 gRPC client

// TODO 需从配置文件中获取
target := "127.0.0.1:9988"
secret := "abcdef"

clientInterceptor := NewClientInterceptor(func(message []byte) (authorization string, err error) {
 return GenerateSign(secret, message)
})

conn, err := grpclient.New(target,
 grpclient.WithKeepAlive(keepAlive),
 grpclient.WithDialTimeout(time.Second*5),
 grpclient.WithUnaryInterceptor(clientInterceptor.UnaryInterceptor),
)

return &clientConn{
 conn: conn,
}, err

调用具体方法

// 核心:传递 core.Context 给 Interceptor 使用
client := hello.NewHelloClient(d.grpconn.Conn())
client.SayHello(grpc.ContextWithValueAndTimeout(c, time.Second*3), &hello.HelloRequest{Name: "Hello World"})

敏感信息脱敏

敏感信息脱敏又称为动态数据掩码(Dynamic Data Masking,简称为DDM)能够防止把敏感数据暴露给未经授权的用户。

根据项目要求可以约定一些规范,例如:


类型要求示例说明
手机号前 3 后 4132****7986定长 11 位数字
邮箱地址前 1 后 1l**w@gmail.com仅对 @ 之前的邮箱名称进行掩码
姓名隐姓*鸿章将姓氏隐藏
密码不输出******
银行卡卡号前 6 后 4622888******5676银行卡卡号最多 19 位数字
身份证号前 1 后 11******7定长 18 位


如何实现

我现在的实现方案是:自定义 MarshalJSON(),欢迎大佬们提出更好的方案。

示例代码

// 定义 Mobile 类型
type Mobile string

// 自定义 MarshalJSON()
func (m Mobile) MarshalJSON() ([]byte, error) {
 if len(m) != 11 {
  return []byte(`"` + m + `"`), nil
 }

 v := fmt.Sprintf("%s****%s", m[:3], m[len(m)-4:])
 return []byte(`"` + v + `"`), nil
}

测试

type message struct {
 Mobile    ddm.Mobile   `json:"mobile"`
}

msg := new(message)
msg.Mobile = ddm.Mobile("13288889999")

marshal, _ := json.Marshal(msg)
fmt.Println(string(marshal))

// 输出:{"mobile":"132****9999"}

小结

本篇文章新增了 2 个实用的功能点,大家赶紧使用起来吧。关于 敏感信息脱敏 期待各位大佬不吝赐教,提出更好的解决方案,谢谢!


本文来自:51CTO博客

感谢作者:wx6087c7391d3cd

查看原文:Go - 实现项目内链路追踪(二)

相关阅读 >>

手撸Golang 仿spring ioc/aop 之10 增强1

关于Go值传递和地址传递的例子

Golang如何判断目录是否存在

djanGo模板语言

自制文件系统 — 04 hellofs 进阶 分布式加密文件系统

Go中sync.cond源码解读

Golang如何创建map

Go微服务入门到容器化实践,落地可观测的微服务电商项目

手撸Golang 基本数据结构与算法 插入排序

手撸Golang 基本数据结构与算法 图的搜索 深度优先/广度优先

更多相关阅读请进入《Go》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...