This commit is contained in:
2026-02-19 10:07:43 +00:00
parent 007438e372
commit 6e637ecf77
1763 changed files with 60820 additions and 279516 deletions

View File

@@ -4,39 +4,46 @@
package netmon
import (
"context"
"sync"
"time"
"tailscale.com/types/logger"
"tailscale.com/util/eventbus"
)
const cooldownSeconds = 300
// LinkChangeLogLimiter returns a new [logger.Logf] that logs each unique
// format string to the underlying logger only once per major LinkChange event.
// format string to the underlying logger only once per major LinkChange event
// with a cooldownSeconds second cooldown.
//
// The returned function should be called when the logger is no longer needed,
// to release resources from the Monitor.
func LinkChangeLogLimiter(logf logger.Logf, nm *Monitor) (_ logger.Logf, unregister func()) {
var formatSeen sync.Map // map[string]bool
unregister = nm.RegisterChangeCallback(func(cd *ChangeDelta) {
// If we're in a major change or a time jump, clear the seen map.
if cd.Major || cd.TimeJumped {
formatSeen.Clear()
// The logger stops tracking seen format strings when the provided context is
// done.
func LinkChangeLogLimiter(ctx context.Context, logf logger.Logf, nm *Monitor) logger.Logf {
var formatLastSeen sync.Map // map[string]int64
sub := eventbus.SubscribeFunc(nm.b, func(cd *ChangeDelta) {
// Any link changes that are flagged as likely require a rebind are
// interesting enough that we should log them.
if cd.RebindLikelyRequired {
formatLastSeen.Clear()
}
})
context.AfterFunc(ctx, sub.Close)
return func(format string, args ...any) {
// We only store 'true' in the map, so if it's present then it
// means we've already logged this format string.
_, loaded := formatSeen.LoadOrStore(format, true)
if loaded {
// TODO(andrew-d): we may still want to log this
// message every N minutes (1x/hour?) even if it's been
// seen, so that debugging doesn't require searching
// back in the logs for an unbounded amount of time.
//
// See: https://github.com/tailscale/tailscale/issues/13145
return
// get the current timestamp
now := time.Now().Unix()
lastSeen, ok := formatLastSeen.Load(format)
if ok {
// if we've seen this format string within the last cooldownSeconds, skip logging
if now-lastSeen.(int64) < cooldownSeconds {
return
}
}
// update the last seen timestamp for this format string
formatLastSeen.Store(format, now)
logf(format, args...)
}, unregister
}
}