diff --git a/internal/command/deploy/deploy.go b/internal/command/deploy/deploy.go index 82fc37a8e8..837a9ebfcc 100644 --- a/internal/command/deploy/deploy.go +++ b/internal/command/deploy/deploy.go @@ -9,6 +9,7 @@ import ( "github.com/logrusorgru/aurora" "github.com/spf13/cobra" + "github.com/superfly/client-signals/go" "github.com/superfly/fly-go/flaps" "github.com/superfly/flyctl/internal/appconfig" "github.com/superfly/flyctl/internal/build/imgsrc" @@ -517,6 +518,7 @@ func deployToMachines( startTime := time.Now() var status metrics.DeployStatusPayload + status.Operator, status.AgentName = metrics.OperatorFromSignals(clientsignals.DetectOnce()) metrics.Started(ctx, "deploy") // TODO: remove this once there is nothing upstream using it diff --git a/internal/command/launch/cmd.go b/internal/command/launch/cmd.go index 8ffe362623..e9df05598b 100644 --- a/internal/command/launch/cmd.go +++ b/internal/command/launch/cmd.go @@ -15,6 +15,7 @@ import ( "github.com/logrusorgru/aurora" "github.com/samber/lo" "github.com/spf13/cobra" + "github.com/superfly/client-signals/go" "github.com/superfly/flyctl/gql" "github.com/superfly/flyctl/internal/appconfig" "github.com/superfly/flyctl/internal/appsecrets" @@ -303,6 +304,7 @@ func run(ctx context.Context) (err error) { startTime := time.Now() var status metrics.LaunchStatusPayload + status.Operator, status.AgentName = metrics.OperatorFromSignals(clientsignals.DetectOnce()) metrics.Started(ctx, "launch") var state *launchState = nil diff --git a/internal/metrics/helpers.go b/internal/metrics/helpers.go index 7a9b023f98..d02a6fa1a5 100644 --- a/internal/metrics/helpers.go +++ b/internal/metrics/helpers.go @@ -6,6 +6,7 @@ import ( "sync" "time" + "github.com/superfly/client-signals/go" "github.com/superfly/flyctl/terminal" ) @@ -80,6 +81,8 @@ type LaunchStatusPayload struct { ScannerFamily string `json:"scanner_family"` FlyctlVersion string `json:"flyctlVersion"` + Operator string `json:"operator,omitempty"` + AgentName string `json:"agentName,omitempty"` } func LaunchStatus(ctx context.Context, payload LaunchStatusPayload) { @@ -113,6 +116,8 @@ type DeployStatusPayload struct { Strategy string `json:"strategy"` FlyctlVersion string `json:"flyctlVersion"` + Operator string `json:"operator,omitempty"` + AgentName string `json:"agentName,omitempty"` } func DeployStatus(ctx context.Context, payload DeployStatusPayload) { @@ -159,6 +164,22 @@ func StartTiming(ctx context.Context, metricSlug string) func() { } } +// OperatorFromSignals returns an operator classification and, when the +// operator is "agent", the agent name. Precedence: ci > agent > interactive. +// Falls back to "unknown" when none of the signals match. +func OperatorFromSignals(s clientsignals.Signals) (operator, agentName string) { + switch { + case s.CI: + return "ci", "" + case s.Agent != "": + return "agent", s.Agent + case s.Interactive: + return "interactive", "" + default: + return "unknown", "" + } +} + type disableFlushMetricsKey struct{} // WithDisableFlushMetrics returns a context with a flag that disables