1 /* 2 Copyright 2018 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package log 18 19 import ( 20 "sync" 21 22 "github.com/go-logr/logr" 23 ) 24 25 // KubeAPIWarningLoggerOptions controls the behavior 26 // of a rest.WarningHandler constructed using NewKubeAPIWarningLogger(). 27 type KubeAPIWarningLoggerOptions struct { 28 // Deduplicate indicates a given warning message should only be written once. 29 // Setting this to true in a long-running process handling many warnings can 30 // result in increased memory use. 31 Deduplicate bool 32 } 33 34 // KubeAPIWarningLogger is a wrapper around 35 // a provided logr.Logger that implements the 36 // rest.WarningHandler interface. 37 type KubeAPIWarningLogger struct { 38 // logger is used to log responses with the warning header 39 logger logr.Logger 40 // opts contain options controlling warning output 41 opts KubeAPIWarningLoggerOptions 42 // writtenLock gurads written 43 writtenLock sync.Mutex 44 // used to keep track of already logged messages 45 // and help in de-duplication. 46 written map[string]struct{} 47 } 48 49 // HandleWarningHeader handles logging for responses from API server that are 50 // warnings with code being 299 and uses a logr.Logger for its logging purposes. 51 func (l *KubeAPIWarningLogger) HandleWarningHeader(code int, agent string, message string) { 52 if code != 299 || len(message) == 0 { 53 return 54 } 55 56 if l.opts.Deduplicate { 57 l.writtenLock.Lock() 58 defer l.writtenLock.Unlock() 59 60 if _, alreadyLogged := l.written[message]; alreadyLogged { 61 return 62 } 63 l.written[message] = struct{}{} 64 } 65 l.logger.Info(message) 66 } 67 68 // NewKubeAPIWarningLogger returns an implementation of rest.WarningHandler that logs warnings 69 // with code = 299 to the provided logr.Logger. 70 func NewKubeAPIWarningLogger(l logr.Logger, opts KubeAPIWarningLoggerOptions) *KubeAPIWarningLogger { 71 h := &KubeAPIWarningLogger{logger: l, opts: opts} 72 if opts.Deduplicate { 73 h.written = map[string]struct{}{} 74 } 75 return h 76 } 77