diff --git a/CHANGELOG.md b/CHANGELOG.md index 31e7326..2432b76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,13 @@ ## Unreleased +BUG FIXES: + +* AddInstance bugfix: pass r.cfg.PoolOpts to new instance + FEATURES: * Support StdoutLoggerf that allows control log level (resolve issue #84) +* Implement go-tarantool Logger interface to use the same logger as router uses (resolve issue #79) ## v1.0.1 diff --git a/logger.go b/logger.go new file mode 100644 index 0000000..087b2c6 --- /dev/null +++ b/logger.go @@ -0,0 +1,59 @@ +package vshard_router + +import ( + "context" + + "github.com/tarantool/go-tarantool/v2" +) + +// go-tarantool writes logs by default to stderr. Stderr might be not available, or user might use syslog or logging into file. +// So we should implement logging interface and redirect go-tarantool logs to the user's logger. +type tarantoolOptsLogger struct { + loggerf LogfProvider + ctx context.Context +} + +// Does almost the same thing as defaultLogger in go-tarantool, but uses user provided logger instead of stdout logger. +// https://github.com/tarantool/go-tarantool/blob/592db69eed8649b82ce432b930c27daeee98c52f/connection.go#L90 +func (l tarantoolOptsLogger) Report(event tarantool.ConnLogKind, conn *tarantool.Connection, v ...interface{}) { + switch event { + case tarantool.LogReconnectFailed: + reconnects, ok1 := v[0].(uint) + err, ok2 := v[1].(error) + if ok1 && ok2 { + l.loggerf.Errorf(l.ctx, "tarantool: reconnect (%d) to %s failed: %s", reconnects, conn.Addr(), err) + } else { + l.loggerf.Errorf(l.ctx, "tarantool: reconnect to %s failed (unexpected v... format): %+v", conn.Addr(), v) + } + case tarantool.LogLastReconnectFailed: + if err, ok := v[0].(error); ok { + l.loggerf.Errorf(l.ctx, "tarantool: last reconnect to %s failed: %s, giving it up", conn.Addr(), err) + } else { + l.loggerf.Errorf(l.ctx, "tarantool: last reconnect to %s failed (unexpected v... format): %v+", conn.Addr(), v) + } + case tarantool.LogUnexpectedResultId: + if header, ok := v[0].(tarantool.Header); ok { + l.loggerf.Errorf(l.ctx, "tarantool: connection %s got unexpected resultId (%d) in response"+ + "(probably cancelled request)", + conn.Addr(), header.RequestId) + } else { + l.loggerf.Errorf(l.ctx, "tarantool: connection %s got unexpected resultId in response"+ + "(probably cancelled request) (unexpected v... format): %+v", + conn.Addr(), v) + } + case tarantool.LogWatchEventReadFailed: + if err, ok := v[0].(error); ok { + l.loggerf.Errorf(l.ctx, "tarantool: unable to parse watch event: %s", err) + } else { + l.loggerf.Errorf(l.ctx, "tarantool: unable to parse watch event (unexpected v... format): %+v", v) + } + case tarantool.LogAppendPushFailed: + if err, ok := v[0].(error); ok { + l.loggerf.Errorf(l.ctx, "tarantool: unable to append a push response: %s", err) + } else { + l.loggerf.Errorf(l.ctx, "tarantool: unable to append a push response (unexpected v... format): %+v", v) + } + default: + l.loggerf.Errorf(l.ctx, "tarantool: unexpected event %d on conn %s, v...: %+v", event, conn, v) + } +} diff --git a/topology.go b/topology.go index ff6d80d..211d40c 100644 --- a/topology.go +++ b/topology.go @@ -57,6 +57,7 @@ func (r *Router) AddInstance(ctx context.Context, rsID uuid.UUID, info InstanceI User: r.cfg.User, Password: r.cfg.Password, }, + Opts: r.cfg.PoolOpts, } idToReplicasetRef := r.getIDToReplicaset() diff --git a/vshard.go b/vshard.go index 673cee5..843b6cd 100644 --- a/vshard.go +++ b/vshard.go @@ -243,6 +243,12 @@ func prepareCfg(cfg Config) (Config, error) { } } + // Log tarantool internal events using the same logger as router uses. + cfg.PoolOpts.Logger = tarantoolOptsLogger{ + loggerf: cfg.Loggerf, + ctx: context.Background(), + } + if cfg.Metrics == nil { cfg.Metrics = emptyMetricsProvider }