diff --git a/go.mod b/go.mod index 36106aa066f..19e50e4b5aa 100644 --- a/go.mod +++ b/go.mod @@ -52,7 +52,7 @@ require ( github.com/stretchr/testify v1.7.0 github.com/thanos-io/thanos v0.22.0 github.com/uber/jaeger-client-go v2.29.1+incompatible - github.com/weaveworks/common v0.0.0-20211015155308-ebe5bdc2c89e + github.com/weaveworks/common v0.0.0-20211025090655-ffcd684ef9ae go.etcd.io/bbolt v1.3.6 go.uber.org/atomic v1.9.0 go.uber.org/goleak v1.1.10 diff --git a/go.sum b/go.sum index 363e745d2fa..3b9b721875a 100644 --- a/go.sum +++ b/go.sum @@ -1463,8 +1463,8 @@ github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1 github.com/weaveworks/common v0.0.0-20210722103813-e649eff5ab4a/go.mod h1:YU9FvnS7kUnRt6HY10G+2qHkwzP3n3Vb1XsXDsJTSp8= github.com/weaveworks/common v0.0.0-20210901124008-1fa3f9fa874c/go.mod h1:YU9FvnS7kUnRt6HY10G+2qHkwzP3n3Vb1XsXDsJTSp8= github.com/weaveworks/common v0.0.0-20210913144402-035033b78a78/go.mod h1:YU9FvnS7kUnRt6HY10G+2qHkwzP3n3Vb1XsXDsJTSp8= -github.com/weaveworks/common v0.0.0-20211015155308-ebe5bdc2c89e h1:B0gVGyVpjfWJWSRe027EkhmEype0a0Dt2uHVxcPrhfs= -github.com/weaveworks/common v0.0.0-20211015155308-ebe5bdc2c89e/go.mod h1:GWX2dQ7yjrgvqH0+d3kCJC5bsY8oOFwqjxFMHaRK4/k= +github.com/weaveworks/common v0.0.0-20211025090655-ffcd684ef9ae h1:6bfJszypmVh6ViTaxvoB7ICYIwJ16DdBfBxNWt5lhnE= +github.com/weaveworks/common v0.0.0-20211025090655-ffcd684ef9ae/go.mod h1:GWX2dQ7yjrgvqH0+d3kCJC5bsY8oOFwqjxFMHaRK4/k= github.com/weaveworks/promrus v1.2.0 h1:jOLf6pe6/vss4qGHjXmGz4oDJQA+AOCqEL3FvvZGz7M= github.com/weaveworks/promrus v1.2.0/go.mod h1:SaE82+OJ91yqjrE1rsvBWVzNZKcHYFtMUyS1+Ogs/KA= github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= diff --git a/vendor/github.com/weaveworks/common/logging/dedupe.go b/vendor/github.com/weaveworks/common/logging/dedupe.go deleted file mode 100644 index caa523ef93f..00000000000 --- a/vendor/github.com/weaveworks/common/logging/dedupe.go +++ /dev/null @@ -1,137 +0,0 @@ -package logging - -import ( - "fmt" - "strings" - "sync" - "time" - - log "github.com/sirupsen/logrus" -) - -const ( - defaultDedupeInterval = time.Minute -) - -// SetupDeduplication should be performed after any other logging setup. -// For all logs less severe or equal to the given log level (but still higher than the logger's configured log level), -// these logs will be 'deduplicated'. What this means is that, excluding certain special fields like time, multiple -// identical log entries will be grouped up and a summary message emitted. -// For example, instead of: -// 00:00:00 INFO User 123 did xyz -// 00:00:10 INFO User 123 did xyz -// 00:00:25 INFO User 123 did xyz -// 00:00:55 INFO User 123 did xyz -// you would get: -// 00:00:00 INFO User 123 did xyz -// 00:01:00 INFO Repeated 3 times: User 123 did xyz -// The interval argument controls how long to wait for additional messages to arrive before reporting. -// Increase it to deduplicate more aggressively, decrease it to lower latency from a log occurring to it appearing. -// Set it to 0 to pick a sensible default value (recommended). -// NOTE: For simplicity and efficiency, fields are considered 'equal' if and only if their string representations (%v) are equal. -func SetupDeduplication(logLevel string, interval time.Duration) error { - dedupeLevel, err := log.ParseLevel(logLevel) - if err != nil { - return fmt.Errorf("Error parsing log level: %v", err) - } - if interval <= 0 { - interval = defaultDedupeInterval - } - - // We use a special Formatter to either format the log using the original formatter, or to return "" - // so nothing will be written for that event. The repeated entries are later logged along with a field flag - // that tells the formatter to ignore the message. - stdLogger := log.StandardLogger() - stdLogger.Formatter = newDedupeFormatter(stdLogger.Formatter, dedupeLevel, interval) - return nil -} - -type entryCount struct { - entry log.Entry - count int -} - -type dedupeFormatter struct { - innerFormatter log.Formatter - level log.Level - interval time.Duration - seen map[string]entryCount - lock sync.Mutex -} - -func newDedupeFormatter(innerFormatter log.Formatter, level log.Level, interval time.Duration) *dedupeFormatter { - return &dedupeFormatter{ - innerFormatter: innerFormatter, - level: level, - interval: interval, - seen: map[string]entryCount{}, - } -} - -func (f *dedupeFormatter) Format(entry *log.Entry) ([]byte, error) { - if f.shouldLog(entry) { - b, err := f.innerFormatter.Format(entry) - return b, err - } - return []byte{}, nil -} - -func (f *dedupeFormatter) shouldLog(entry *log.Entry) bool { - if _, ok := entry.Data["deduplicated"]; ok { - // ignore our own logs about deduped messages - return true - } - if entry.Level < f.level { - // ignore logs more severe than our level - return true - } - key := fmt.Sprintf("%s %s", entry.Message, fieldsToString(entry.Data)) - f.lock.Lock() - defer f.lock.Unlock() - if ec, ok := f.seen[key]; ok { - // already seen, increment count and do not log - ec.count++ - f.seen[key] = ec - return false - } - // New message, log it but add it to seen. - // We need to copy because the pointer ceases to be valid after we return from Format - f.seen[key] = entryCount{entry: *entry} - go f.evictEntry(key) // queue to evict later - return true -} - -// Wait for interval seconds then evict the entry and send the log -func (f *dedupeFormatter) evictEntry(key string) { - time.Sleep(f.interval) - var ec entryCount - func() { - f.lock.Lock() - defer f.lock.Unlock() - ec = f.seen[key] - delete(f.seen, key) - }() - if ec.count == 0 { - return - } - entry := log.WithFields(ec.entry.Data).WithField("deduplicated", ec.count) - message := fmt.Sprintf("Repeated %d times: %s", ec.count, ec.entry.Message) - // There's no way to choose the log level dynamically, so we have to do this hack - map[log.Level]func(args ...interface{}){ - log.PanicLevel: entry.Panic, - log.FatalLevel: entry.Fatal, - log.ErrorLevel: entry.Error, - log.WarnLevel: entry.Warn, - log.InfoLevel: entry.Info, - log.DebugLevel: entry.Debug, - }[ec.entry.Level](message) -} - -func fieldsToString(data log.Fields) string { - parts := make([]string, 0, len(data)) - // traversal order here is arbitrary but stable, which is fine for our purposes - for k, v := range data { - parts = append(parts, fmt.Sprintf("%s=%v", k, v)) - } - return strings.Join(parts, " ") -} diff --git a/vendor/github.com/weaveworks/common/logging/gokit.go b/vendor/github.com/weaveworks/common/logging/gokit.go index 9384d30a115..e4b6fdc032c 100644 --- a/vendor/github.com/weaveworks/common/logging/gokit.go +++ b/vendor/github.com/weaveworks/common/logging/gokit.go @@ -17,8 +17,13 @@ func NewGoKitFormat(l Level, f Format) Interface { } else { logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr)) } + return addStandardFields(logger, l) +} + +// stand-alone for test purposes +func addStandardFields(logger log.Logger, l Level) Interface { + logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.Caller(5)) logger = level.NewFilter(logger, l.Gokit) - logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller) return gokit{logger} } @@ -36,32 +41,52 @@ type gokit struct { log.Logger } +// Helper to defer sprintf until it is needed. +type sprintf struct { + format string + args []interface{} +} + +func (s *sprintf) String() string { + return fmt.Sprintf(s.format, s.args...) +} + +// Helper to defer sprint until it is needed. +// Note we don't use Sprintln because the output is passed to go-kit as one value among many on a line +type sprint struct { + args []interface{} +} + +func (s *sprint) String() string { + return fmt.Sprint(s.args...) +} + func (g gokit) Debugf(format string, args ...interface{}) { - level.Debug(g.Logger).Log("msg", fmt.Sprintf(format, args...)) + level.Debug(g.Logger).Log("msg", &sprintf{format: format, args: args}) } func (g gokit) Debugln(args ...interface{}) { - level.Debug(g.Logger).Log("msg", fmt.Sprintln(args...)) + level.Debug(g.Logger).Log("msg", &sprint{args: args}) } func (g gokit) Infof(format string, args ...interface{}) { - level.Info(g.Logger).Log("msg", fmt.Sprintf(format, args...)) + level.Info(g.Logger).Log("msg", &sprintf{format: format, args: args}) } func (g gokit) Infoln(args ...interface{}) { - level.Info(g.Logger).Log("msg", fmt.Sprintln(args...)) + level.Info(g.Logger).Log("msg", &sprint{args: args}) } func (g gokit) Warnf(format string, args ...interface{}) { - level.Warn(g.Logger).Log("msg", fmt.Sprintf(format, args...)) + level.Warn(g.Logger).Log("msg", &sprintf{format: format, args: args}) } func (g gokit) Warnln(args ...interface{}) { - level.Warn(g.Logger).Log("msg", fmt.Sprintln(args...)) + level.Warn(g.Logger).Log("msg", &sprint{args: args}) } func (g gokit) Errorf(format string, args ...interface{}) { - level.Error(g.Logger).Log("msg", fmt.Sprintf(format, args...)) + level.Error(g.Logger).Log("msg", &sprintf{format: format, args: args}) } func (g gokit) Errorln(args ...interface{}) { - level.Error(g.Logger).Log("msg", fmt.Sprintln(args...)) + level.Error(g.Logger).Log("msg", &sprint{args: args}) } func (g gokit) WithField(key string, value interface{}) Interface { diff --git a/vendor/github.com/weaveworks/common/server/server.go b/vendor/github.com/weaveworks/common/server/server.go index 58da4ae3acd..63d505370d2 100644 --- a/vendor/github.com/weaveworks/common/server/server.go +++ b/vendor/github.com/weaveworks/common/server/server.go @@ -171,6 +171,13 @@ func New(cfg Config) (*Server, error) { }, []string{"protocol"}) prometheus.MustRegister(tcpConnections) + tcpConnectionsLimit := prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: cfg.MetricsNamespace, + Name: "tcp_connections_limit", + Help: "The max number of TCP connections that can be accepted (0 means no limit).", + }, []string{"protocol"}) + prometheus.MustRegister(tcpConnectionsLimit) + network := cfg.HTTPListenNetwork if network == "" { network = DefaultNetwork @@ -182,6 +189,7 @@ func New(cfg Config) (*Server, error) { } httpListener = middleware.CountingListener(httpListener, tcpConnections.WithLabelValues("http")) + tcpConnectionsLimit.WithLabelValues("http").Set(float64(cfg.HTTPConnLimit)) if cfg.HTTPConnLimit > 0 { httpListener = netutil.LimitListener(httpListener, cfg.HTTPConnLimit) } @@ -196,6 +204,7 @@ func New(cfg Config) (*Server, error) { } grpcListener = middleware.CountingListener(grpcListener, tcpConnections.WithLabelValues("grpc")) + tcpConnectionsLimit.WithLabelValues("grpc").Set(float64(cfg.GRPCConnLimit)) if cfg.GRPCConnLimit > 0 { grpcListener = netutil.LimitListener(grpcListener, cfg.GRPCConnLimit) } diff --git a/vendor/modules.txt b/vendor/modules.txt index 6ad1f40e9a4..c6876664a59 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -643,7 +643,7 @@ github.com/uber/jaeger-client-go/utils # github.com/uber/jaeger-lib v2.4.1+incompatible github.com/uber/jaeger-lib/metrics github.com/uber/jaeger-lib/metrics/prometheus -# github.com/weaveworks/common v0.0.0-20211015155308-ebe5bdc2c89e +# github.com/weaveworks/common v0.0.0-20211025090655-ffcd684ef9ae ## explicit github.com/weaveworks/common/aws github.com/weaveworks/common/errors