grpc: add trace.EventLog to ClientConn.
This event log records events that are interesting for live debugging of a gRPC client. In particular, this records when a connection is established, broken, and reestablished. The log is displayed on the HTTP endpoint /debug/events in the family named "grpc.ClientConn". Tested using a version of the route guide client modified to serve HTTP and block at the end of main.
This commit is contained in:
@ -42,6 +42,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
"golang.org/x/net/trace"
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
"google.golang.org/grpc/grpclog"
|
"google.golang.org/grpc/grpclog"
|
||||||
"google.golang.org/grpc/transport"
|
"google.golang.org/grpc/transport"
|
||||||
@ -131,6 +132,7 @@ func Dial(target string, opts ...DialOption) (*ClientConn, error) {
|
|||||||
}
|
}
|
||||||
cc := &ClientConn{
|
cc := &ClientConn{
|
||||||
target: target,
|
target: target,
|
||||||
|
events: trace.NewEventLog("grpc.ClientConn", target),
|
||||||
shutdownChan: make(chan struct{}),
|
shutdownChan: make(chan struct{}),
|
||||||
}
|
}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
@ -157,6 +159,7 @@ func Dial(target string, opts ...DialOption) (*ClientConn, error) {
|
|||||||
// Start a goroutine connecting to the server asynchronously.
|
// Start a goroutine connecting to the server asynchronously.
|
||||||
go func() {
|
go func() {
|
||||||
if err := cc.resetTransport(false); err != nil {
|
if err := cc.resetTransport(false); err != nil {
|
||||||
|
cc.events.Errorf("dial failed: %v", err)
|
||||||
grpclog.Printf("Failed to dial %s: %v; please retry.", target, err)
|
grpclog.Printf("Failed to dial %s: %v; please retry.", target, err)
|
||||||
cc.Close()
|
cc.Close()
|
||||||
return
|
return
|
||||||
@ -206,6 +209,7 @@ type ClientConn struct {
|
|||||||
authority string
|
authority string
|
||||||
dopts dialOptions
|
dopts dialOptions
|
||||||
shutdownChan chan struct{}
|
shutdownChan chan struct{}
|
||||||
|
events trace.EventLog
|
||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
state ConnectivityState
|
state ConnectivityState
|
||||||
@ -320,9 +324,11 @@ func (cc *ClientConn) resetTransport(closeTransport bool) error {
|
|||||||
closeTransport = false
|
closeTransport = false
|
||||||
time.Sleep(sleepTime)
|
time.Sleep(sleepTime)
|
||||||
retries++
|
retries++
|
||||||
|
cc.events.Errorf("connection failed, will retry: %v", err)
|
||||||
grpclog.Printf("grpc: ClientConn.resetTransport failed to create client transport: %v; Reconnecting to %q", err, cc.target)
|
grpclog.Printf("grpc: ClientConn.resetTransport failed to create client transport: %v; Reconnecting to %q", err, cc.target)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
cc.events.Printf("connection established")
|
||||||
cc.mu.Lock()
|
cc.mu.Lock()
|
||||||
if cc.state == Shutdown {
|
if cc.state == Shutdown {
|
||||||
// cc.Close() has been invoked.
|
// cc.Close() has been invoked.
|
||||||
@ -359,6 +365,7 @@ func (cc *ClientConn) transportMonitor() {
|
|||||||
cc.mu.Unlock()
|
cc.mu.Unlock()
|
||||||
if err := cc.resetTransport(true); err != nil {
|
if err := cc.resetTransport(true); err != nil {
|
||||||
// The ClientConn is closing.
|
// The ClientConn is closing.
|
||||||
|
cc.events.Printf("transport exiting: %v", err)
|
||||||
grpclog.Printf("grpc: ClientConn.transportMonitor exits due to: %v", err)
|
grpclog.Printf("grpc: ClientConn.transportMonitor exits due to: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -411,6 +418,7 @@ func (cc *ClientConn) Close() error {
|
|||||||
}
|
}
|
||||||
cc.state = Shutdown
|
cc.state = Shutdown
|
||||||
cc.stateCV.Broadcast()
|
cc.stateCV.Broadcast()
|
||||||
|
cc.events.Finish()
|
||||||
if cc.ready != nil {
|
if cc.ready != nil {
|
||||||
close(cc.ready)
|
close(cc.ready)
|
||||||
cc.ready = nil
|
cc.ready = nil
|
||||||
|
Reference in New Issue
Block a user