Go - 實(shí)現(xiàn)項(xiàng)目內(nèi)鏈路追蹤(二)
上篇文章 Go - 實(shí)現(xiàn)項(xiàng)目內(nèi)鏈路追蹤 分享了,通過 鏈路 ID 可以將 請求信息、響應(yīng)信息、調(diào)用第三方接口的信息、調(diào)試信息、執(zhí)行的 SQL 信息、執(zhí)行的 Redis 信息 串起來,記錄的具體參數(shù)在文件中都有介紹。
這篇文章在上面的基礎(chǔ)上,新增 2 個功能點(diǎn):
新增將 調(diào)用 gRPC 接口信息記錄到Trace中;新增對記錄的敏感信息進(jìn)行脫敏處理;
調(diào)用 gRPC 接口信息
記錄參數(shù)
Object,結(jié)構(gòu)如下:
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"`??????????//?執(zhí)行時間(單位秒)
?Code????????string?????????????????`json:"err_code,omitempty"`????//?錯誤碼
?Message?????string?????????????????`json:"err_message,omitempty"`?//?錯誤信息
}
如何收集參數(shù)
封裝了一個 grpclient 包:
支持設(shè)置 DialTimeout;支持設(shè)置 UnaryInterceptor;支持設(shè)置 KeepaliveParams;支持設(shè)置 TransportCredentials;
主要是在攔截器 Interceptor 中進(jìn)行收集。
示例代碼
實(shí)例化 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
調(diào)用具體方法
//?核心:傳遞 core.Context 給 Interceptor 使用
client?:=?hello.NewHelloClient(d.grpconn.Conn())
client.SayHello(grpc.ContextWithValueAndTimeout(c,?time.Second*3),?&hello.HelloRequest{Name:?"Hello?World"})
敏感信息脫敏
敏感信息脫敏又稱為動態(tài)數(shù)據(jù)掩碼(Dynamic Data Masking,簡稱為DDM)能夠防止把敏感數(shù)據(jù)暴露給未經(jīng)授權(quán)的用戶。
根據(jù)項(xiàng)目要求可以約定一些規(guī)范,例如:
| 類型 | 要求 | 示例 | 說明 |
|---|---|---|---|
| 手機(jī)號 | 前 3 后 4 | 132****7986 | 定長 11 位數(shù)字 |
| 郵箱地址 | 前 1 后 1 | l**[email protected] | 僅對 @ 之前的郵箱名稱進(jìn)行掩碼 |
| 姓名 | 隱姓 | *鴻章 | 將姓氏隱藏 |
| 密碼 | 不輸出 | ****** | |
| 銀行卡卡號 | 前 6 后 4 | 622888******5676 | 銀行卡卡號最多 19 位數(shù)字 |
| 身份證號 | 前 1 后 1 | 1******7 | 定長 18 位 |
如何實(shí)現(xiàn)
我現(xiàn)在的實(shí)現(xiàn)方案是:自定義 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"}
小結(jié)
本篇文章新增了 2 個實(shí)用的功能點(diǎn),大家趕緊使用起來吧。關(guān)于 敏感信息脫敏 期待各位大佬不吝賜教,提出更好的解決方案,謝謝!
以上代碼都在 go-gin-api 項(xiàng)目中,地址:https://github.com/xinliangnote/go-gin-api
推薦閱讀
評論
圖片
表情
