From c3da2631bf3cfa1fa4e6aab83fc05f8535cee9b9 Mon Sep 17 00:00:00 2001 From: mqliang Date: Tue, 12 Apr 2016 22:47:27 +0800 Subject: [PATCH 1/4] etcdctlv3: add db size and raft status in protobuffer --- etcdserver/etcdserverpb/rpc.proto | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/etcdserver/etcdserverpb/rpc.proto b/etcdserver/etcdserverpb/rpc.proto index c9737ba7a..8d4d9b93d 100644 --- a/etcdserver/etcdserverpb/rpc.proto +++ b/etcdserver/etcdserverpb/rpc.proto @@ -499,6 +499,10 @@ message StatusRequest { message StatusResponse { ResponseHeader header = 1; string version = 2; + int64 dbSize = 3; + uint64 leader = 4; + uint64 raftIndex = 5; + uint64 raftTerm = 6; } message AuthEnableRequest { From 1044fbce2cd956bf9e83524cb265b3e97ad7f372 Mon Sep 17 00:00:00 2001 From: mqliang Date: Tue, 12 Apr 2016 22:48:47 +0800 Subject: [PATCH 2/4] etcdctlv3: update aunto generated files --- auth/authpb/auth.pb.go | 4 +- etcdserver/etcdserverpb/rpc.pb.go | 116 +++++++++++++++++++++++++++++- lease/leasepb/lease.pb.go | 4 +- raft/raftpb/raft.pb.go | 4 +- snap/snappb/snap.pb.go | 4 +- storage/storagepb/kv.pb.go | 4 +- wal/walpb/record.pb.go | 4 +- 7 files changed, 126 insertions(+), 14 deletions(-) diff --git a/auth/authpb/auth.pb.go b/auth/authpb/auth.pb.go index 00a5cfe64..44ffc6400 100644 --- a/auth/authpb/auth.pb.go +++ b/auth/authpb/auth.pb.go @@ -19,10 +19,10 @@ import ( "fmt" proto "github.com/gogo/protobuf/proto" - - math "math" ) +import math "math" + import io "io" // Reference imports to suppress errors if they are not otherwise used. diff --git a/etcdserver/etcdserverpb/rpc.pb.go b/etcdserver/etcdserverpb/rpc.pb.go index cd95b9ca7..8a2f9d84a 100644 --- a/etcdserver/etcdserverpb/rpc.pb.go +++ b/etcdserver/etcdserverpb/rpc.pb.go @@ -1286,8 +1286,12 @@ func (m *StatusRequest) String() string { return proto.CompactTextString(m) } func (*StatusRequest) ProtoMessage() {} type StatusResponse struct { - Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` - Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + DbSize int64 `protobuf:"varint,3,opt,name=dbSize,proto3" json:"dbSize,omitempty"` + Leader uint64 `protobuf:"varint,4,opt,name=leader,proto3" json:"leader,omitempty"` + RaftIndex uint64 `protobuf:"varint,5,opt,name=raftIndex,proto3" json:"raftIndex,omitempty"` + RaftTerm uint64 `protobuf:"varint,6,opt,name=raftTerm,proto3" json:"raftTerm,omitempty"` } func (m *StatusResponse) Reset() { *m = StatusResponse{} } @@ -4619,6 +4623,26 @@ func (m *StatusResponse) MarshalTo(data []byte) (int, error) { i = encodeVarintRpc(data, i, uint64(len(m.Version))) i += copy(data[i:], m.Version) } + if m.DbSize != 0 { + data[i] = 0x18 + i++ + i = encodeVarintRpc(data, i, uint64(m.DbSize)) + } + if m.Leader != 0 { + data[i] = 0x20 + i++ + i = encodeVarintRpc(data, i, uint64(m.Leader)) + } + if m.RaftIndex != 0 { + data[i] = 0x28 + i++ + i = encodeVarintRpc(data, i, uint64(m.RaftIndex)) + } + if m.RaftTerm != 0 { + data[i] = 0x30 + i++ + i = encodeVarintRpc(data, i, uint64(m.RaftTerm)) + } return i, nil } @@ -6078,6 +6102,18 @@ func (m *StatusResponse) Size() (n int) { if l > 0 { n += 1 + l + sovRpc(uint64(l)) } + if m.DbSize != 0 { + n += 1 + sovRpc(uint64(m.DbSize)) + } + if m.Leader != 0 { + n += 1 + sovRpc(uint64(m.Leader)) + } + if m.RaftIndex != 0 { + n += 1 + sovRpc(uint64(m.RaftIndex)) + } + if m.RaftTerm != 0 { + n += 1 + sovRpc(uint64(m.RaftTerm)) + } return n } @@ -11096,6 +11132,82 @@ func (m *StatusResponse) Unmarshal(data []byte) error { } m.Version = string(data[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DbSize", wireType) + } + m.DbSize = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + m.DbSize |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Leader", wireType) + } + m.Leader = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + m.Leader |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RaftIndex", wireType) + } + m.RaftIndex = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + m.RaftIndex |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RaftTerm", wireType) + } + m.RaftTerm = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + m.RaftTerm |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) diff --git a/lease/leasepb/lease.pb.go b/lease/leasepb/lease.pb.go index 9c0d77124..b98ca98ca 100644 --- a/lease/leasepb/lease.pb.go +++ b/lease/leasepb/lease.pb.go @@ -17,10 +17,10 @@ import ( "fmt" proto "github.com/gogo/protobuf/proto" - - math "math" ) +import math "math" + import io "io" // Reference imports to suppress errors if they are not otherwise used. diff --git a/raft/raftpb/raft.pb.go b/raft/raftpb/raft.pb.go index d5abecb48..3421e8196 100644 --- a/raft/raftpb/raft.pb.go +++ b/raft/raftpb/raft.pb.go @@ -23,10 +23,10 @@ import ( "fmt" proto "github.com/gogo/protobuf/proto" - - math "math" ) +import math "math" + import io "io" // Reference imports to suppress errors if they are not otherwise used. diff --git a/snap/snappb/snap.pb.go b/snap/snappb/snap.pb.go index f83fd411a..5d1d21ab3 100644 --- a/snap/snappb/snap.pb.go +++ b/snap/snappb/snap.pb.go @@ -17,10 +17,10 @@ import ( "fmt" proto "github.com/gogo/protobuf/proto" - - math "math" ) +import math "math" + import io "io" // Reference imports to suppress errors if they are not otherwise used. diff --git a/storage/storagepb/kv.pb.go b/storage/storagepb/kv.pb.go index 2987b9be6..02588904c 100644 --- a/storage/storagepb/kv.pb.go +++ b/storage/storagepb/kv.pb.go @@ -18,10 +18,10 @@ import ( "fmt" proto "github.com/gogo/protobuf/proto" - - math "math" ) +import math "math" + import io "io" // Reference imports to suppress errors if they are not otherwise used. diff --git a/wal/walpb/record.pb.go b/wal/walpb/record.pb.go index 7ae042a51..638bdc3b6 100644 --- a/wal/walpb/record.pb.go +++ b/wal/walpb/record.pb.go @@ -18,10 +18,10 @@ import ( "fmt" proto "github.com/gogo/protobuf/proto" - - math "math" ) +import math "math" + import io "io" // Reference imports to suppress errors if they are not otherwise used. From a9a06438f9f071283f0edca03f15691a6edb648d Mon Sep 17 00:00:00 2001 From: mqliang Date: Tue, 12 Apr 2016 22:49:15 +0800 Subject: [PATCH 3/4] etcdctlv3: expose db size and raft status in server side --- etcdserver/api/v3rpc/maintenance.go | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/etcdserver/api/v3rpc/maintenance.go b/etcdserver/api/v3rpc/maintenance.go index b455fe98a..6de1c661a 100644 --- a/etcdserver/api/v3rpc/maintenance.go +++ b/etcdserver/api/v3rpc/maintenance.go @@ -19,6 +19,7 @@ import ( "github.com/coreos/etcd/etcdserver" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" + "github.com/coreos/etcd/pkg/types" "github.com/coreos/etcd/storage/backend" "github.com/coreos/etcd/version" "golang.org/x/net/context" @@ -32,14 +33,21 @@ type Alarmer interface { Alarm(ctx context.Context, ar *pb.AlarmRequest) (*pb.AlarmResponse, error) } +type RaftStatusGetter interface { + Index() uint64 + Term() uint64 + Leader() types.ID +} + type maintenanceServer struct { + rg RaftStatusGetter bg BackendGetter a Alarmer hdr header } func NewMaintenanceServer(s *etcdserver.EtcdServer) pb.MaintenanceServer { - return &maintenanceServer{bg: s, a: s, hdr: newHeader(s)} + return &maintenanceServer{rg: s, bg: s, a: s, hdr: newHeader(s)} } func (ms *maintenanceServer) Defragment(ctx context.Context, sr *pb.DefragmentRequest) (*pb.DefragmentResponse, error) { @@ -103,7 +111,14 @@ func (ms *maintenanceServer) Alarm(ctx context.Context, ar *pb.AlarmRequest) (*p } func (ms *maintenanceServer) Status(ctx context.Context, ar *pb.StatusRequest) (*pb.StatusResponse, error) { - resp := &pb.StatusResponse{Header: &pb.ResponseHeader{Revision: ms.hdr.rev()}, Version: version.Version} + resp := &pb.StatusResponse{ + Header: &pb.ResponseHeader{Revision: ms.hdr.rev()}, + Version: version.Version, + DbSize: ms.bg.Backend().Size(), + Leader: uint64(ms.rg.Leader()), + RaftIndex: ms.rg.Index(), + RaftTerm: ms.rg.Term(), + } ms.hdr.fill(resp.Header) return resp, nil } From ff311ba0a7acfc0109ca20e4bdbd2aaf2c6be9b2 Mon Sep 17 00:00:00 2001 From: mqliang Date: Tue, 12 Apr 2016 22:49:39 +0800 Subject: [PATCH 4/4] etcdctlv3: print db size and raft status in 'etcdctl status' command --- etcdctl/ctlv3/command/printer.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/etcdctl/ctlv3/command/printer.go b/etcdctl/ctlv3/command/printer.go index 1432d82cd..59ccaad6c 100644 --- a/etcdctl/ctlv3/command/printer.go +++ b/etcdctl/ctlv3/command/printer.go @@ -131,13 +131,17 @@ func (s *simplePrinter) MemberList(resp v3.MemberListResponse) { func (s *simplePrinter) MemberStatus(statusList []statusInfo) { table := tablewriter.NewWriter(os.Stdout) - table.SetHeader([]string{"endpoint", "ID", "version"}) + table.SetHeader([]string{"endpoint", "ID", "version", "db size", "is leader", "raft term", "raft index"}) for _, status := range statusList { table.Append([]string{ fmt.Sprint(status.ep), fmt.Sprintf("%x", status.resp.Header.MemberId), fmt.Sprint(status.resp.Version), + fmt.Sprint(humanize.Bytes(uint64(status.resp.DbSize))), + fmt.Sprint(status.resp.Leader == status.resp.Header.MemberId), + fmt.Sprint(status.resp.RaftTerm), + fmt.Sprint(status.resp.RaftIndex), }) }