Skip to content

Commit 233492b

Browse files
authored
fix: ensure coordinator debug output is always sorted (#5867)
1 parent 5da4b53 commit 233492b

File tree

1 file changed

+93
-45
lines changed

1 file changed

+93
-45
lines changed

tailnet/coordinator.go

+93-45
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"time"
1515

1616
"github.com/google/uuid"
17+
"golang.org/x/exp/slices"
1718
"golang.org/x/xerrors"
1819
"tailscale.com/tailcfg"
1920
"tailscale.com/types/key"
@@ -444,62 +445,109 @@ func (c *coordinator) ServeHTTPDebug(w http.ResponseWriter, _ *http.Request) {
444445
defer c.mutex.RUnlock()
445446

446447
fmt.Fprintln(w, "<h1>in-memory wireguard coordinator debug</h1>")
447-
fmt.Fprintf(w, "<h2 id=agents><a href=#agents>#</a> agents: total %d</h2>\n", len(c.agentSockets))
448-
fmt.Fprintln(w, "<ul>")
449-
for id, conn := range c.agentSockets {
450-
fmt.Fprintf(w, "<li><b>%s</b> (%s): created %v ago, write %v ago, overwrites %d </li>\n",
451-
conn.name,
452-
id.String(),
453-
now.Sub(time.Unix(conn.start, 0)).Round(time.Second),
454-
now.Sub(time.Unix(conn.lastWrite, 0)).Round(time.Second),
455-
conn.overwrites,
456-
)
457-
458-
if connCount := len(c.agentToConnectionSockets[id]); connCount > 0 {
459-
fmt.Fprintf(w, "<h3>connections: total %d</h3>\n", connCount)
460-
fmt.Fprintln(w, "<ul>")
461-
for id, conn := range c.agentToConnectionSockets[id] {
462-
fmt.Fprintf(w, "<li><b>%s</b> (%s): created %v ago, write %v ago </li>\n",
463-
conn.name,
464-
id.String(),
465-
now.Sub(time.Unix(conn.start, 0)).Round(time.Second),
466-
now.Sub(time.Unix(conn.lastWrite, 0)).Round(time.Second),
467-
)
468-
}
469-
fmt.Fprintln(w, "</ul>")
470-
}
448+
449+
type idConn struct {
450+
id uuid.UUID
451+
conn *trackedConn
471452
}
472-
fmt.Fprintln(w, "</ul>")
473453

474-
missingAgents := map[uuid.UUID]map[uuid.UUID]*trackedConn{}
475-
for agentID, conns := range c.agentToConnectionSockets {
476-
if len(conns) == 0 {
477-
continue
454+
{
455+
fmt.Fprintf(w, "<h2 id=agents><a href=#agents>#</a> agents: total %d</h2>\n", len(c.agentSockets))
456+
fmt.Fprintln(w, "<ul>")
457+
agentSockets := make([]idConn, 0, len(c.agentSockets))
458+
459+
for id, conn := range c.agentSockets {
460+
agentSockets = append(agentSockets, idConn{id, conn})
478461
}
479462

480-
if _, ok := c.agentSockets[agentID]; !ok {
481-
missingAgents[agentID] = conns
463+
slices.SortFunc(agentSockets, func(a, b idConn) bool {
464+
return a.conn.name < b.conn.name
465+
})
466+
467+
for _, agent := range agentSockets {
468+
fmt.Fprintf(w, "<li style=\"margin-top:4px\"><b>%s</b> (<code>%s</code>): created %v ago, write %v ago, overwrites %d </li>\n",
469+
agent.conn.name,
470+
agent.id.String(),
471+
now.Sub(time.Unix(agent.conn.start, 0)).Round(time.Second),
472+
now.Sub(time.Unix(agent.conn.lastWrite, 0)).Round(time.Second),
473+
agent.conn.overwrites,
474+
)
475+
476+
if conns := c.agentToConnectionSockets[agent.id]; len(conns) > 0 {
477+
fmt.Fprintf(w, "<h3 style=\"margin:0px;font-size:16px;font-weight:400\">connections: total %d</h3>\n", len(conns))
478+
479+
connSockets := make([]idConn, 0, len(conns))
480+
for id, conn := range conns {
481+
connSockets = append(connSockets, idConn{id, conn})
482+
}
483+
slices.SortFunc(connSockets, func(a, b idConn) bool {
484+
return a.id.String() < b.id.String()
485+
})
486+
487+
fmt.Fprintln(w, "<ul>")
488+
for _, connSocket := range connSockets {
489+
fmt.Fprintf(w, "<li><b>%s</b> (<code>%s</code>): created %v ago, write %v ago </li>\n",
490+
connSocket.conn.name,
491+
connSocket.id.String(),
492+
now.Sub(time.Unix(connSocket.conn.start, 0)).Round(time.Second),
493+
now.Sub(time.Unix(connSocket.conn.lastWrite, 0)).Round(time.Second),
494+
)
495+
}
496+
fmt.Fprintln(w, "</ul>")
497+
}
482498
}
499+
500+
fmt.Fprintln(w, "</ul>")
483501
}
484502

485-
fmt.Fprintf(w, "<h2 id=missing-agents><a href=#missing-agents>#</a> missing agents: total %d</h2>\n", len(missingAgents))
486-
fmt.Fprintln(w, "<ul>")
487-
for agentID, conns := range missingAgents {
488-
fmt.Fprintf(w, "<li><b>unknown</b> (%s): created ? ago, write ? ago, overwrites ? </li>\n",
489-
agentID.String(),
490-
)
503+
{
504+
type agentConns struct {
505+
id uuid.UUID
506+
conns []idConn
507+
}
491508

492-
fmt.Fprintf(w, "<h3>connections: total %d</h3>\n", len(conns))
509+
missingAgents := []agentConns{}
510+
for agentID, conns := range c.agentToConnectionSockets {
511+
if len(conns) == 0 {
512+
continue
513+
}
514+
515+
if _, ok := c.agentSockets[agentID]; !ok {
516+
connsSlice := make([]idConn, 0, len(conns))
517+
for id, conn := range conns {
518+
connsSlice = append(connsSlice, idConn{id, conn})
519+
}
520+
slices.SortFunc(connsSlice, func(a, b idConn) bool {
521+
return a.id.String() < b.id.String()
522+
})
523+
524+
missingAgents = append(missingAgents, agentConns{agentID, connsSlice})
525+
}
526+
}
527+
slices.SortFunc(missingAgents, func(a, b agentConns) bool {
528+
return a.id.String() < b.id.String()
529+
})
530+
531+
fmt.Fprintf(w, "<h2 id=missing-agents><a href=#missing-agents>#</a> missing agents: total %d</h2>\n", len(missingAgents))
493532
fmt.Fprintln(w, "<ul>")
494-
for id, conn := range conns {
495-
fmt.Fprintf(w, "<li><b>%s</b> (%s): created %v ago, write %v ago </li>\n",
496-
conn.name,
497-
id.String(),
498-
now.Sub(time.Unix(conn.start, 0)).Round(time.Second),
499-
now.Sub(time.Unix(conn.lastWrite, 0)).Round(time.Second),
533+
534+
for _, agentConns := range missingAgents {
535+
fmt.Fprintf(w, "<li style=\"margin-top:4px\"><b>unknown</b> (<code>%s</code>): created ? ago, write ? ago, overwrites ? </li>\n",
536+
agentConns.id.String(),
500537
)
538+
539+
fmt.Fprintf(w, "<h3 style=\"margin:0px;font-size:16px;font-weight:400\">connections: total %d</h3>\n", len(agentConns.conns))
540+
fmt.Fprintln(w, "<ul>")
541+
for _, agentConn := range agentConns.conns {
542+
fmt.Fprintf(w, "<li><b>%s</b> (<code>%s</code>): created %v ago, write %v ago </li>\n",
543+
agentConn.conn.name,
544+
agentConn.id.String(),
545+
now.Sub(time.Unix(agentConn.conn.start, 0)).Round(time.Second),
546+
now.Sub(time.Unix(agentConn.conn.lastWrite, 0)).Round(time.Second),
547+
)
548+
}
549+
fmt.Fprintln(w, "</ul>")
501550
}
502551
fmt.Fprintln(w, "</ul>")
503552
}
504-
fmt.Fprintln(w, "</ul>")
505553
}

0 commit comments

Comments
 (0)