更新时间:2025-03-01 GMT+08:00
如何通过扩展完成DataDog的对接
本章节指导如何通过扩展API,实现上报监控数据至DataDog平台。
前期准备
- 在DataDog官方网站注册一个账户。完成注册后,您将能够从DataDog的用户界面获取必要的配置信息,包括需上报数据的目标域名、API密钥以及APP密钥。
- 对于需要扩展的函数,需要为其启用公网访问。具体操作步骤请参考配置函数访问公网。
配置函数对接DataDog
- 编写扩展包代码。
以下代码示例展示了如何通过扩展API,实现向DataDog平台上报functiongraph.invoke.count指标,以记录函数调用次数。可参考此示例开发扩展包。
package main import ( "context" "encoding/json" "errors" "fmt" "io" "net/http" "os" "time" "github.com/DataDog/datadog-api-client-go/v2/api/datadog" "github.com/DataDog/datadog-api-client-go/v2/api/datadogV2" ) const ( registerURL = "/extension/register" invokeURL = "/extension/invoke" requestTimeout = 5 * time.Second extensionName = "FunctionGraph-Extension-Name" extensionAddr = "FunctionGraph-Extension-Address" currentExtensionAddr = "127.0.0.1:8081" currentExtensionName = "extension_1.sh" ) var ( extensionApiAddr = os.Getenv("EXTENSION_API_ADDR") ) type ExtensionRequest struct { TraceID string `json:"traceId" valid:"optional"` URN string `json:"invokedFunctionUrn" valid:"optional"` } func init() { // Set your DataDog site address os.Setenv("DD_SITE", "your_datadog_site") // Set your DataDog api key os.Setenv("DD_API_KEY", "your_datadog_api_key") // Set your DataDog app key os.Setenv("DD_APP_KEY", "your datadog_app_key") } func main() { err := registerExtension(currentExtensionName, currentExtensionAddr) if err != nil { fmt.Printf("failed to register extension, error: %s \n", err.Error()) return } http.HandleFunc(invokeURL, ServeHTTP) err = http.ListenAndServe(currentExtensionAddr, nil) if err != nil { fmt.Printf("http server error, error: %s \n", err.Error()) return } return } func getHTTPClient() *http.Client { httpClient := &http.Client{ Timeout: requestTimeout, } return httpClient } func registerExtension(name, address string) error { if len(extensionApiAddr) == 0 { return errors.New("failed to get extension api addr") } baseURLPath := "http://" + extensionApiAddr + registerURL req, err := http.NewRequest("POST", baseURLPath, nil) if err != nil { fmt.Printf("failed to build register request, error: %s\n", err.Error()) return err } req.Header.Set("Content-Type", "application/json") req.Header.Set(extensionName, currentExtensionName) req.Header.Set(extensionAddr, currentExtensionAddr) _, err = getHTTPClient().Do(req) if err != nil { fmt.Printf("failed to send register request, error: %s\n", err.Error()) return err } return nil } func ServeHTTP(writer http.ResponseWriter, request *http.Request) { req := ExtensionRequest{} defer request.Body.Close() b, err := io.ReadAll(request.Body) if err != nil { fmt.Printf("failed to parse invoke request body with error: %s \n", err.Error()) writeHeaders(writer, 500, "failed to parse invoke request body") return } if err := json.Unmarshal(b, &req); err != nil { fmt.Printf("failed to unmarshal the json, error: %s", err.Error()) writeHeaders(writer, 500, "failed to unmarshal the json") return } fmt.Println(" invoke request traceID -- ", req.TraceID) fmt.Println(" invoke request URN -- ", req.URN) sendMetricToMyDataDog(req.URN, req.TraceID) writeHeaders(writer, 200, "succeed to get invoke request") return } func writeHeaders(w http.ResponseWriter, status int, msg string) error { w.WriteHeader(status) _, err := w.Write([]byte(msg)) return err } func sendMetricToMyDataDog(urn string, traceId string) { // Assemble your metric data body := datadogV2.MetricPayload{ Series: []datadogV2.MetricSeries{ { Metric: "functiongraph.invoke.count", Type: datadogV2.METRICINTAKETYPE_UNSPECIFIED.Ptr(), Points: []datadogV2.MetricPoint{ { Timestamp: datadog.PtrInt64(time.Now().Unix()), Value: datadog.PtrFloat64(1), }, }, Resources: []datadogV2.MetricResource{ { Name: datadog.PtrString(urn), Type: datadog.PtrString("function_urn"), }, { Name: datadog.PtrString(traceId), Type: datadog.PtrString("trace_id"), }, }, }, }, } ctx := datadog.NewDefaultContext(context.Background()) configuration := datadog.NewConfiguration() apiClient := datadog.NewAPIClient(configuration) api := datadogV2.NewMetricsApi(apiClient) resp, r, err := api.SubmitMetrics(ctx, body, *datadogV2.NewSubmitMetricsOptionalParameters()) if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `MetricsApi.SubmitMetrics`: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } responseContent, _ := json.MarshalIndent(resp, "", " ") fmt.Fprintf(os.Stdout, "Response from `MetricsApi.SubmitMetrics`:\n%s\n", responseContent) }
- 制作函数扩展依赖包。
请参见如何制作函数依赖包制作函数扩展依赖包。制作完成后的依赖包示例:datadog-extension,可下载使用。
- 配置函数扩展依赖包。
请参见配置依赖包为需要扩展的函数配置依赖包。
- 触发函数执行,登录DataDog查看上报指标。
图1 登录DataDog查看上报指标
父主题: 扩展API