Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions agent/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/superfly/flyctl/internal/config"
"github.com/superfly/flyctl/internal/env"
"github.com/superfly/flyctl/internal/flyutil"
"github.com/superfly/flyctl/internal/metrics"
"github.com/superfly/flyctl/internal/metrics/synthetics"
"github.com/superfly/flyctl/internal/sentry"
"github.com/superfly/flyctl/internal/wireguard"
Expand Down Expand Up @@ -245,7 +246,10 @@ func (s *server) buildTunnel(ctx context.Context, org *fly.Organization, reestab
}

// WIP: can't stay this way, need something more clever than this
transport := "udp"
if env.IsCI() || os.Getenv("WSWG") != "" || s.ConfigWebsockets {
transport = "websocket"

if tunnel, err = wg.ConnectWS(ctx, state); err != nil {
return
}
Expand All @@ -255,6 +259,10 @@ func (s *server) buildTunnel(ctx context.Context, org *fly.Organization, reestab
}
}

// use the agent's run context: the session context may be gone before the
// send completes
metrics.AgentWireGuardTransport(s.runCtx, transport)

s.tunnels[tk] = tunnel

return
Expand Down
29 changes: 29 additions & 0 deletions internal/metrics/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,35 @@ func rawSend(parentCtx context.Context, metricSlug string, payload json.RawMessa
queueMetric(message)
}

// SendImmediate sends a single metric to the collector right away instead of
// queueing it for the end-of-command flush. Long-running processes (e.g. the
// agent) queue metrics that would otherwise never be flushed.
func SendImmediate[T any](ctx context.Context, metricSlug string, value T) {
if !shouldSendMetrics(ctx) {
return
}

payload, err := json.Marshal(value)
if err != nil {
return
}

buf, err := json.Marshal([]metricsMessage{{
Metric: metricSlug,
Payload: payload,
}})
if err != nil {
return
}

done.Add(1)
go func() {
defer done.Done()

_ = SendMetrics(ctx, string(buf))
}()
}

func shouldSendMetrics(ctx context.Context) bool {
if !Enabled {
return false
Expand Down
7 changes: 7 additions & 0 deletions internal/metrics/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,13 @@ func DeployStatus(ctx context.Context, payload DeployStatusPayload) {
Send(ctx, "deploy/status", payload)
}

// AgentWireGuardTransport reports which transport the agent used to establish
// a WireGuard tunnel: "udp" or "websocket". It sends immediately because the
// agent daemon never reaches the end-of-command metrics flush.
func AgentWireGuardTransport(ctx context.Context, transport string) {
SendImmediate(ctx, "agent_wireguard/transport", map[string]string{"transport": transport})
}

func Send[T any](ctx context.Context, metricSlug string, value T) {
valJson, err := json.Marshal(value)
if err != nil {
Expand Down
Loading