Connecting to DataDog with an Extension
This section describes how to use extension APIs to report monitoring data to the DataDog platform.
Preparations
- Register an account at the DataDog official website. Obtain necessary configuration information including the target domain name, API key, and app key for data reporting.
- For functions that need to be extended, enable public access for them. For details, see Configuring Public Access for a Function.
Connecting a Function to DataDog
- Compile the extension package code.
The following code example shows how to use an extension API to report the functiongraph.invoke.count metric to the DataDog platform to record the number of function calls. You can refer to this example to develop an extension package.
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) }
- Create an extension dependency.
For details, see How Do I Create Function Dependencies? datadog-extension is an example dependency, which can be downloaded and used.
- Configure the function extension dependency.
Configure the dependency for the function. For details, see Configuring Dependency Packages.
- Trigger the function and log in to the DataDog to view the reported metrics.
Figure 1 Logging in to the DataDog and viewing the reported metrics
Feedback
Was this page helpful?
Provide feedbackThank you very much for your feedback. We will continue working to improve the documentation.See the reply and handling status in My Cloud VOC.
For any further questions, feel free to contact us through the chatbot.
Chatbot