diff --git a/cmd/agent/subcommands/status/command.go b/cmd/agent/subcommands/status/command.go index 88b30ee873dc1..a86a5d61e0076 100644 --- a/cmd/agent/subcommands/status/command.go +++ b/cmd/agent/subcommands/status/command.go @@ -11,10 +11,8 @@ import ( "encoding/json" "errors" "fmt" - "net/http" "net/url" "os" - "time" "go.uber.org/fx" @@ -162,14 +160,6 @@ func requestStatus(config config.Component, cliParams *cliParams) error { if err != nil { return err } - // attach trace-agent status, if obtainable - temp := make(map[string]interface{}) - if err := json.Unmarshal(r, &temp); err == nil { - temp["apmStats"] = getAPMStatus(config) - if newr, err := json.Marshal(temp); err == nil { - r = newr - } - } // The rendering is done in the client so that the agent has less work to do if cliParams.prettyPrintJSON { @@ -195,30 +185,6 @@ func requestStatus(config config.Component, cliParams *cliParams) error { return nil } -// getAPMStatus returns a set of key/value pairs summarizing the status of the trace-agent. -// If the status can not be obtained for any reason, the returned map will contain an "error" -// key with an explanation. -func getAPMStatus(config config.Component) map[string]interface{} { - port := config.GetInt("apm_config.debug.port") - url := fmt.Sprintf("http://localhost:%d/debug/vars", port) - resp, err := (&http.Client{Timeout: 2 * time.Second}).Get(url) - if err != nil { - return map[string]interface{}{ - "port": port, - "error": err.Error(), - } - } - defer resp.Body.Close() - status := make(map[string]interface{}) - if err := json.NewDecoder(resp.Body).Decode(&status); err != nil { - return map[string]interface{}{ - "port": port, - "error": err.Error(), - } - } - return status -} - func componentStatusCmd(log log.Component, config config.Component, cliParams *cliParams) error { if len(cliParams.args) != 1 { return fmt.Errorf("a component name must be specified") diff --git a/pkg/status/apm/apm.go b/pkg/status/apm/apm.go new file mode 100644 index 0000000000000..dce29195b5abf --- /dev/null +++ b/pkg/status/apm/apm.go @@ -0,0 +1,59 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +// Package apm fetch information about the apm agent. +// This will, in time, be migrated to the apm agent component. +package apm + +import ( + "encoding/json" + "fmt" + "net/http" + "sync" + + apiutil "github.com/DataDog/datadog-agent/pkg/api/util" + "github.com/DataDog/datadog-agent/pkg/config" +) + +// httpClients should be reused instead of created as needed. They keep cached TCP connections +// that may leak otherwise +var ( + httpClient *http.Client + clientInitOnce sync.Once +) + +func getHTTPClient() *http.Client { + clientInitOnce.Do(func() { + httpClient = apiutil.GetClient(false) + }) + + return httpClient +} + +// GetAPMStatus returns a set of key/value pairs summarizing the status of the trace-agent. +// If the status can not be obtained for any reason, the returned map will contain an "error" +// key with an explanation. +func GetAPMStatus() map[string]interface{} { + port := config.Datadog.GetInt("apm_config.debug.port") + + client := getHTTPClient() + url := fmt.Sprintf("http://localhost:%d/debug/vars", port) + resp, err := apiutil.DoGet(client, url, apiutil.CloseConnection) + if err != nil { + return map[string]interface{}{ + "port": port, + "error": err.Error(), + } + } + + status := make(map[string]interface{}) + if err := json.Unmarshal(resp, &status); err != nil { + return map[string]interface{}{ + "port": port, + "error": err.Error(), + } + } + return status +} diff --git a/pkg/status/status.go b/pkg/status/status.go index 21696dc0ac489..a3f86b0c6cabb 100644 --- a/pkg/status/status.go +++ b/pkg/status/status.go @@ -30,6 +30,7 @@ import ( "github.com/DataDog/datadog-agent/pkg/config/utils" logsStatus "github.com/DataDog/datadog-agent/pkg/logs/status" "github.com/DataDog/datadog-agent/pkg/snmp/traps" + "github.com/DataDog/datadog-agent/pkg/status/apm" "github.com/DataDog/datadog-agent/pkg/status/collector" "github.com/DataDog/datadog-agent/pkg/status/jmx" "github.com/DataDog/datadog-agent/pkg/status/otlp" @@ -82,6 +83,7 @@ func GetStatus(verbose bool, invAgent inventoryagent.Component) (map[string]inte } stats["processAgentStatus"] = GetProcessAgentStatus() + stats["apmStats"] = apm.GetAPMStatus() if !config.Datadog.GetBool("no_proxy_nonexact_match") { stats["TransportWarnings"] = httputils.GetNumberOfWarnings() > 0