1// Copyright 2015 The etcd Authors 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 raft 16 17import ( 18 "fmt" 19 "io/ioutil" 20 "log" 21 "os" 22 "sync" 23) 24 25type Logger interface { 26 Debug(v ...interface{}) 27 Debugf(format string, v ...interface{}) 28 29 Error(v ...interface{}) 30 Errorf(format string, v ...interface{}) 31 32 Info(v ...interface{}) 33 Infof(format string, v ...interface{}) 34 35 Warning(v ...interface{}) 36 Warningf(format string, v ...interface{}) 37 38 Fatal(v ...interface{}) 39 Fatalf(format string, v ...interface{}) 40 41 Panic(v ...interface{}) 42 Panicf(format string, v ...interface{}) 43} 44 45func SetLogger(l Logger) { 46 raftLoggerMu.Lock() 47 raftLogger = l 48 raftLoggerMu.Unlock() 49} 50 51var ( 52 defaultLogger = &DefaultLogger{Logger: log.New(os.Stderr, "raft", log.LstdFlags)} 53 discardLogger = &DefaultLogger{Logger: log.New(ioutil.Discard, "", 0)} 54 raftLoggerMu sync.Mutex 55 raftLogger = Logger(defaultLogger) 56) 57 58const ( 59 calldepth = 2 60) 61 62// DefaultLogger is a default implementation of the Logger interface. 63type DefaultLogger struct { 64 *log.Logger 65 debug bool 66} 67 68func (l *DefaultLogger) EnableTimestamps() { 69 l.SetFlags(l.Flags() | log.Ldate | log.Ltime) 70} 71 72func (l *DefaultLogger) EnableDebug() { 73 l.debug = true 74} 75 76func (l *DefaultLogger) Debug(v ...interface{}) { 77 if l.debug { 78 l.Output(calldepth, header("DEBUG", fmt.Sprint(v...))) 79 } 80} 81 82func (l *DefaultLogger) Debugf(format string, v ...interface{}) { 83 if l.debug { 84 l.Output(calldepth, header("DEBUG", fmt.Sprintf(format, v...))) 85 } 86} 87 88func (l *DefaultLogger) Info(v ...interface{}) { 89 l.Output(calldepth, header("INFO", fmt.Sprint(v...))) 90} 91 92func (l *DefaultLogger) Infof(format string, v ...interface{}) { 93 l.Output(calldepth, header("INFO", fmt.Sprintf(format, v...))) 94} 95 96func (l *DefaultLogger) Error(v ...interface{}) { 97 l.Output(calldepth, header("ERROR", fmt.Sprint(v...))) 98} 99 100func (l *DefaultLogger) Errorf(format string, v ...interface{}) { 101 l.Output(calldepth, header("ERROR", fmt.Sprintf(format, v...))) 102} 103 104func (l *DefaultLogger) Warning(v ...interface{}) { 105 l.Output(calldepth, header("WARN", fmt.Sprint(v...))) 106} 107 108func (l *DefaultLogger) Warningf(format string, v ...interface{}) { 109 l.Output(calldepth, header("WARN", fmt.Sprintf(format, v...))) 110} 111 112func (l *DefaultLogger) Fatal(v ...interface{}) { 113 l.Output(calldepth, header("FATAL", fmt.Sprint(v...))) 114 os.Exit(1) 115} 116 117func (l *DefaultLogger) Fatalf(format string, v ...interface{}) { 118 l.Output(calldepth, header("FATAL", fmt.Sprintf(format, v...))) 119 os.Exit(1) 120} 121 122func (l *DefaultLogger) Panic(v ...interface{}) { 123 l.Logger.Panic(v...) 124} 125 126func (l *DefaultLogger) Panicf(format string, v ...interface{}) { 127 l.Logger.Panicf(format, v...) 128} 129 130func header(lvl, msg string) string { 131 return fmt.Sprintf("%s: %s", lvl, msg) 132} 133