通過SkyWalking為應用埋點並上報鏈路資料至Managed Service for OpenTelemetry後,Managed Service for OpenTelemetry即可開始監控應用,您可以查看應用拓撲、調用鏈路、異常事務、慢事務和SQL分析等一系列監控資料。本文介紹如何使用SkyWalking Go Agent進行自動埋點並上報應用資料。
ARMS應用監控針對Golang語言提供了商業化版本的自研探針,提供了無侵入的埋點能力,擁有更加豐富的功能和更高的穩定性。詳細資料,請參見開始監控Golang應用。
前提條件
Agent選擇
Go2Sky是SkyWalking官方舊版的SkyWalking Go探針,使用人數較多,但侵入較嚴重,因此官方推出了新版的skywalking-go探針,新版探針具有無侵入的特性。本文同時提供skywalking-go和Go2Sky兩種探針接入流程,方便您將資料上報至Managed Service for OpenTelemetry控制台。
Go2Sky
舊版SkyWalking Agent,在skywalking-go Agent正式發布後停止支援。
根據官網頁面顯示,Go2Sky已被移到Retired,即不再維護。
代碼侵入較嚴重,每一個外掛程式都要在專案中添加Hook。
使用人數較多。
支援的埋點庫:
skywalking-go
新版SkyWalking Agent,官方提供穩定支援。
代碼幾乎無侵入。
用法簡單,只需要編譯GoLang專案時通過
-toolexec
參數指定skywalking-go Agent。使用人數相對Go2Sky較少。
支援的埋點庫:
推薦Agent
建議您使用新版skywalking-go探針,優勢如下:
使用簡便:skywalking-go使用更簡單,您只需要通過簡短的步驟即可完成接入和自動埋點。Skywalking-go是無侵入式探針,而Go2Sky在使用外掛程式時需要手動添加Hook鉤子。
社區支援:官方將取消對Go2Sky的繼續支援,也不再接受關於Go2Sky的PR。
外掛程式生態:官方將會持續將Go2Sky的外掛程式移植到skywalking-go。目前,skywalking-go相比Go2Sky多了對gRPC架構的埋點。
樣本Demo
樣本Demo倉庫地址:SkyWalking Demo
通過skywalking-go探針上報
下載skywalking-go Agent。
構建Agent。
cd skywalking-go && make build
在skywalking-go/bin路徑下產生可執行檔。
不同的作業系統對應的可執行檔不同。例如,mac系統需選擇skywalking-go-agent--darwin-amd64。
開啟Go專案,在main package中匯入skywalking module。
方式一
package main import ( _ "github.com/apache/skywalking-go" )
方式二
skywalking-go/bin/skywalking-go-agent--darwin-amd64 -inject path/to/your-project
配置config.yaml檔案。
您可以參考樣本Demo的skywalking-go/tools/go-agent/config/config.default.yaml檔案修改。
設定參數有以下兩種方式,例如,如果要配置service_name,配置方法如下:
方式一(推薦):直接在config.yaml中添加參數
agent: service_name: ${SW_AGENT_NAME:<your_service_name>}
方式二:配置系統內容變數
export SW_AGENT_NAME=<your_service_name>
接入Managed Service for OpenTelemetry控制台需要設定以下參數:
service_name: ${SW_AGENT_NAME:Your_ApplicationName}
:服務名稱。backend_service: ${SW_AGENT_REPORTER_GRPC_BACKEND_SERVICE:127.0.0.1:11800}
:存取點的Endpoint。authentication: ${SW_AGENT_REPORTER_GRPC_AUTHENTICATION:}
:存取點鑒權Token。
skywalking-go Agent預設對所有的外掛程式自動埋點,若需要移除特定外掛程式,可以設定excluded參數,例如:
# 如果想要關閉sql plugin plugin: excluded: ${SW_AGENT_PLUGIN_EXCLUDES:sql} # 如果想同時關閉多個plugin,使用,分隔 plugin: excluded: ${SW_AGENT_PLUGIN_EXCLUDES:sql,gorm}
重新構建專案。
# 需要使用-toolexec sudo go build -toolexec "path/to/skywalking-go-agent -config path/to/config.yaml" -a
path/to/skywalking-go-agent
:上文步驟1可執行檔的絕對路徑。path/to/config.yaml
:skywalking-go Agent的參數設定檔的絕對路徑。
啟動專案。此時SkyWalking資料將會上報至Managed Service for OpenTelemetry控制台。
參考資訊
skywalking-go探針的部分屬性列表,NULL表示預設值未設定:
環境變數 | 描述 | 預設值 |
SW_AGENT_NAME | 服務名稱。 | NULL |
SW_AGENT_INSTANCE_NAME | 服務執行個體名稱。 | 自動產生 |
SW_AGENT_SAMPLE | 採樣率,取值在0和1之間。 | 1 |
SW_AGENT_REPORTER_GRPC_BACKEND_SERVICE | 監控資料通過gRPC上報的服務端Endpoint。 | 127.0.0.1:11800 |
SW_AGENT_REPORTER_GRPC_AUTHENTICATION | 監控資料通過gRPC上報的服務端的鑒權Token。 | NULL |
SW_AGENT_PLUGIN_EXCLUDES | 指定移除的外掛程式。 | NULL |
通過Go2Sky探針上報
Go2Sky同時支援配置參數寫入程式碼到專案或通過環境變數自動設定兩種方法。
配置參數寫入程式碼
### 使用reporter.WithParameter()匯入參數 report, err := reporter.NewGRPCReporter( <your-backend-server-address>, reporter.WithAuthentication(<your-auth-token>))
環境變數自動設定
### 目前go2sky支援從環境變數擷取以下參數 SW_AGENT_AUTHENTICATION SW_AGENT_LAYER SW_AGENT_COLLECTOR_HEARTBEAT_PERIOD SW_AGENT_COLLECTOR_GET_AGENT_DYNAMIC_CONFIG_INTERVAL SW_AGENT_COLLECTOR_BACKEND_SERVICES SW_AGENT_COLLECTOR_MAX_SEND_QUEUE_SIZE SW_AGENT_PROCESS_STATUS_HOOK_ENABLE SW_AGENT_PROCESS_LABELS ### 配置環境變數,以macOS為例 # 方法1:寫入環境變數設定檔(持久化) vim ~/.bash_profile export SW_AGENT_COLLECTOR_BACKEND_SERVICES=<your-collector-address> source ~/.bash_profile # 方法2:開啟終端,命令列配置(臨時生效,開啟新的終端失效) export SW_AGENT_COLLECTOR_BACKEND_SERVICES=<your-collector-address>
配置ServiceName,用於識別具體的應用。
ServiceName := <your-service-name> tracer, err := go2sky.NewTracer(ServiceName, go2sky.WithReporter(report))
添加Go2Sky-Plugin Hook。
Go2Sky開發了眾多庫的外掛程式,但是需要在專案原始碼中添加埋點。如何添加埋點請參見Go2Sky-Plugins的Github倉庫。在每個外掛程式的plugin檔案夾下,README.md檔案給了簡單的使用樣本。
以gin架構為例:
進入/gin檔案夾,查看/gin/v3/README.md檔案。
添加Middleware的Hook:v3.Middleware(r, tracer)。
package main import ( "log" "github.com/SkyAPM/go2sky" v3 "github.com/SkyAPM/go2sky-plugins/gin/v3" "github.com/SkyAPM/go2sky/reporter" "github.com/gin-gonic/gin" ) func main() { // Use gRPC reporter for production re, err := reporter.NewLogReporter() if err != nil { log.Fatalf("new reporter error %v \n", err) } defer re.Close() tracer, err := go2sky.NewTracer("gin-server", go2sky.WithReporter(re)) if err != nil { log.Fatalf("create tracer error %v \n", err) } gin.SetMode(gin.ReleaseMode) r := gin.New() //Use go2sky middleware with tracing r.Use(v3.Middleware(r, tracer)) // do something }
重新啟動應用。
參考資訊
Go2Sky的Agent屬性配置表,NULL表示預設值未設定:
環境變數 | 描述 | 預設值 |
SW_AGENT_NAME | Go服務的名稱。 | NULL |
SW_AGENT_LAYER | Instance belong layer name which define in the backend 執行個體所屬的layer名稱。 | NULL |
SW_AGENT_INSTANCE_NAME | Go服務的執行個體名稱。 | 隨機產生 |
SW_AGENT_SAMPLE | 採樣率,1表示全量採集。 | 1 |
SW_AGENT_COLLECTOR_BACKEND_SERVICES | Agent資料上報的服務端地址。 | NULL |
SW_AGENT_AUTHENTICATION | Agent資料上報的服務端的鑒權令牌。 | NULL |
SW_AGENT_COLLECTOR_HEARTBEAT_PERIOD | Agent心跳上報周期,單位:s。 | 20 |
SW_AGENT_COLLECTOR_GET_AGENT_DYNAMIC_CONFIG_INTERVAL | 動態擷取Agent配置的時間間隔,單位:s。 | 20 |
SW_AGENT_COLLECTOR_MAX_SEND_QUEUE_SIZE | 發送跨度Span的隊列Buffer長度。 | 30000 |
SW_AGENT_PROCESS_STATUS_HOOK_ENABLE | 啟用進程狀態Hook功能。 | False |
SW_AGENT_PROCESS_LABELS | 進程標籤,多個標籤用英文半形逗號(,)分隔。 | NULL |
常見問題
使用skywalking-go時報錯如下:
如果使用inject方式報錯,您可以通過import在main package中匯入skywalking module。
跨進程調用時,為什麼通過Go2Sky上報Managed Service for OpenTelemetry控制台無法顯示正確的調用鏈?
全鏈路追蹤通過TraceId將整個鏈路串聯起來,而TraceId通過HTTP請求攜帶傳遞。如果調用鏈不正確,說明TraceId沒有正確傳遞,需要設定合理的Span埋點。
通過合理使用下面兩個重要的介面,可以將跨進程的調用鏈正確的串聯起來:
CreateEntrySpan:入口Span,可以通過該介面從HTTP請求中提取得到鏈路追蹤上下文(包含TraceId)。
CreateExitSpan:出口Span,可以通過該介面向HTTP請求注入鏈路追蹤上下文(包含TraceId)。
// 進程內,使用CreateLocalSpan建立一個跨度(Span)。 span, ctx, err := tracer.CreateLocalSpan(context.Background()) subSpan, newCtx, err := tracer.CreateLocalSpan(ctx) // 跨進程,使用入口Span從CreateEntrySpan從Http請求中提取上下文,使用出口Span向CreateExitSpan向Http請求中注入上下文。 span, ctx, err := tracer.CreateEntrySpan(r.Context(), "/api/login", func(key string) (string, error) { return r.Header.Get(key), nil }) span, err := tracer.CreateExitSpan(req.Context(), "/service/validate", "tomcat-service:8080", func(key, value string) error { req.Header.Set(key, value) return nil })
跨進程的專案,不同進程之間需要傳遞TraceId才能將調用鏈串聯起來,所以需要用到上面的介面將上下文注入到HTTP請求中隨著請求在進程間傳遞。