From 896c944c7ea0704bb0b59ea20081cb8129c80e4a Mon Sep 17 00:00:00 2001 From: Xiang Li Date: Tue, 20 Aug 2013 14:05:23 -0700 Subject: [PATCH] add serverStats --- command.go | 2 +- raft_handlers.go | 3 +++ raft_server.go | 37 ++++++++++++++++++++++--------------- raft_stats.go | 38 +++++++++++++++++++++++++++++++++++--- transporter.go | 3 +++ 5 files changed, 64 insertions(+), 19 deletions(-) diff --git a/command.go b/command.go index 6dc46bfc0..0147811da 100644 --- a/command.go +++ b/command.go @@ -171,7 +171,7 @@ func (c *JoinCommand) Apply(raftServer *raft.Server) (interface{}, error) { etcdStore.Set(key, value, time.Unix(0, 0), raftServer.CommitIndex()) if c.Name != r.Name() { - r.peersStats[c.Name] = &peerStats{MinLatency: 1 << 63} + r.peersStats[c.Name] = &raftPeerStats{MinLatency: 1 << 63} } return b, err diff --git a/raft_handlers.go b/raft_handlers.go index 1a92560ec..f56a3aa0b 100644 --- a/raft_handlers.go +++ b/raft_handlers.go @@ -42,6 +42,9 @@ func AppendEntriesHttpHandler(w http.ResponseWriter, req *http.Request) { if err == nil { debugf("[recv] POST %s/log/append [%d]", r.url, len(aereq.Entries)) + + r.serverStats.RecvAppendReq(aereq.LeaderName) + if resp := r.AppendEntries(aereq); resp != nil { w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(resp) diff --git a/raft_server.go b/raft_server.go index 6355ea86b..91b304ecb 100644 --- a/raft_server.go +++ b/raft_server.go @@ -17,13 +17,14 @@ import ( type raftServer struct { *raft.Server - version string - joinIndex uint64 - name string - url string - tlsConf *TLSConfig - tlsInfo *TLSInfo - peersStats map[string]*peerStats + version string + joinIndex uint64 + name string + url string + tlsConf *TLSConfig + tlsInfo *TLSInfo + peersStats map[string]*raftPeerStats + serverStats *raftServerStats } var r *raftServer @@ -39,13 +40,14 @@ func newRaftServer(name string, url string, tlsConf *TLSConfig, tlsInfo *TLSInfo check(err) return &raftServer{ - Server: server, - version: raftVersion, - name: name, - url: url, - tlsConf: tlsConf, - tlsInfo: tlsInfo, - peersStats: make(map[string]*peerStats), + Server: server, + version: raftVersion, + name: name, + url: url, + tlsConf: tlsConf, + tlsInfo: tlsInfo, + peersStats: make(map[string]*raftPeerStats), + serverStats: &raftServerStats{}, } } @@ -270,7 +272,12 @@ func joinByMachine(s *raft.Server, machine string, scheme string) error { } func (r *raftServer) Stats() []byte { - b, _ := json.Marshal(r.peersStats) + sBytes, _ := json.Marshal(r.serverStats) + + pBytes, _ := json.Marshal(r.peersStats) + + b := append(sBytes, pBytes...) + return b } diff --git a/raft_stats.go b/raft_stats.go index e66f72bd3..2b1686bb6 100644 --- a/raft_stats.go +++ b/raft_stats.go @@ -3,9 +3,41 @@ package main import ( "math" "time" + + "github.com/coreos/go-raft" ) -type peerStats struct { +type raftServerStats struct { + State string + StartTime time.Time + Leader string + leaderStartTime time.Time + LeaderUptime time.Duration + RecvAppendRequestCnt uint64 + SendAppendRequestCnt uint64 +} + +func (ss *raftServerStats) RecvAppendReq(leaderName string) { + ss.State = raft.Follower + if leaderName != ss.Leader { + ss.Leader = leaderName + ss.leaderStartTime = time.Now() + } + + ss.RecvAppendRequestCnt++ +} + +func (ss *raftServerStats) SendAppendReq() { + if ss.State != raft.Leader { + ss.State = raft.Leader + ss.Leader = r.Name() + ss.leaderStartTime = time.Now() + } + + ss.SendAppendRequestCnt++ +} + +type raftPeerStats struct { Latency float64 `json:"latency"` AvgLatency float64 `json:"averageLatency"` avgLatencySquare float64 @@ -16,11 +48,11 @@ type peerStats struct { SuccCnt uint64 `json:"successCount"` } -func (ps *peerStats) Fail() { +func (ps *raftPeerStats) Fail() { ps.FailCnt++ } -func (ps *peerStats) Succ(d time.Duration) { +func (ps *raftPeerStats) Succ(d time.Duration) { total := float64(ps.SuccCnt) * ps.AvgLatency totalSquare := float64(ps.SuccCnt) * ps.avgLatencySquare diff --git a/transporter.go b/transporter.go index 909b6ea68..e476fdf05 100644 --- a/transporter.go +++ b/transporter.go @@ -47,6 +47,9 @@ func dialTimeout(network, addr string) (net.Conn, error) { func (t transporter) SendAppendEntriesRequest(server *raft.Server, peer *raft.Peer, req *raft.AppendEntriesRequest) *raft.AppendEntriesResponse { var aersp *raft.AppendEntriesResponse var b bytes.Buffer + + r.serverStats.SendAppendReq() + json.NewEncoder(&b).Encode(req) u, _ := nameToRaftURL(peer.Name)