# 如何通过扩展完成DataDog的对接
本章节指导如何通过扩展API，实现上报监控数据至DataDog平台。
#### 前期准备
- 在DataDog官方网站注册一个账户。完成注册后，您将能够从DataDog的用户界面获取必要的配置信息，包括需上报数据的目标域名、API密钥以及APP密钥。
- 对于需要扩展的函数，需要为其启用公网访问。具体操作步骤请参考[配置函数访问公网](https://support.huaweicloud.com/usermanual-functiongraph/functiongraph_01_0222.html)。
 
#### 配置函数对接DataDog
1. 编写扩展包代码。 
   以下代码示例展示了如何通过扩展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)
   }
   ```
   
   
2. 制作函数扩展依赖包。 
   请参见制作函数扩展依赖包。制作完成后的依赖包示例：[datadog-extension](https://functionstage-community.obs.cn-north-1.myhuaweicloud.com/examples/datadog-extension.zip)，可下载使用。
   
   
3. 配置函数扩展依赖包。 
   请参见为需要扩展的函数配置依赖包。
   
   
4. 触发函数执行，登录DataDog查看上报指标。 
   图1登录DataDog查看上报指标   
   ![](https://support.huaweicloud.com/api-functiongraph/zh-cn_image_0000002220388137.png)
   
   
 
