8000 chore: add DRPC tailnet & cli network telemetry by ethanndickson · Pull Request #13687 · coder/coder · GitHub
[go: up one dir, main page]

Skip to content

chore: add DRPC tailnet & cli network telemetry #13687

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
ping and speedtest telemetry
  • Loading branch information
ethanndickson committed Jul 2, 2024
commit b9cd8fb7e019b49e273b1efddb568a330bbd8878
1 change: 1 addition & 0 deletions cli/speedtest.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ func (r *RootCmd) speedtest() *serpent.Command {
outputResult.Intervals[i] = interval
}
}
_ = conn.Conn.SendSpeedtestTelemetry(outputResult.Overall.ThroughputMbits)
out, err := formatter.Format(inv.Context(), outputResult)
if err != nil {
return err
Expand Down
3 changes: 0 additions & 3 deletions coderd/telemetry/telemetry.go
Original file line number Diff line number Diff line change
Expand Up @@ -1221,14 +1221,11 @@ func netcheckFromProto(proto *tailnetproto.Netcheck) Netcheck {

PreferredDERP: proto.PreferredDERP,

RegionLatency: durationMapFromProto(proto.RegionLatency),
RegionV4Latency: durationMapFromProto(proto.RegionV4Latency),
RegionV6Latency: durationMapFromProto(proto.RegionV6Latency),

GlobalV4: netcheckIPFromProto(proto.GlobalV4),
GlobalV6: netcheckIPFromProto(proto.GlobalV6),

CaptivePortal: protoBool(proto.CaptivePortal),
}
}

Expand Down
2 changes: 1 addition & 1 deletion codersdk/workspacesdk/connector_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ func (*fakeDRPCClient) DRPCConn() drpc.Conn {
}

