wgengine: log node IDs when peers are added/removed (#381)
Also stop logging data sent/received from nodes we're not connected to (ie all those `x`s being logged in the `peers: ` line) Signed-off-by: Wendi <wendi.yu@yahoo.ca>
This commit is contained in:
+25
-4
@@ -15,6 +15,7 @@ import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/time/rate"
|
||||
)
|
||||
@@ -60,10 +61,10 @@ type limitData struct {
|
||||
}
|
||||
|
||||
// RateLimitedFn returns a rate-limiting Logf wrapping the given logf.
|
||||
// Messages are allowed through at a maximum of f messages/second, in
|
||||
// Messages are allowed through at a maximum of one message every f (where f is a time.Duration), in
|
||||
// bursts of up to burst messages at a time. Up to maxCache strings will be held at a time.
|
||||
func RateLimitedFn(logf Logf, f float64, burst int, maxCache int) Logf {
|
||||
r := rate.Limit(f)
|
||||
func RateLimitedFn(logf Logf, f time.Duration, burst int, maxCache int) Logf {
|
||||
r := rate.Every(f)
|
||||
var (
|
||||
mu sync.Mutex
|
||||
msgLim = make(map[string]*limitData) // keyed by logf format
|
||||
@@ -109,11 +110,31 @@ func RateLimitedFn(logf Logf, f float64, burst int, maxCache int) Logf {
|
||||
case warn:
|
||||
logf("Repeated messages were suppressed by rate limiting. Original message: %s",
|
||||
fmt.Sprintf(format, args...))
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// LogOnChange logs a given line only if line != lastLine, or if maxInterval has passed
|
||||
// since the last time this identical line was logged.
|
||||
func LogOnChange(logf Logf, maxInterval time.Duration, timeNow func() time.Time) Logf {
|
||||
var (
|
||||
sLastLogged string
|
||||
tLastLogged = timeNow()
|
||||
)
|
||||
|
||||
return func(format string, args ...interface{}) {
|
||||
s := fmt.Sprintf(format, args...)
|
||||
if s == sLastLogged && timeNow().Sub(tLastLogged) < maxInterval {
|
||||
return
|
||||
}
|
||||
|
||||
sLastLogged = s
|
||||
tLastLogged = timeNow()
|
||||
logf(s)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ArgWriter is a fmt.Formatter that can be passed to any Logf func to
|
||||
// efficiently write to a %v argument without allocations.
|
||||
type ArgWriter func(*bufio.Writer)
|
||||
|
||||
+56
-15
@@ -10,6 +10,7 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestFuncWriter(t *testing.T) {
|
||||
@@ -23,22 +24,21 @@ func TestStdLogger(t *testing.T) {
|
||||
lg.Printf("plumbed through")
|
||||
}
|
||||
|
||||
func TestRateLimiter(t *testing.T) {
|
||||
|
||||
// Testing function. args[0] should indicate what should
|
||||
logTester := func(want []string) Logf {
|
||||
i := 0
|
||||
return func(format string, args ...interface{}) {
|
||||
got := fmt.Sprintf(format, args...)
|
||||
if i >= len(want) {
|
||||
t.Fatalf("Logging continued past end of expected input: %s", got)
|
||||
}
|
||||
if got != want[i] {
|
||||
t.Fatalf("wanted: %s \n got: %s", want[i], got)
|
||||
}
|
||||
i++
|
||||
func logTester(want []string, t *testing.T, i *int) Logf {
|
||||
return func(format string, args ...interface{}) {
|
||||
got := fmt.Sprintf(format, args...)
|
||||
if *i >= len(want) {
|
||||
t.Fatalf("Logging continued past end of expected input: %s", got)
|
||||
}
|
||||
if got != want[*i] {
|
||||
t.Fatalf("wanted: %s \n got: %s", want[*i], got)
|
||||
}
|
||||
t.Log(got)
|
||||
*i++
|
||||
}
|
||||
}
|
||||
|
||||
func TestRateLimiter(t *testing.T) {
|
||||
|
||||
want := []string{
|
||||
"boring string with constant formatting (constant)",
|
||||
@@ -51,7 +51,9 @@ func TestRateLimiter(t *testing.T) {
|
||||
"4 shouldn't get filtered.",
|
||||
}
|
||||
|
||||
lg := RateLimitedFn(logTester(want), 1, 2, 50)
|
||||
testsRun := 0
|
||||
lgtest := logTester(want, t, &testsRun)
|
||||
lg := RateLimitedFn(lgtest, 1*time.Second, 2, 50)
|
||||
var prefixed Logf
|
||||
for i := 0; i < 10; i++ {
|
||||
lg("boring string with constant formatting %s", "(constant)")
|
||||
@@ -62,9 +64,48 @@ func TestRateLimiter(t *testing.T) {
|
||||
prefixed(" shouldn't get filtered.")
|
||||
}
|
||||
}
|
||||
if testsRun < len(want) {
|
||||
t.Fatalf("Tests after %s weren't logged.", want[testsRun])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func testTimer(d time.Duration) func() time.Time {
|
||||
timeNow := time.Now()
|
||||
return func() time.Time {
|
||||
timeNow = timeNow.Add(d)
|
||||
return timeNow
|
||||
}
|
||||
}
|
||||
|
||||
func TestLogOnChange(t *testing.T) {
|
||||
want := []string{
|
||||
"1 2 3 4 5 6",
|
||||
"1 2 3 4 5 6",
|
||||
"1 2 3 4 5 7",
|
||||
"1 2 3 4 5",
|
||||
"1 2 3 4 5 6 7",
|
||||
}
|
||||
|
||||
timeNow := testTimer(1 * time.Second)
|
||||
|
||||
testsRun := 0
|
||||
lgtest := logTester(want, t, &testsRun)
|
||||
lg := LogOnChange(lgtest, 5*time.Second, timeNow)
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
lg("%s", "1 2 3 4 5 6")
|
||||
}
|
||||
lg("1 2 3 4 5 7")
|
||||
lg("1 2 3 4 5")
|
||||
lg("1 2 3 4 5")
|
||||
lg("1 2 3 4 5 6 7")
|
||||
|
||||
if testsRun < len(want) {
|
||||
t.Fatalf("'Wanted' lines including and after [%s] weren't logged.", want[testsRun])
|
||||
}
|
||||
}
|
||||
|
||||
func TestArgWriter(t *testing.T) {
|
||||
got := new(bytes.Buffer)
|
||||
fmt.Fprintf(got, "Greeting: %v", ArgWriter(func(bw *bufio.Writer) {
|
||||
|
||||
Reference in New Issue
Block a user