"go build -X" 的妙用

不知道大家還記不記得,上次發了一篇關於 panic 檢測機器人的文章,原理非常簡單,簡單回顧一下:

  1. 業務服務在 recover 函數里通過 HTTP 請求的方式向機器人上報 panic 棧信息。

  2. 機器人解析出 panic 棧裏的代碼行號,調用 gitlab 接口拿到該行代碼的提交人、提交日期等信息。

當然,後面我又給機器人增加了一些其他的功能,例如自動拉羣,自動提醒相關人修復 panic 代碼等……

上面說的這些其實都很好實現,主要就是和飛書 API 打交道,再加上一些邏輯串連一下流程。目前機器人上報了 1000+ 次 panic,工作狀態良好。

但偶爾還是有一些小問題的存在,例如有人用開發分支(非 master)上到線上測試環境(只讀環境)測試一把,這時機器人還是用 master(默認)分支請求 gitlab 接口拿 commit 信息,拿到的信息就有可能不準。

那有沒有什麼好的方法能拿到正在運行的進程的代碼分支呢?如果能拿到,機器人用代碼路徑 + 代碼行號 + 代碼分支,就可以從 gitlab 拿到正確的 commit 信息。

答案是有,通過 go build -X 注入。

那具體怎麼玩的呢,通過一個小例子來說明。

下面是 build.sh 的代碼:

#!/bin/sh

COMMIT_ID=`git log |head -n 1| awk '{print $2;}'`
AUTHOR=`git log |head -n 3| grep Author| awk '{print $2;}'`
BRANCH_NAME=`git branch | awk '/\*/ { print $2; }'`
SERVICE_INFO="$COMMIT_ID,$AUTHOR,$BRANCH_NAME"
echo $SERVICE_INFO
go build -ldflags "-X codebase/build-x/compile_info.ServiceInfo=$SERVICE_INFO" -o output/bin/build

第 3、4、5 行分別用 git 命令拿到本次提交的 commit-id,author,分支名;第 6 行用 “,” 將三者組合成一個字符串;第 8 行用 go build 命令,設置 ldflags,將變量 $SERVICE_INFO 注入到包變量 codebase/build-x/compile_info.ServiceInfo,這樣在 Go 代碼中就可以直接用了。

再看看我的 compile_info 包的代碼,非常簡單,就定義了一個變量:

package compile_info

var ServiceInfo string

執行完 go build 命令後,compile_info.ServiceInfo 就會被賦上值,在 main 函數里打印一下:

package main

import (
 "fmt"
 "codebase/build-x/compile_info"
)

func init() {
 fmt.Println("init: ", compile_info.ServiceInfo)
}

func main() {
 fmt.Println(compile_info.ServiceInfo)
}

先執行:

sh build.sh

再執行:

~/go/src/codebase/build-x$ ./output/bin/build

得到運行結果:

init:  9699dcaae31e7e5eab55a1d75283a6d7158a64e8,raoquancheng,master
9699dcaae31e7e5eab55a1d75283a6d7158a64e8,raoquancheng,master

可知,在 init 函數里我們就可以拿到 compile_info.ServiceInfo 的值了。

代碼文件結構如下:

文件結構

原理也沒啥可探究的,就是通過 -ldflags 給鏈接器傳參數:

-X definition: 添加形式爲 importpath.name=value 的字符串值定義

其他的一些常見的命令用處:

-s 的作用是去掉符號信息。-w 的作用是去掉調試信息。go build -ldflags "-s -w" -o xxx

之前看到公司項目裏 build 腳本里的一些命令不知道有啥用,真正到了用的時候才驚呼:原來是這樣!

今天的 go build 妙用你學會了嗎?也許下次就可以在同事面前裝 B 了,當然如果碰到了老司機,也可能會被打臉。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/uzaymD5izrBJMKDrn9OpBw