上篇文章 Go - 實現專案內鏈路追蹤 分享了,通過 鏈路 ID
可以將 請求資訊
、響應資訊
、呼叫第三方介面的資訊
、除錯資訊
、執行的 SQL 資訊
、執行的 Redis 資訊
串起來,記錄的具體引數在檔案中都有介紹。
這篇文章在上面的基礎上,新增 2 個功能點:
- 新增將
呼叫 gRPC 介面資訊
記錄到Trace
中; - 新增對記錄的敏感資訊進行脫敏處理;
呼叫 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 後 4 | 132****7986 | 定長 11 位數字 |
郵箱地址 | 前 1 後 1 | l**w@gmail.com | 僅對 @ 之前的郵箱名稱進行掩碼 |
姓名 | 隱姓 | *鴻章 | 將姓氏隱藏 |
密碼 | 不輸出 | ****** | |
銀行卡卡號 | 前 6 後 4 | 622888******5676 | 銀行卡卡號最多 19 位數字 |
身份證號 | 前 1 後 1 | 1******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 個實用的功能點,大家趕緊使用起來吧。關於 敏感資訊脫敏
期待各位大佬不吝賜教,提出更好的解決方案,謝謝!
以上程式碼都在 go-gin-api 專案中,地址:https://github.com/xinliangnote/go-gin-api