1// Copyright 2013-2020 Aerospike, Inc. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package logger 16 17import ( 18 "fmt" 19 "log" 20 "os" 21 "sync" 22) 23 24// LogPriority specifies the logging level for the client 25type LogPriority int 26 27const ( 28 DEBUG LogPriority = iota - 1 29 INFO 30 WARNING 31 ERR 32 OFF LogPriority = 999 33) 34 35type genericLogger interface { 36 Printf(format string, v ...interface{}) 37} 38 39type logger struct { 40 Logger genericLogger 41 42 level LogPriority 43 mutex sync.RWMutex 44} 45 46// Logger is the default logger instance 47var Logger = newLogger() 48 49func newLogger() *logger { 50 return &logger{ 51 Logger: log.New(os.Stdout, "", log.LstdFlags), 52 level: OFF, 53 } 54} 55 56// SetLogger sets the *log.Logger object where log messages should be sent to. 57func (lgr *logger) SetLogger(l genericLogger) { 58 lgr.mutex.Lock() 59 defer lgr.mutex.Unlock() 60 61 lgr.Logger = l 62} 63 64// SetLevel sets logging level. Default is ERR. 65func (lgr *logger) SetLevel(level LogPriority) { 66 lgr.mutex.Lock() 67 defer lgr.mutex.Unlock() 68 69 lgr.level = level 70} 71 72// Error logs a message if log level allows to do so. 73func (lgr *logger) LogAtLevel(level LogPriority, format string, v ...interface{}) { 74 switch level { 75 case DEBUG: 76 lgr.Debug(format, v...) 77 case INFO: 78 lgr.Info(format, v...) 79 case WARNING: 80 lgr.Warn(format, v...) 81 case ERR: 82 lgr.Error(format, v...) 83 } 84} 85 86// Debug logs a message if log level allows to do so. 87func (lgr *logger) Debug(format string, v ...interface{}) { 88 lgr.mutex.RLock() 89 defer lgr.mutex.RUnlock() 90 91 if lgr.level <= DEBUG { 92 if l, ok := lgr.Logger.(*log.Logger); ok { 93 l.Output(2, fmt.Sprintf(format, v...)) 94 } else { 95 lgr.Logger.Printf(format, v...) 96 } 97 } 98} 99 100// Info logs a message if log level allows to do so. 101func (lgr *logger) Info(format string, v ...interface{}) { 102 lgr.mutex.RLock() 103 defer lgr.mutex.RUnlock() 104 105 if lgr.level <= INFO { 106 if l, ok := lgr.Logger.(*log.Logger); ok { 107 l.Output(2, fmt.Sprintf(format, v...)) 108 } else { 109 lgr.Logger.Printf(format, v...) 110 } 111 } 112} 113 114// Warn logs a message if log level allows to do so. 115func (lgr *logger) Warn(format string, v ...interface{}) { 116 lgr.mutex.RLock() 117 defer lgr.mutex.RUnlock() 118 119 if lgr.level <= WARNING { 120 if l, ok := lgr.Logger.(*log.Logger); ok { 121 l.Output(2, fmt.Sprintf(format, v...)) 122 } else { 123 lgr.Logger.Printf(format, v...) 124 } 125 } 126} 127 128// Error logs a message if log level allows to do so. 129func (lgr *logger) Error(format string, v ...interface{}) { 130 lgr.mutex.RLock() 131 defer lgr.mutex.RUnlock() 132 133 if lgr.level <= ERR { 134 if l, ok := lgr.Logger.(*log.Logger); ok { 135 l.Output(2, fmt.Sprintf(format, v...)) 136 } else { 137 lgr.Logger.Printf(format, v...) 138 } 139 } 140} 141