Skip to content

Commit 127e03f

Browse files
committed
fix(hosterrorscache): dup log spam for permanent errs
The "Skipped X from target list as found unresponsive permanently" message was logged on every `(*Cache).Check()` call for hosts with permanent errors, resulting in thousands of duplicate log entries in verbose mode. Wrap the log statement in `sync.Once` to match the behavior already used for non-permanent error logging. Signed-off-by: Dwi Siswanto <git@dw1.io>
1 parent cf3b5bf commit 127e03f

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

pkg/protocols/common/hosterrorscache/hosterrorscache.go

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ type CacheInterface interface {
2727
Remove(ctx *contextargs.Context) // remove a host from the cache
2828
MarkFailed(protoType string, ctx *contextargs.Context, err error) // record a failure (and cause) for the host
2929
MarkFailedOrRemove(protoType string, ctx *contextargs.Context, err error) // record a failure (and cause) for the host or remove it
30+
IsPermanentErr(ctx *contextargs.Context, err error) bool // return true if the error is permanent for the host
3031
}
3132

3233
var (
@@ -137,8 +138,9 @@ func (c *Cache) Check(protoType string, ctx *contextargs.Context) bool {
137138
defer cache.mu.Unlock()
138139

139140
if cache.isPermanentErr {
140-
// skipping permanent errors is expected so verbose instead of info
141-
gologger.Verbose().Msgf("Skipped %s from target list as found unresponsive permanently: %s", finalValue, cache.cause)
141+
cache.Do(func() {
142+
gologger.Info().Msgf("Skipped %s from target list as found unresponsive permanently: %s", finalValue, cache.cause)
143+
})
142144
return true
143145
}
144146

@@ -232,6 +234,28 @@ func (c *Cache) MarkFailedOrRemove(protoType string, ctx *contextargs.Context, e
232234
_ = c.failedTargets.Set(cacheKey, cache)
233235
}
234236

237+
// IsPermanentErr returns true if the error is permanent for the host.
238+
func (c *Cache) IsPermanentErr(ctx *contextargs.Context, err error) bool {
239+
if err == nil {
240+
return false
241+
}
242+
243+
if errkit.IsKind(err, errkit.ErrKindNetworkPermanent) {
244+
return true
245+
}
246+
247+
cacheKey := c.GetKeyFromContext(ctx, err)
248+
cache, cacheErr := c.failedTargets.GetIFPresent(cacheKey)
249+
if cacheErr != nil {
250+
return false
251+
}
252+
253+
cache.mu.Lock()
254+
defer cache.mu.Unlock()
255+
256+
return cache.isPermanentErr
257+
}
258+
235259
// GetKeyFromContext returns the key for the cache from the context
236260
func (c *Cache) GetKeyFromContext(ctx *contextargs.Context, err error) string {
237261
// Note:

pkg/protocols/http/request_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,9 @@ func (f *fakeHostErrorsCache) MarkFailedOrRemove(string, *contextargs.Context, e
274274
// Check always returns true to simulate an already unresponsive host
275275
func (f *fakeHostErrorsCache) Check(string, *contextargs.Context) bool { return true }
276276

277+
// IsPermanentErr returns false for tests
278+
func (f *fakeHostErrorsCache) IsPermanentErr(*contextargs.Context, error) bool { return false }
279+
277280
func TestExecuteParallelHTTP_StopAtFirstMatch(t *testing.T) {
278281
options := testutils.DefaultOptions
279282
testutils.Init(options)

0 commit comments

Comments
 (0)