// PostTelemetry implements proto.DRPCTailnetClient.
func (f *fakeDRPCClient) PostTelemetry(_ context.Context, in *proto.TelemetryRequest) (*proto.TelemetryResponse, error) {
func (f *fakeDRPCClient) PostTelemetry(_ context.Context, _ *proto.TelemetryRequest) (*proto.TelemetryResponse, error) {
return nil, f.telemeteryErorr
}

Expand Down
59 changes: 51 additions & 8 deletions tailnet/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,12 @@ func (c *Conn) Status() *ipnstate.Status {
// Ping sends a ping to the Wireguard engine.
// The bool returned is true if the ping was performed P2P.
func (c *Conn) Ping(ctx context.Context, ip netip.Addr) (time.Duration, bool, *ipnstate.PingResult, error) {
return c.pingWithType(ctx, ip, tailcfg.PingDisco)
dur, p2p, pr, err := c.pingWithType(ctx, ip, tailcfg.PingDisco)
if err == nil {
// TODO(ethanndickson): Is this too often?
_ = c.sendPingTelemetry(dur, p2p)
}
return dur, p2p, pr, err
}

func (c *Conn) pingWithType(ctx context.Context, ip netip.Addr, pt tailcfg.PingType) (time.Duration, bool, *ipnstate.PingResult, error) {
Expand Down Expand Up @@ -525,7 +530,7 @@ func (c *Conn) AwaitReachable(ctx context.Context, ip netip.Addr) bool {
case <-completedCtx.Done():
// TODO(ethanndickson): For now, I'm interpreting 'connected' as when the
// agent is reachable.
// _ = c.connectedTelemetryEvent()
_ = c.sendConnectedTelemetry()
return true
case <-t.C:
// Pings can take a while, so we can run multiple
Expand Down Expand Up @@ -715,7 +720,24 @@ func (c *Conn) MagicsockServeHTTPDebug(w http.ResponseWriter, r *http.Request) {
c.magicConn.ServeHTTPDebug(w, r)
}

func (c *Conn) connectedTelemetryEvent() error {
func (c *Conn) sendConnectedTelemetry() error {
if c.telemetrySink == nil {
return nil
}
e, err := c.newTelemetryEvent()
if err != nil {
return xerrors.Errorf("create telemetry event: %w", err)
}
e.Status = proto.TelemetryEvent_CONNECTED
c.telemetryWg.Add(1)
go func() {
defer c.telemetryWg.Done()
c.telemetrySink.SendTelemetryEvent(e)
}()
return nil
}

func (c *Conn) SendSpeedtestTelemetry(throughputMbits float64) error {
if c.telemetrySink == nil {
return nil
}
Expand All @@ -724,6 +746,30 @@ func (c *Conn) connectedTelemetryEvent() error {
return xerrors.Errorf("create telemetry event: %w", err)
}
e.Status = proto.TelemetryEvent_CONNECTED
e.ThroughputMbits = wrapperspb.Float(float32(throughputMbits))
c.telemetryWg.Add(1)
go func() {
defer c.telemetryWg.Done()
c.telemetrySink.SendTelemetryEvent(e)
8000 }()
return nil
}

// nolint: revive
func (c *Conn) sendPingTelemetry(latency time.Duration, p2p bool) error {
if c.telemetrySink == nil {
return nil
}
e, err := c.newTelemetryEvent()
if err != nil {
return xerrors.Errorf("create telemetry event: %w", err)
}
e.Status = proto.TelemetryEvent_CONNECTED
if p2p {
e.P2PLatency = durationpb.New(latency)
} else {
e.DerpLatency = durationpb.New(latency)
}
c.telemetryWg.Add(1)
go func() {
defer c.telemetryWg.Done()
Expand Down Expand Up @@ -754,14 +800,11 @@ func (c *Conn) newTelemetryEvent() (*proto.TelemetryEvent, error) {
Application: "",
NodeIdRemote: 0,
P2PEndpoint: &proto.TelemetryEvent_P2PEndpoint{},
ThroughputMbits: &wrapperspb.FloatValue{},
HomeDerp: "",
ConnectionAge: &durationpb.Duration{},
ConnectionSetup: &durationpb.Duration{},
P2PSetup: &durationpb.Duration{},
// TODO: One of these two
DerpLatency: &durationpb.Duration{},
P2PLatency: &durationpb.Duration{},
// TODO: We only calculate this in one place, do we really want it?
P2PSetup: &durationpb.Duration{},
}, nil
}

Expand Down
17 changes: 7 additions & 10 deletions tailnet/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,8 @@ func NetInfoToProto(netInfo *tailcfg.NetInfo) *proto.Netcheck {
}
return &proto.Netcheck{
UDP: netInfo.WorkingUDP.EqualBool(true),
IPv6CanSend: netInfo.WorkingIPv6.EqualBool(true),
OSHasIPv6: netInfo.OSHasIPv6.EqualBool(true),
IPv6: netInfo.WorkingIPv6.EqualBool(true),
ICMPv4: netInfo.WorkingICMPv4.EqualBool(true),
MappingVariesByDestIP: wrapperspb.Bool(netInfo.MappingVariesByDestIP.EqualBool(true)),
HairPinning: wrapperspb.Bool(netInfo.HairPinning.EqualBool(true)),
Expand All @@ -315,14 +315,11 @@ func NetInfoToProto(netInfo *tailcfg.NetInfo) *proto.Netcheck {
PreferredDERP: int64(netInfo.PreferredDERP),
RegionV4Latency: rlv4,
RegionV6Latency: rlv6,
// TODO: what's the most useful value to have here?
RegionLatency: make(map[int64]*durationpb.Duration),
// TODO: None of these are exposed by tailscale
IPv4CanSend: false,
IPv4: false,
IPv6: false,
GlobalV4: &proto.Netcheck_NetcheckIP{},
GlobalV6: &proto.Netcheck_NetcheckIP{},
CaptivePortal: &wrapperspb.BoolValue{},
// TODO: These aren't yet exposed by Tailscale
IPv6CanSend: false,
IPv4CanSend: false,
IPv4: false,
GlobalV4: &proto.Netcheck_NetcheckIP{},
GlobalV6: &proto.Netcheck_NetcheckIP{},
}
}
Loading
Loading
0