From 7bf82eaa0be9ff65236963191e98f484e2c512c7 Mon Sep 17 00:00:00 2001 From: Craig Peterson <192540+captncraig@users.noreply.github.com> Date: Wed, 29 Nov 2023 14:27:35 -0500 Subject: [PATCH] Add Deploy Mode to usage stats. (#5880) Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com> --- CHANGELOG.md | 4 ++++ docs/sources/data-collection.md | 1 + internal/useragent/useragent.go | 11 +++++++++-- internal/useragent/useragent_test.go | 13 +++++++++++++ pkg/usagestats/stats.go | 3 +++ 5 files changed, 30 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01d1f99a8a9f..e20d12002758 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,10 @@ Main (unreleased) - Fix issue in `prometheus.operator.*` where targets would be dropped if two crds share a common prefix in their names. (@Paul424, @captncraig) +### Other changes + +- Add Agent Deploy Mode to usage report. (@captncraig) + v0.38.0 (2023-11-21) -------------------- diff --git a/docs/sources/data-collection.md b/docs/sources/data-collection.md index a464f5b892b5..da008ce32059 100644 --- a/docs/sources/data-collection.md +++ b/docs/sources/data-collection.md @@ -30,6 +30,7 @@ The usage information includes the following details: * List of enabled feature flags ([Static] mode only). * List of enabled integrations ([Static] mode only). * List of enabled [components][] ([Flow] mode only). +* Method used to deploy Grafana Agent, for example Docker, Helm, RPM, or Operator. This list may change over time. All newly reported data is documented in the CHANGELOG. diff --git a/internal/useragent/useragent.go b/internal/useragent/useragent.go index bb6043f97aa3..8150d5d8ba95 100644 --- a/internal/useragent/useragent.go +++ b/internal/useragent/useragent.go @@ -19,6 +19,7 @@ const ( // settable by tests var goos = runtime.GOOS +var executable = os.Executable func Get() string { parenthesis := "" @@ -27,7 +28,7 @@ func Get() string { metadata = append(metadata, mode) } metadata = append(metadata, goos) - if op := getDeployMode(); op != "" { + if op := GetDeployMode(); op != "" { metadata = append(metadata, op) } if len(metadata) > 0 { @@ -49,12 +50,18 @@ func getRunMode() string { } } -func getDeployMode() string { +// GetDeployMode returns our best-effort guess at the way Grafana Agent was deployed. +func GetDeployMode() string { op := os.Getenv(deployModeEnv) // only return known modes. Use "binary" as a default catch-all. switch op { case "operator", "helm", "docker", "deb", "rpm", "brew": return op } + // try to detect if executable is in homebrew directory + if path, err := executable(); err == nil && goos == "darwin" && strings.Contains(path, "brew") { + return "brew" + } + // fallback to binary return "binary" } diff --git a/internal/useragent/useragent_test.go b/internal/useragent/useragent_test.go index abaf0b80d192..b242a17e4263 100644 --- a/internal/useragent/useragent_test.go +++ b/internal/useragent/useragent_test.go @@ -15,6 +15,7 @@ func TestUserAgent(t *testing.T) { Expected string DeployMode string GOOS string + Exe string }{ { Name: "basic", @@ -76,9 +77,21 @@ func TestUserAgent(t *testing.T) { Expected: "GrafanaAgent/v1.2.3 (flow; linux; helm)", GOOS: "linux", }, + { + Name: "brew", + Mode: "flow", + Expected: "GrafanaAgent/v1.2.3 (flow; darwin; brew)", + GOOS: "darwin", + Exe: "/opt/homebrew/bin/agent", + }, } for _, tst := range tests { t.Run(tst.Name, func(t *testing.T) { + if tst.Exe != "" { + executable = func() (string, error) { return tst.Exe, nil } + } else { + executable = func() (string, error) { return "/agent", nil } + } goos = tst.GOOS t.Setenv(deployModeEnv, tst.DeployMode) t.Setenv(modeEnv, tst.Mode) diff --git a/pkg/usagestats/stats.go b/pkg/usagestats/stats.go index 7256701b5003..d3418a5c4bde 100644 --- a/pkg/usagestats/stats.go +++ b/pkg/usagestats/stats.go @@ -10,6 +10,7 @@ import ( "runtime" "time" + "github.com/grafana/agent/internal/useragent" "github.com/prometheus/common/version" ) @@ -27,6 +28,7 @@ type Report struct { Metrics map[string]interface{} `json:"metrics"` Os string `json:"os"` Arch string `json:"arch"` + DeployMode string `json:"deployMode"` } func sendReport(ctx context.Context, seed *AgentSeed, interval time.Time, metrics map[string]interface{}) error { @@ -38,6 +40,7 @@ func sendReport(ctx context.Context, seed *AgentSeed, interval time.Time, metric Arch: runtime.GOARCH, Interval: interval, Metrics: metrics, + DeployMode: useragent.GetDeployMode(), } out, err := json.MarshalIndent(report, "", " ") if err != nil {