mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
commit
3903385d1b
1
.words
1
.words
@ -10,6 +10,7 @@ RPC
|
|||||||
RPCs
|
RPCs
|
||||||
TODO
|
TODO
|
||||||
WithRequireLeader
|
WithRequireLeader
|
||||||
|
args
|
||||||
backoff
|
backoff
|
||||||
blackhole
|
blackhole
|
||||||
blackholed
|
blackholed
|
||||||
|
@ -166,7 +166,7 @@ func (c *Client) autoSync() {
|
|||||||
err := c.Sync(ctx)
|
err := c.Sync(ctx)
|
||||||
cancel()
|
cancel()
|
||||||
if err != nil && err != c.ctx.Err() {
|
if err != nil && err != c.ctx.Err() {
|
||||||
logger.Println("Auto sync endpoints failed:", err)
|
lg.Lvl(4).Infof("Auto sync endpoints failed: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,26 +158,26 @@ func (b *healthBalancer) pinned() string {
|
|||||||
|
|
||||||
func (b *healthBalancer) hostPortError(hostPort string, err error) {
|
func (b *healthBalancer) hostPortError(hostPort string, err error) {
|
||||||
if b.endpoint(hostPort) == "" {
|
if b.endpoint(hostPort) == "" {
|
||||||
logger.Lvl(4).Infof("clientv3/balancer: %q is stale (skip marking as unhealthy on %q)", hostPort, err.Error())
|
lg.Lvl(4).Infof("clientv3/balancer: %q is stale (skip marking as unhealthy on %q)", hostPort, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
b.unhealthyMu.Lock()
|
b.unhealthyMu.Lock()
|
||||||
b.unhealthyHostPorts[hostPort] = time.Now()
|
b.unhealthyHostPorts[hostPort] = time.Now()
|
||||||
b.unhealthyMu.Unlock()
|
b.unhealthyMu.Unlock()
|
||||||
logger.Lvl(4).Infof("clientv3/balancer: %q is marked unhealthy (%q)", hostPort, err.Error())
|
lg.Lvl(4).Infof("clientv3/balancer: %q is marked unhealthy (%q)", hostPort, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *healthBalancer) removeUnhealthy(hostPort, msg string) {
|
func (b *healthBalancer) removeUnhealthy(hostPort, msg string) {
|
||||||
if b.endpoint(hostPort) == "" {
|
if b.endpoint(hostPort) == "" {
|
||||||
logger.Lvl(4).Infof("clientv3/balancer: %q was not in unhealthy (%q)", hostPort, msg)
|
lg.Lvl(4).Infof("clientv3/balancer: %q was not in unhealthy (%q)", hostPort, msg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
b.unhealthyMu.Lock()
|
b.unhealthyMu.Lock()
|
||||||
delete(b.unhealthyHostPorts, hostPort)
|
delete(b.unhealthyHostPorts, hostPort)
|
||||||
b.unhealthyMu.Unlock()
|
b.unhealthyMu.Unlock()
|
||||||
logger.Lvl(4).Infof("clientv3/balancer: %q is removed from unhealthy (%q)", hostPort, msg)
|
lg.Lvl(4).Infof("clientv3/balancer: %q is removed from unhealthy (%q)", hostPort, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *healthBalancer) countUnhealthy() (count int) {
|
func (b *healthBalancer) countUnhealthy() (count int) {
|
||||||
@ -199,7 +199,7 @@ func (b *healthBalancer) cleanupUnhealthy() {
|
|||||||
for k, v := range b.unhealthyHostPorts {
|
for k, v := range b.unhealthyHostPorts {
|
||||||
if time.Since(v) > b.healthCheckTimeout {
|
if time.Since(v) > b.healthCheckTimeout {
|
||||||
delete(b.unhealthyHostPorts, k)
|
delete(b.unhealthyHostPorts, k)
|
||||||
logger.Lvl(4).Infof("clientv3/balancer: removed %q from unhealthy after %v", k, b.healthCheckTimeout)
|
lg.Lvl(4).Infof("clientv3/balancer: removed %q from unhealthy after %v", k, b.healthCheckTimeout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b.unhealthyMu.Unlock()
|
b.unhealthyMu.Unlock()
|
||||||
@ -402,7 +402,7 @@ func (b *healthBalancer) Up(addr grpc.Address) func(error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if b.pinAddr != "" {
|
if b.pinAddr != "" {
|
||||||
logger.Lvl(4).Infof("clientv3/balancer: %q is up but not pinned (already pinned %q)", addr.Addr, b.pinAddr)
|
lg.Lvl(4).Infof("clientv3/balancer: %q is up but not pinned (already pinned %q)", addr.Addr, b.pinAddr)
|
||||||
return func(err error) {}
|
return func(err error) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -410,7 +410,7 @@ func (b *healthBalancer) Up(addr grpc.Address) func(error) {
|
|||||||
close(b.upc)
|
close(b.upc)
|
||||||
b.downc = make(chan struct{})
|
b.downc = make(chan struct{})
|
||||||
b.pinAddr = addr.Addr
|
b.pinAddr = addr.Addr
|
||||||
logger.Lvl(4).Infof("clientv3/balancer: pin %q", addr.Addr)
|
lg.Lvl(4).Infof("clientv3/balancer: pin %q", addr.Addr)
|
||||||
|
|
||||||
// notify client that a connection is up
|
// notify client that a connection is up
|
||||||
b.readyOnce.Do(func() { close(b.readyc) })
|
b.readyOnce.Do(func() { close(b.readyc) })
|
||||||
@ -427,7 +427,7 @@ func (b *healthBalancer) Up(addr grpc.Address) func(error) {
|
|||||||
close(b.downc)
|
close(b.downc)
|
||||||
b.pinAddr = ""
|
b.pinAddr = ""
|
||||||
b.mu.Unlock()
|
b.mu.Unlock()
|
||||||
logger.Lvl(4).Infof("clientv3/balancer: unpin %q (%q)", addr.Addr, err.Error())
|
lg.Lvl(4).Infof("clientv3/balancer: unpin %q (%q)", addr.Addr, err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,7 +454,7 @@ func (b *healthBalancer) mayPin(addr grpc.Address) bool {
|
|||||||
// 3. grpc-healthcheck still SERVING, thus retry to pin
|
// 3. grpc-healthcheck still SERVING, thus retry to pin
|
||||||
// instead, return before grpc-healthcheck if failed within healthcheck timeout
|
// instead, return before grpc-healthcheck if failed within healthcheck timeout
|
||||||
if elapsed := time.Since(failedTime); elapsed < b.healthCheckTimeout {
|
if elapsed := time.Since(failedTime); elapsed < b.healthCheckTimeout {
|
||||||
logger.Lvl(4).Infof("clientv3/balancer: %q is up but not pinned (failed %v ago, require minimum %v after failure)", addr.Addr, elapsed, b.healthCheckTimeout)
|
lg.Lvl(4).Infof("clientv3/balancer: %q is up but not pinned (failed %v ago, require minimum %v after failure)", addr.Addr, elapsed, b.healthCheckTimeout)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,28 +18,14 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/coreos/etcd/pkg/logger"
|
||||||
|
|
||||||
"google.golang.org/grpc/grpclog"
|
"google.golang.org/grpc/grpclog"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Logger is the logger used by client library.
|
|
||||||
// It implements grpclog.LoggerV2 interface.
|
|
||||||
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 (
|
||||||
loggerMu sync.RWMutex
|
lgMu sync.RWMutex
|
||||||
logger Logger
|
lg logger.Logger
|
||||||
)
|
)
|
||||||
|
|
||||||
type settableLogger struct {
|
type settableLogger struct {
|
||||||
@ -49,29 +35,29 @@ type settableLogger struct {
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// disable client side logs by default
|
// disable client side logs by default
|
||||||
logger = &settableLogger{}
|
lg = &settableLogger{}
|
||||||
SetLogger(grpclog.NewLoggerV2(ioutil.Discard, ioutil.Discard, ioutil.Discard))
|
SetLogger(grpclog.NewLoggerV2(ioutil.Discard, ioutil.Discard, ioutil.Discard))
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetLogger sets client-side Logger.
|
// SetLogger sets client-side Logger.
|
||||||
func SetLogger(l grpclog.LoggerV2) {
|
func SetLogger(l grpclog.LoggerV2) {
|
||||||
loggerMu.Lock()
|
lgMu.Lock()
|
||||||
logger = NewLogger(l)
|
lg = logger.New(l)
|
||||||
// override grpclog so that any changes happen with locking
|
// override grpclog so that any changes happen with locking
|
||||||
grpclog.SetLoggerV2(logger)
|
grpclog.SetLoggerV2(lg)
|
||||||
loggerMu.Unlock()
|
lgMu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLogger returns the current logger.
|
// GetLogger returns the current logger.Logger.
|
||||||
func GetLogger() Logger {
|
func GetLogger() logger.Logger {
|
||||||
loggerMu.RLock()
|
lgMu.RLock()
|
||||||
l := logger
|
l := lg
|
||||||
loggerMu.RUnlock()
|
lgMu.RUnlock()
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLogger returns a new Logger with grpclog.LoggerV2.
|
// NewLogger returns a new Logger with logger.Logger.
|
||||||
func NewLogger(gl grpclog.LoggerV2) Logger {
|
func NewLogger(gl grpclog.LoggerV2) logger.Logger {
|
||||||
return &settableLogger{l: gl}
|
return &settableLogger{l: gl}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,32 +90,12 @@ 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 {
|
func (s *settableLogger) Lvl(lvl int) grpclog.LoggerV2 {
|
||||||
s.mu.RLock()
|
s.mu.RLock()
|
||||||
l := s.l
|
l := s.l
|
||||||
s.mu.RUnlock()
|
s.mu.RUnlock()
|
||||||
if l.V(lvl) {
|
if l.V(lvl) {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
return &noLogger{}
|
return logger.NewDiscardLogger()
|
||||||
}
|
}
|
||||||
|
|
||||||
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 }
|
|
||||||
|
@ -96,13 +96,13 @@ func (c *Client) newRetryWrapper() retryRPCFunc {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
logger.Lvl(4).Infof("clientv3/retry: error %q on pinned endpoint %q", err.Error(), pinned)
|
lg.Lvl(4).Infof("clientv3/retry: error %q on pinned endpoint %q", err.Error(), pinned)
|
||||||
|
|
||||||
if s, ok := status.FromError(err); ok && (s.Code() == codes.Unavailable || s.Code() == codes.DeadlineExceeded || s.Code() == codes.Internal) {
|
if s, ok := status.FromError(err); ok && (s.Code() == codes.Unavailable || s.Code() == codes.DeadlineExceeded || s.Code() == codes.Internal) {
|
||||||
// mark this before endpoint switch is triggered
|
// mark this before endpoint switch is triggered
|
||||||
c.balancer.hostPortError(pinned, err)
|
c.balancer.hostPortError(pinned, err)
|
||||||
c.balancer.next()
|
c.balancer.next()
|
||||||
logger.Lvl(4).Infof("clientv3/retry: switching from %q due to error %q", pinned, err.Error())
|
lg.Lvl(4).Infof("clientv3/retry: switching from %q due to error %q", pinned, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
if isStop(err) {
|
if isStop(err) {
|
||||||
@ -120,12 +120,12 @@ func (c *Client) newAuthRetryWrapper(retryf retryRPCFunc) retryRPCFunc {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
logger.Lvl(4).Infof("clientv3/auth-retry: error %q on pinned endpoint %q", err.Error(), pinned)
|
lg.Lvl(4).Infof("clientv3/auth-retry: error %q on pinned endpoint %q", err.Error(), pinned)
|
||||||
// always stop retry on etcd errors other than invalid auth token
|
// always stop retry on etcd errors other than invalid auth token
|
||||||
if rpctypes.Error(err) == rpctypes.ErrInvalidAuthToken {
|
if rpctypes.Error(err) == rpctypes.ErrInvalidAuthToken {
|
||||||
gterr := c.getToken(rpcCtx)
|
gterr := c.getToken(rpcCtx)
|
||||||
if gterr != nil {
|
if gterr != nil {
|
||||||
logger.Lvl(4).Infof("clientv3/auth-retry: cannot retry due to error %q(%q) on pinned endpoint %q", err.Error(), gterr.Error(), pinned)
|
lg.Lvl(4).Infof("clientv3/auth-retry: cannot retry due to error %q(%q) on pinned endpoint %q", err.Error(), gterr.Error(), pinned)
|
||||||
return err // return the original error for simplicity
|
return err // return the original error for simplicity
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
|
@ -24,7 +24,6 @@ import (
|
|||||||
"github.com/coreos/etcd/pkg/types"
|
"github.com/coreos/etcd/pkg/types"
|
||||||
"github.com/coreos/etcd/snapshot"
|
"github.com/coreos/etcd/snapshot"
|
||||||
|
|
||||||
"github.com/coreos/pkg/capnslog"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -103,7 +102,7 @@ func snapshotSaveCommandFunc(cmd *cobra.Command, args []string) {
|
|||||||
ExitWithError(ExitError, err)
|
ExitWithError(ExitError, err)
|
||||||
}
|
}
|
||||||
if debug {
|
if debug {
|
||||||
lg = logger.NewPackageLogger(capnslog.NewPackageLogger("github.com/coreos/etcd", "snapshot"))
|
lg = logger.NewPackageLogger("github.com/coreos/etcd", "snapshot")
|
||||||
}
|
}
|
||||||
sp := snapshot.NewV3(mustClientFromCmd(cmd), lg)
|
sp := snapshot.NewV3(mustClientFromCmd(cmd), lg)
|
||||||
|
|
||||||
@ -127,7 +126,7 @@ func snapshotStatusCommandFunc(cmd *cobra.Command, args []string) {
|
|||||||
ExitWithError(ExitError, err)
|
ExitWithError(ExitError, err)
|
||||||
}
|
}
|
||||||
if debug {
|
if debug {
|
||||||
lg = logger.NewPackageLogger(capnslog.NewPackageLogger("github.com/coreos/etcd", "snapshot"))
|
lg = logger.NewPackageLogger("github.com/coreos/etcd", "snapshot")
|
||||||
}
|
}
|
||||||
sp := snapshot.NewV3(nil, lg)
|
sp := snapshot.NewV3(nil, lg)
|
||||||
|
|
||||||
@ -165,7 +164,7 @@ func snapshotRestoreCommandFunc(cmd *cobra.Command, args []string) {
|
|||||||
ExitWithError(ExitError, err)
|
ExitWithError(ExitError, err)
|
||||||
}
|
}
|
||||||
if debug {
|
if debug {
|
||||||
lg = logger.NewPackageLogger(capnslog.NewPackageLogger("github.com/coreos/etcd", "snapshot"))
|
lg = logger.NewPackageLogger("github.com/coreos/etcd", "snapshot")
|
||||||
}
|
}
|
||||||
sp := snapshot.NewV3(nil, lg)
|
sp := snapshot.NewV3(nil, lg)
|
||||||
|
|
||||||
|
@ -14,9 +14,13 @@
|
|||||||
|
|
||||||
package logger
|
package logger
|
||||||
|
|
||||||
import "log"
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
// assert that Logger satisfies grpclog.LoggerV2
|
"google.golang.org/grpc/grpclog"
|
||||||
|
)
|
||||||
|
|
||||||
|
// assert that "discardLogger" satisfy "Logger" interface
|
||||||
var _ Logger = &discardLogger{}
|
var _ Logger = &discardLogger{}
|
||||||
|
|
||||||
// NewDiscardLogger returns a new Logger that discards everything except "fatal".
|
// NewDiscardLogger returns a new Logger that discards everything except "fatal".
|
||||||
@ -39,3 +43,4 @@ func (l *discardLogger) Fatalf(format string, args ...interface{}) { log.Fatal
|
|||||||
func (l *discardLogger) V(lvl int) bool {
|
func (l *discardLogger) V(lvl int) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
func (l *discardLogger) Lvl(lvl int) grpclog.LoggerV2 { return l }
|
||||||
|
@ -17,6 +17,47 @@ package logger
|
|||||||
import "google.golang.org/grpc/grpclog"
|
import "google.golang.org/grpc/grpclog"
|
||||||
|
|
||||||
// Logger defines logging interface.
|
// Logger defines logging interface.
|
||||||
// TODO: add "Lvl(lvl int)" for clientv3 loggers.
|
type Logger interface {
|
||||||
// TODO: make this settable with "Set" method.
|
grpclog.LoggerV2
|
||||||
type Logger grpclog.LoggerV2
|
|
||||||
|
// Lvl returns logger if logger's verbosity level >= "lvl".
|
||||||
|
// Otherwise, logger that discards everything.
|
||||||
|
Lvl(lvl int) grpclog.LoggerV2
|
||||||
|
}
|
||||||
|
|
||||||
|
// assert that "defaultLogger" satisfy "Logger" interface
|
||||||
|
var _ Logger = &defaultLogger{}
|
||||||
|
|
||||||
|
// New wraps "grpclog.LoggerV2" that implements "Logger" interface.
|
||||||
|
//
|
||||||
|
// For example:
|
||||||
|
//
|
||||||
|
// var defaultLogger Logger
|
||||||
|
// g := grpclog.NewLoggerV2WithVerbosity(os.Stderr, os.Stderr, os.Stderr, 4)
|
||||||
|
// defaultLogger = New(g)
|
||||||
|
//
|
||||||
|
func New(g grpclog.LoggerV2) Logger { return &defaultLogger{g: g} }
|
||||||
|
|
||||||
|
type defaultLogger struct {
|
||||||
|
g grpclog.LoggerV2
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *defaultLogger) Info(args ...interface{}) { l.g.Info(args...) }
|
||||||
|
func (l *defaultLogger) Infoln(args ...interface{}) { l.g.Info(args...) }
|
||||||
|
func (l *defaultLogger) Infof(format string, args ...interface{}) { l.g.Infof(format, args...) }
|
||||||
|
func (l *defaultLogger) Warning(args ...interface{}) { l.g.Warning(args...) }
|
||||||
|
func (l *defaultLogger) Warningln(args ...interface{}) { l.g.Warning(args...) }
|
||||||
|
func (l *defaultLogger) Warningf(format string, args ...interface{}) { l.g.Warningf(format, args...) }
|
||||||
|
func (l *defaultLogger) Error(args ...interface{}) { l.g.Error(args...) }
|
||||||
|
func (l *defaultLogger) Errorln(args ...interface{}) { l.g.Error(args...) }
|
||||||
|
func (l *defaultLogger) Errorf(format string, args ...interface{}) { l.g.Errorf(format, args...) }
|
||||||
|
func (l *defaultLogger) Fatal(args ...interface{}) { l.g.Fatal(args...) }
|
||||||
|
func (l *defaultLogger) Fatalln(args ...interface{}) { l.g.Fatal(args...) }
|
||||||
|
func (l *defaultLogger) Fatalf(format string, args ...interface{}) { l.g.Fatalf(format, args...) }
|
||||||
|
func (l *defaultLogger) V(lvl int) bool { return l.g.V(lvl) }
|
||||||
|
func (l *defaultLogger) Lvl(lvl int) grpclog.LoggerV2 {
|
||||||
|
if l.g.V(lvl) {
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
return &discardLogger{}
|
||||||
|
}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package clientv3
|
package logger_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@ -20,13 +20,15 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/coreos/etcd/pkg/logger"
|
||||||
|
|
||||||
"google.golang.org/grpc/grpclog"
|
"google.golang.org/grpc/grpclog"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLogger(t *testing.T) {
|
func TestLogger(t *testing.T) {
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
|
|
||||||
l := NewLogger(grpclog.NewLoggerV2WithVerbosity(buf, buf, buf, 10))
|
l := logger.New(grpclog.NewLoggerV2WithVerbosity(buf, buf, buf, 10))
|
||||||
l.Infof("hello world!")
|
l.Infof("hello world!")
|
||||||
if !strings.Contains(buf.String(), "hello world!") {
|
if !strings.Contains(buf.String(), "hello world!") {
|
||||||
t.Fatalf("expected 'hello world!', got %q", buf.String())
|
t.Fatalf("expected 'hello world!', got %q", buf.String())
|
||||||
@ -43,7 +45,7 @@ func TestLogger(t *testing.T) {
|
|||||||
}
|
}
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
|
|
||||||
l = NewLogger(grpclog.NewLoggerV2(ioutil.Discard, ioutil.Discard, ioutil.Discard))
|
l = logger.New(grpclog.NewLoggerV2(ioutil.Discard, ioutil.Discard, ioutil.Discard))
|
||||||
l.Infof("ignore this")
|
l.Infof("ignore this")
|
||||||
if len(buf.Bytes()) > 0 {
|
if len(buf.Bytes()) > 0 {
|
||||||
t.Fatalf("unexpected logs %q", buf.String())
|
t.Fatalf("unexpected logs %q", buf.String())
|
@ -14,9 +14,12 @@
|
|||||||
|
|
||||||
package logger
|
package logger
|
||||||
|
|
||||||
import "github.com/coreos/pkg/capnslog"
|
import (
|
||||||
|
"github.com/coreos/pkg/capnslog"
|
||||||
|
"google.golang.org/grpc/grpclog"
|
||||||
|
)
|
||||||
|
|
||||||
// assert that Logger satisfies grpclog.LoggerV2
|
// assert that "packageLogger" satisfy "Logger" interface
|
||||||
var _ Logger = &packageLogger{}
|
var _ Logger = &packageLogger{}
|
||||||
|
|
||||||
// NewPackageLogger wraps "*capnslog.PackageLogger" that implements "Logger" interface.
|
// NewPackageLogger wraps "*capnslog.PackageLogger" that implements "Logger" interface.
|
||||||
@ -24,10 +27,11 @@ var _ Logger = &packageLogger{}
|
|||||||
// For example:
|
// For example:
|
||||||
//
|
//
|
||||||
// var defaultLogger Logger
|
// var defaultLogger Logger
|
||||||
// plog := capnslog.NewPackageLogger("github.com/coreos/etcd", "snapshot")
|
// defaultLogger = NewPackageLogger("github.com/coreos/etcd", "snapshot")
|
||||||
// defaultLogger = NewPackageLogger(plog)
|
|
||||||
//
|
//
|
||||||
func NewPackageLogger(p *capnslog.PackageLogger) Logger { return &packageLogger{p: p} }
|
func NewPackageLogger(repo, pkg string) Logger {
|
||||||
|
return &packageLogger{p: capnslog.NewPackageLogger(repo, pkg)}
|
||||||
|
}
|
||||||
|
|
||||||
type packageLogger struct {
|
type packageLogger struct {
|
||||||
p *capnslog.PackageLogger
|
p *capnslog.PackageLogger
|
||||||
@ -48,3 +52,9 @@ func (l *packageLogger) Fatalf(format string, args ...interface{}) { l.p.Fatal
|
|||||||
func (l *packageLogger) V(lvl int) bool {
|
func (l *packageLogger) V(lvl int) bool {
|
||||||
return l.p.LevelAt(capnslog.LogLevel(lvl))
|
return l.p.LevelAt(capnslog.LogLevel(lvl))
|
||||||
}
|
}
|
||||||
|
func (l *packageLogger) Lvl(lvl int) grpclog.LoggerV2 {
|
||||||
|
if l.p.LevelAt(capnslog.LogLevel(lvl)) {
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
return &discardLogger{}
|
||||||
|
}
|
||||||
|
59
pkg/logger/package_logger_test.go
Normal file
59
pkg/logger/package_logger_test.go
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// Copyright 2017 The etcd Authors
|
||||||
|
//
|
||||||
|
// 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_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/coreos/pkg/capnslog"
|
||||||
|
|
||||||
|
"github.com/coreos/etcd/pkg/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPackageLogger(t *testing.T) {
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
capnslog.SetFormatter(capnslog.NewDefaultFormatter(buf))
|
||||||
|
|
||||||
|
l := logger.NewPackageLogger("github.com/coreos/etcd", "logger")
|
||||||
|
|
||||||
|
r := capnslog.MustRepoLogger("github.com/coreos/etcd")
|
||||||
|
r.SetLogLevel(map[string]capnslog.LogLevel{"logger": capnslog.INFO})
|
||||||
|
|
||||||
|
l.Infof("hello world!")
|
||||||
|
if !strings.Contains(buf.String(), "hello world!") {
|
||||||
|
t.Fatalf("expected 'hello world!', got %q", buf.String())
|
||||||
|
}
|
||||||
|
buf.Reset()
|
||||||
|
|
||||||
|
// capnslog.INFO is 3
|
||||||
|
l.Lvl(2).Infof("Level 2")
|
||||||
|
l.Lvl(5).Infof("Level 5")
|
||||||
|
if !strings.Contains(buf.String(), "Level 2") {
|
||||||
|
t.Fatalf("expected 'Level 2', got %q", buf.String())
|
||||||
|
}
|
||||||
|
if strings.Contains(buf.String(), "Level 5") {
|
||||||
|
t.Fatalf("unexpected 'Level 5', got %q", buf.String())
|
||||||
|
}
|
||||||
|
buf.Reset()
|
||||||
|
|
||||||
|
capnslog.SetFormatter(capnslog.NewDefaultFormatter(ioutil.Discard))
|
||||||
|
l.Infof("ignore this")
|
||||||
|
if len(buf.Bytes()) > 0 {
|
||||||
|
t.Fatalf("unexpected logs %q", buf.String())
|
||||||
|
}
|
||||||
|
}
|
@ -29,8 +29,6 @@ import (
|
|||||||
"github.com/coreos/etcd/pkg/logger"
|
"github.com/coreos/etcd/pkg/logger"
|
||||||
"github.com/coreos/etcd/pkg/testutil"
|
"github.com/coreos/etcd/pkg/testutil"
|
||||||
"github.com/coreos/etcd/pkg/types"
|
"github.com/coreos/etcd/pkg/types"
|
||||||
|
|
||||||
"github.com/coreos/pkg/capnslog"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestSnapshotV3RestoreSingle tests single node cluster restoring
|
// TestSnapshotV3RestoreSingle tests single node cluster restoring
|
||||||
@ -53,7 +51,7 @@ func TestSnapshotV3RestoreSingle(t *testing.T) {
|
|||||||
cfg.InitialCluster = fmt.Sprintf("%s=%s", cfg.Name, pURLs[0].String())
|
cfg.InitialCluster = fmt.Sprintf("%s=%s", cfg.Name, pURLs[0].String())
|
||||||
cfg.Dir = filepath.Join(os.TempDir(), fmt.Sprint(time.Now().Nanosecond()))
|
cfg.Dir = filepath.Join(os.TempDir(), fmt.Sprint(time.Now().Nanosecond()))
|
||||||
|
|
||||||
sp := NewV3(nil, logger.NewPackageLogger(capnslog.NewPackageLogger("github.com/coreos/etcd", "snapshot")))
|
sp := NewV3(nil, logger.NewPackageLogger("github.com/coreos/etcd", "snapshot"))
|
||||||
|
|
||||||
err := sp.Restore(dbPath, RestoreConfig{})
|
err := sp.Restore(dbPath, RestoreConfig{})
|
||||||
if err.Error() != `couldn't find local name "" in the initial cluster configuration` {
|
if err.Error() != `couldn't find local name "" in the initial cluster configuration` {
|
||||||
@ -190,7 +188,7 @@ func createSnapshotFile(t *testing.T, kvs []kv) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sp := NewV3(cli, logger.NewPackageLogger(capnslog.NewPackageLogger("github.com/coreos/etcd", "snapshot")))
|
sp := NewV3(cli, logger.NewPackageLogger("github.com/coreos/etcd", "snapshot"))
|
||||||
dpPath := filepath.Join(os.TempDir(), fmt.Sprintf("snapshot%d.db", time.Now().Nanosecond()))
|
dpPath := filepath.Join(os.TempDir(), fmt.Sprintf("snapshot%d.db", time.Now().Nanosecond()))
|
||||||
if err = sp.Save(context.Background(), dpPath); err != nil {
|
if err = sp.Save(context.Background(), dpPath); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -231,7 +229,7 @@ func restoreCluster(t *testing.T, clusterN int, dbPath string) (
|
|||||||
cfg.InitialCluster = ics
|
cfg.InitialCluster = ics
|
||||||
cfg.Dir = filepath.Join(os.TempDir(), fmt.Sprint(time.Now().Nanosecond()+i))
|
cfg.Dir = filepath.Join(os.TempDir(), fmt.Sprint(time.Now().Nanosecond()+i))
|
||||||
|
|
||||||
sp := NewV3(nil, logger.NewPackageLogger(capnslog.NewPackageLogger("github.com/coreos/etcd", "snapshot")))
|
sp := NewV3(nil, logger.NewPackageLogger("github.com/coreos/etcd", "snapshot"))
|
||||||
if err := sp.Restore(dbPath, RestoreConfig{
|
if err := sp.Restore(dbPath, RestoreConfig{
|
||||||
Name: cfg.Name,
|
Name: cfg.Name,
|
||||||
OutputDataDir: cfg.Dir,
|
OutputDataDir: cfg.Dir,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user