经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Go语言 » 查看文章
Go - 实现项目内链路追踪(二)
来源:cnblogs  作者:新亮笔记  时间:2021/2/18 15:35:38  对本文有异议

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

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

  1. 新增将 调用 gRPC 接口信息 记录到 Trace 中;
  2. 新增对记录的敏感信息进行脱敏处理;

调用 gRPC 接口信息

记录参数

Object,结构如下:

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

如何收集参数

封装了一个 grpclient 包:

  • 支持设置 DialTimeout
  • 支持设置 UnaryInterceptor
  • 支持设置 KeepaliveParams
  • 支持设置 TransportCredentials

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

示例代码

实例化 gRPC client

  1. // TODO 需从配置文件中获取
  2. target := "127.0.0.1:9988"
  3. secret := "abcdef"
  4. clientInterceptor := NewClientInterceptor(func(message []byte) (authorization string, err error) {
  5. return GenerateSign(secret, message)
  6. })
  7. conn, err := grpclient.New(target,
  8. grpclient.WithKeepAlive(keepAlive),
  9. grpclient.WithDialTimeout(time.Second*5),
  10. grpclient.WithUnaryInterceptor(clientInterceptor.UnaryInterceptor),
  11. )
  12. return &clientConn{
  13. conn: conn,
  14. }, err

调用具体方法

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

敏感信息脱敏

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

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

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

如何实现

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

示例代码

  1. // 定义 Mobile 类型
  2. type Mobile string
  3. // 自定义 MarshalJSON()
  4. func (m Mobile) MarshalJSON() ([]byte, error) {
  5. if len(m) != 11 {
  6. return []byte(`"` + m + `"`), nil
  7. }
  8. v := fmt.Sprintf("%s****%s", m[:3], m[len(m)-4:])
  9. return []byte(`"` + v + `"`), nil
  10. }

测试

  1. type message struct {
  2. Mobile ddm.Mobile `json:"mobile"`
  3. }
  4. msg := new(message)
  5. msg.Mobile = ddm.Mobile("13288889999")
  6. marshal, _ := json.Marshal(msg)
  7. fmt.Println(string(marshal))
  8. // 输出:{"mobile":"132****9999"}

小结

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

以上代码都在 go-gin-api 项目中,地址:https://github.com/xinliangnote/go-gin-api

原文链接:http://www.cnblogs.com/xinliangcoder/p/14396753.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号