etcdserver: expose store statistics
parent
79e9f2ab81
commit
0a8721a708
|
@ -25,6 +25,7 @@ const (
|
|||
deprecatedMachinesPrefix = "/v2/machines"
|
||||
adminMembersPrefix = "/v2/admin/members/"
|
||||
raftPrefix = "/raft"
|
||||
statsPrefix = "/v2/stats"
|
||||
|
||||
// time to wait for response from EtcdServer requests
|
||||
defaultServerTimeout = 500 * time.Millisecond
|
||||
|
@ -42,10 +43,12 @@ func NewClientHandler(server *etcdserver.EtcdServer) http.Handler {
|
|||
clusterStore: server.ClusterStore,
|
||||
timer: server,
|
||||
timeout: defaultServerTimeout,
|
||||
storeStats: server.StoreStats,
|
||||
}
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc(keysPrefix, sh.serveKeys)
|
||||
mux.HandleFunc(keysPrefix+"/", sh.serveKeys)
|
||||
mux.HandleFunc(statsPrefix+"/store", sh.serveStoreStats)
|
||||
// TODO: dynamic configuration may make this outdated. take care of it.
|
||||
// TODO: dynamic configuration may introduce race also.
|
||||
// TODO: add serveMembers
|
||||
|
@ -72,6 +75,7 @@ type serverHandler struct {
|
|||
server etcdserver.Server
|
||||
timer etcdserver.RaftTimer
|
||||
clusterStore etcdserver.ClusterStore
|
||||
storeStats func() []byte
|
||||
}
|
||||
|
||||
func (h serverHandler) serveKeys(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -162,6 +166,14 @@ func (h serverHandler) serveAdminMembers(w http.ResponseWriter, r *http.Request)
|
|||
}
|
||||
}
|
||||
|
||||
func (h serverHandler) serveStoreStats(w http.ResponseWriter, r *http.Request) {
|
||||
if !allowMethod(w, r.Method, "GET") {
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(h.storeStats())
|
||||
}
|
||||
|
||||
func (h serverHandler) serveRaft(w http.ResponseWriter, r *http.Request) {
|
||||
if !allowMethod(w, r.Method, "POST") {
|
||||
return
|
||||
|
|
|
@ -637,6 +637,32 @@ func TestServeMachines(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestServeStoreStats(t *testing.T) {
|
||||
w := "foobarbaz"
|
||||
sh := &serverHandler{
|
||||
storeStats: func() []byte {
|
||||
return []byte(w)
|
||||
},
|
||||
}
|
||||
rw := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
sh.serveStoreStats(rw, req)
|
||||
if rw.Code != http.StatusOK {
|
||||
t.Errorf("header = %d, want %d", rw.Code, http.StatusOK)
|
||||
}
|
||||
wct := "application/json"
|
||||
if gct := rw.Header().Get("Content-Type"); gct != wct {
|
||||
t.Errorf("Content-Type = %q, want %q", gct, wct)
|
||||
}
|
||||
if g := rw.Body.String(); g != w {
|
||||
t.Errorf("body = %s, want %s", g, w)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestAllowMethod(t *testing.T) {
|
||||
tests := []struct {
|
||||
m string
|
||||
|
|
|
@ -198,6 +198,10 @@ func (s *EtcdServer) Start() {
|
|||
go s.publish(defaultPublishRetryInterval)
|
||||
}
|
||||
|
||||
func (s *EtcdServer) StoreStats() []byte {
|
||||
return s.store.JsonStats()
|
||||
}
|
||||
|
||||
// start prepares and starts server in a new goroutine. It is no longer safe to
|
||||
// modify a server's fields after it has been sent to Start.
|
||||
// This function is just used for testing.
|
||||
|
|
Loading…
Reference in New Issue