|
@@ -23,10 +23,23 @@ import (
|
|
|
|
|
|
|
|
// Logger is the logger used by client library.
|
|
// Logger is the logger used by client library.
|
|
|
// It implements grpclog.LoggerV2 interface.
|
|
// It implements grpclog.LoggerV2 interface.
|
|
|
-type Logger grpclog.LoggerV2
|
|
|
|
|
|
|
+type Logger interface {
|
|
|
|
|
+ grpclog.LoggerV2
|
|
|
|
|
+
|
|
|
|
|
+ // Lvl returns logger if logger's verbosity level >= "lvl".
|
|
|
|
|
+ // Otherwise, logger that discards all logs.
|
|
|
|
|
+ Lvl(lvl int) Logger
|
|
|
|
|
+
|
|
|
|
|
+ // to satisfy capnslog
|
|
|
|
|
+
|
|
|
|
|
+ Print(args ...interface{})
|
|
|
|
|
+ Printf(format string, args ...interface{})
|
|
|
|
|
+ Println(args ...interface{})
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
var (
|
|
var (
|
|
|
- logger settableLogger
|
|
|
|
|
|
|
+ loggerMu sync.RWMutex
|
|
|
|
|
+ logger Logger
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
type settableLogger struct {
|
|
type settableLogger struct {
|
|
@@ -36,38 +49,35 @@ type settableLogger struct {
|
|
|
|
|
|
|
|
func init() {
|
|
func init() {
|
|
|
// disable client side logs by default
|
|
// disable client side logs by default
|
|
|
- logger.mu.Lock()
|
|
|
|
|
- logger.l = grpclog.NewLoggerV2(ioutil.Discard, ioutil.Discard, ioutil.Discard)
|
|
|
|
|
-
|
|
|
|
|
- // logger has to override the grpclog at initialization so that
|
|
|
|
|
- // any changes to the grpclog go through logger with locking
|
|
|
|
|
- // instead of through SetLogger
|
|
|
|
|
- //
|
|
|
|
|
- // now updates only happen through settableLogger.set
|
|
|
|
|
- grpclog.SetLoggerV2(&logger)
|
|
|
|
|
- logger.mu.Unlock()
|
|
|
|
|
|
|
+ logger = &settableLogger{}
|
|
|
|
|
+ SetLogger(grpclog.NewLoggerV2(ioutil.Discard, ioutil.Discard, ioutil.Discard))
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// SetLogger sets client-side Logger. By default, logs are disabled.
|
|
|
|
|
-func SetLogger(l Logger) {
|
|
|
|
|
- logger.set(l)
|
|
|
|
|
|
|
+// SetLogger sets client-side Logger.
|
|
|
|
|
+func SetLogger(l grpclog.LoggerV2) {
|
|
|
|
|
+ loggerMu.Lock()
|
|
|
|
|
+ logger = NewLogger(l)
|
|
|
|
|
+ // override grpclog so that any changes happen with locking
|
|
|
|
|
+ grpclog.SetLoggerV2(logger)
|
|
|
|
|
+ loggerMu.Unlock()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// GetLogger returns the current logger.
|
|
// GetLogger returns the current logger.
|
|
|
func GetLogger() Logger {
|
|
func GetLogger() Logger {
|
|
|
- return logger.get()
|
|
|
|
|
|
|
+ loggerMu.RLock()
|
|
|
|
|
+ l := logger
|
|
|
|
|
+ loggerMu.RUnlock()
|
|
|
|
|
+ return l
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func (s *settableLogger) set(l Logger) {
|
|
|
|
|
- s.mu.Lock()
|
|
|
|
|
- logger.l = l
|
|
|
|
|
- grpclog.SetLoggerV2(&logger)
|
|
|
|
|
- s.mu.Unlock()
|
|
|
|
|
|
|
+// NewLogger returns a new Logger with grpclog.LoggerV2.
|
|
|
|
|
+func NewLogger(gl grpclog.LoggerV2) Logger {
|
|
|
|
|
+ return &settableLogger{l: gl}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func (s *settableLogger) get() Logger {
|
|
|
|
|
|
|
+func (s *settableLogger) get() grpclog.LoggerV2 {
|
|
|
s.mu.RLock()
|
|
s.mu.RLock()
|
|
|
- l := logger.l
|
|
|
|
|
|
|
+ l := s.l
|
|
|
s.mu.RUnlock()
|
|
s.mu.RUnlock()
|
|
|
return l
|
|
return l
|
|
|
}
|
|
}
|
|
@@ -94,3 +104,32 @@ func (s *settableLogger) Print(args ...interface{}) { s.get().In
|
|
|
func (s *settableLogger) Printf(format string, args ...interface{}) { s.get().Infof(format, args...) }
|
|
func (s *settableLogger) Printf(format string, args ...interface{}) { s.get().Infof(format, args...) }
|
|
|
func (s *settableLogger) Println(args ...interface{}) { s.get().Infoln(args...) }
|
|
func (s *settableLogger) Println(args ...interface{}) { s.get().Infoln(args...) }
|
|
|
func (s *settableLogger) V(l int) bool { return s.get().V(l) }
|
|
func (s *settableLogger) V(l int) bool { return s.get().V(l) }
|
|
|
|
|
+func (s *settableLogger) Lvl(lvl int) Logger {
|
|
|
|
|
+ s.mu.RLock()
|
|
|
|
|
+ l := s.l
|
|
|
|
|
+ s.mu.RUnlock()
|
|
|
|
|
+ if l.V(lvl) {
|
|
|
|
|
+ return s
|
|
|
|
|
+ }
|
|
|
|
|
+ return &noLogger{}
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+type noLogger struct{}
|
|
|
|
|
+
|
|
|
|
|
+func (*noLogger) Info(args ...interface{}) {}
|
|
|
|
|
+func (*noLogger) Infof(format string, args ...interface{}) {}
|
|
|
|
|
+func (*noLogger) Infoln(args ...interface{}) {}
|
|
|
|
|
+func (*noLogger) Warning(args ...interface{}) {}
|
|
|
|
|
+func (*noLogger) Warningf(format string, args ...interface{}) {}
|
|
|
|
|
+func (*noLogger) Warningln(args ...interface{}) {}
|
|
|
|
|
+func (*noLogger) Error(args ...interface{}) {}
|
|
|
|
|
+func (*noLogger) Errorf(format string, args ...interface{}) {}
|
|
|
|
|
+func (*noLogger) Errorln(args ...interface{}) {}
|
|
|
|
|
+func (*noLogger) Fatal(args ...interface{}) {}
|
|
|
|
|
+func (*noLogger) Fatalf(format string, args ...interface{}) {}
|
|
|
|
|
+func (*noLogger) Fatalln(args ...interface{}) {}
|
|
|
|
|
+func (*noLogger) Print(args ...interface{}) {}
|
|
|
|
|
+func (*noLogger) Printf(format string, args ...interface{}) {}
|
|
|
|
|
+func (*noLogger) Println(args ...interface{}) {}
|
|
|
|
|
+func (*noLogger) V(l int) bool { return false }
|
|
|
|
|
+func (ng *noLogger) Lvl(lvl int) Logger { return ng }
|