feat: enhance logging for relay announcements and add public lease readiness check

Kim committed Apr 17, 2026 at 16:51 UTC 81595ab651f5f49ad43490763bb7a51842671423
3 files changed +39 -12
portal/discovery/refresher.go
+28 -11
@@ -29,6 +29,7 @@ type Refresher struct {
29 httpClient *http.Client
30 overlay OverlayRuntime
31 directRecoveryFailures int
32 + lastAnnounceSuccess map[string]bool
33 }
34
35 func NewRefresher(relaySet *RelaySet, overlay OverlayRuntime) *Refresher {
@@ -46,6 +47,7 @@ func NewRefresher(relaySet *RelaySet, overlay OverlayRuntime) *Refresher {
47 },
48 overlay: overlay,
49 directRecoveryFailures: defaultRecoveryFailures,
50 + lastAnnounceSuccess: make(map[string]bool),
51 }
52 }
53
@@ -94,10 +96,12 @@ func (r *Refresher) announceSelf(ctx context.Context, descriptor types.RelayDesc
96 }
97 baseURL, err := url.Parse(relayURL)
98 if err != nil {
97 - log.Warn().
98 - Err(err).
99 - Str("relay", relayURL).
100 - Msg("relay discovery announce target skipped")
99 + if r.shouldLogAnnounce(relayURL, false) {
100 + log.Warn().
101 + Err(err).
102 + Str("relay", relayURL).
103 + Msg("relay discovery announce target skipped")
104 + }
105 continue
106 }
107
@@ -105,19 +109,32 @@ func (r *Refresher) announceSelf(ctx context.Context, descriptor types.RelayDesc
109 if ctx.Err() != nil {
110 return ctx.Err()
111 }
108 - log.Warn().
109 - Err(err).
110 - Str("relay", relayURL).
111 - Msg("relay discovery announce failed")
112 + if r.shouldLogAnnounce(relayURL, false) {
113 + log.Warn().
114 + Err(err).
115 + Str("relay", relayURL).
116 + Msg("relay discovery announce failed")
117 + }
118 continue
119 }
114 - log.Info().
115 - Str("relay", relayURL).
116 - Msg("relay discovery announce succeeded")
120 + if r.shouldLogAnnounce(relayURL, true) {
121 + log.Info().
122 + Str("relay", relayURL).
123 + Msg("relay discovery announce succeeded")
124 + }
125 }
126 return nil
127 }
128
129 +func (r *Refresher) shouldLogAnnounce(relayURL string, success bool) bool {
130 + previous, ok := r.lastAnnounceSuccess[relayURL]
131 + if ok && previous == success {
132 + return false
133 + }
134 + r.lastAnnounceSuccess[relayURL] = success
135 + return true
136 +}
137 +
138 func (r *Refresher) refreshHTTPS(ctx context.Context) error {
139 r.relaySet.mu.RLock()
140 states := make([]RelayState, 0, len(r.relaySet.relays))
portal/lease.go
+6
@@ -582,6 +582,12 @@ func (r *leaseRegistry) publicLease(record *leaseRecord) types.Lease {
582 }
583 if record.stream != nil {
584 lease.Ready = record.stream.ReadyCount()
585 + } else if record.isPublicEntry() {
586 + _, _, hasNextHop := record.nextHop()
587 + if !hasNextHop {
588 + return lease
589 + }
590 + lease.Ready = 1
591 }
592 return lease
593 }
portal/server.go
+5 -1
@@ -518,7 +518,11 @@ func (s *Server) runHopMux(ctx context.Context) error {
518 _ = stream.Conn.Close()
519 return
520 }
521 - log.Info().Str("remote_addr", stream.RemoteAddr).Bool("forward", record.isHopMiddle()).Msg("hop stream received")
521 + hopRole := "exit"
522 + if record.isHopMiddle() {
523 + hopRole = "middle"
524 + }
525 + log.Info().Str("remote_addr", stream.RemoteAddr).Str("hop_role", hopRole).Msg("hop stream received")
526 if err := s.bridgeLeaseConn(groupCtx, stream.Conn, record); err != nil {
527 log.Warn().Err(err).Str("remote_addr", stream.RemoteAddr).Msg("hop stream bridge failed")
528 _ = stream.Conn.Close()