Log errors only once for event notification errors (#5905)

This commit is contained in:
Krishna Srinivas 2018-05-09 15:59:45 -07:00 committed by Dee Koder
parent 4886bfbc72
commit cc8178cdc4
2 changed files with 83 additions and 1 deletions

82
cmd/logger/logonce.go Normal file
View File

@ -0,0 +1,82 @@
/*
* Minio Cloud Storage, (C) 2018 Minio, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package logger
import (
"context"
"sync"
"time"
)
// Holds a map of recently logged errors.
type logOnceType struct {
IDMap map[interface{}]error
sync.Mutex
}
// One log message per error.
func (l *logOnceType) logOnceIf(ctx context.Context, err error, id interface{}) {
if err == nil {
return
}
l.Lock()
shouldLog := false
prevErr := l.IDMap[id]
if prevErr == nil {
l.IDMap[id] = err
shouldLog = true
} else {
if prevErr.Error() != err.Error() {
l.IDMap[id] = err
shouldLog = true
}
}
l.Unlock()
if shouldLog {
LogIf(ctx, err)
}
}
// Cleanup the map every 30 minutes so that the log message is printed again for the user to notice.
func (l *logOnceType) cleanupRoutine() {
for {
select {
case <-time.After(time.Minute * 30):
l.Lock()
l.IDMap = make(map[interface{}]error)
l.Unlock()
}
}
}
// Returns logOnceType
func newLogOnceType() *logOnceType {
l := &logOnceType{IDMap: make(map[interface{}]error)}
go l.cleanupRoutine()
return l
}
var logOnce = newLogOnceType()
// LogOnceIf - Logs notification errors - once per error.
// id is a unique identifier for related log messages, refer to cmd/notification.go
// on how it is used.
func LogOnceIf(ctx context.Context, err error, id interface{}) {
logOnce.logOnceIf(ctx, err, id)
}

View File

@ -532,7 +532,7 @@ func sendEvent(args eventArgs) {
reqInfo.AppendTags("EventName", args.EventName.String()) reqInfo.AppendTags("EventName", args.EventName.String())
reqInfo.AppendTags("targetID", err.ID.Name) reqInfo.AppendTags("targetID", err.ID.Name)
ctx := logger.SetReqInfo(context.Background(), reqInfo) ctx := logger.SetReqInfo(context.Background(), reqInfo)
logger.LogIf(ctx, err.Err) logger.LogOnceIf(ctx, err.Err, err.ID)
} }
} }