Skip to content

Commit

Permalink
feature: add request handling statistics for pouch daemon
Browse files Browse the repository at this point in the history
Signed-off-by: Allen Sun <allensun.shl@alibaba-inc.com>
  • Loading branch information
allencloud committed Aug 10, 2018
1 parent 33d90d2 commit 1ee251a
Show file tree
Hide file tree
Showing 5 changed files with 215 additions and 1 deletion.
65 changes: 65 additions & 0 deletions apis/server/response_stats.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package server

import "sync"

// RequestStats is the request dealing result,
// including all handled request number, 2xx3xx number, 4xx number and 5xx number
type RequestStats struct {
sync.Mutex
// req5xxCount is the count number of failed request which returns a status code of 5xx.
req5xxCount uint64
// req4xxCount is the count number of failed request which returns a status code of 5xx.
req4xxCount uint64
// req2xxCount is the count number of requests which returns a status code of 2xx and 3xx.
req2xx3xxCount uint64
// reqCount is the count number of all request.
reqCount uint64
}

func (rs *RequestStats) getAllCount() uint64 {
rs.Lock()
defer rs.Unlock()
return rs.reqCount
}

func (rs *RequestStats) get2xx3xxCount() uint64 {
rs.Lock()
defer rs.Unlock()
return rs.req2xx3xxCount
}

func (rs *RequestStats) get4xxCount() uint64 {
rs.Lock()
defer rs.Unlock()
return rs.req4xxCount
}

func (rs *RequestStats) get5xxCount() uint64 {
rs.Lock()
defer rs.Unlock()
return rs.req5xxCount
}

func (rs *RequestStats) increaseReqCount() {
rs.Lock()
rs.reqCount++
rs.Unlock()
}

func (rs *RequestStats) increase2xx3xxCount() {
rs.Lock()
rs.req2xx3xxCount++
rs.Unlock()
}

func (rs *RequestStats) increase4xxCount() {
rs.Lock()
rs.req4xxCount++
rs.Unlock()
}

func (rs *RequestStats) increase5xxCount() {
rs.Lock()
rs.req5xxCount++
rs.Unlock()
}
28 changes: 27 additions & 1 deletion apis/server/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,24 @@ import (
// versionMatcher defines to parse version url path.
const versionMatcher = "/v{version:[0-9.]+}"

// reqStats is used to calculate the request dealing status.
var reqStats = &RequestStats{}

func initRoute(s *Server) http.Handler {
r := mux.NewRouter()

// system
s.addRoute(r, http.MethodGet, "/_ping", s.ping)
s.addRoute(r, http.MethodGet, "/info", s.info)
s.addRoute(r, http.MethodGet, "/version", s.version)
s.addRoute(r, http.MethodGet, "/stats", func(context context.Context, rw http.ResponseWriter, req *http.Request) (err error) {
return EncodeResponse(rw, http.StatusOK, types.ResponseStats{
AllRequests: reqStats.getAllCount(),
Req2xx3xxCount: reqStats.get2xx3xxCount(),
Req4xxCount: reqStats.get4xxCount(),
Req5xxCount: reqStats.get5xxCount(),
})
})
s.addRoute(r, http.MethodPost, "/auth", s.auth)

// daemon, we still list this API into system manager.
Expand Down Expand Up @@ -75,7 +86,6 @@ func initRoute(s *Server) http.Handler {
s.addRoute(r, http.MethodDelete, "/volumes/{name:.*}", s.removeVolume)

// network

s.addRoute(r, http.MethodGet, "/networks", s.listNetwork)
s.addRoute(r, http.MethodPost, "/networks/create", s.createNetwork)
s.addRoute(r, http.MethodGet, "/networks/{id:.*}", s.getNetwork)
Expand Down Expand Up @@ -184,9 +194,13 @@ func filter(handler handler, s *Server) http.HandlerFunc {
logrus.Debugf("Calling %s %s, client %s", req.Method, req.URL.RequestURI(), clientInfo)
}

// increase the request number by 1.
reqStats.increaseReqCount()

// Start to handle request.
err := handler(ctx, w, req)
if err == nil {
reqStats.increase2xx3xxCount()
return
}
// Handle error if request handling fails.
Expand Down Expand Up @@ -224,6 +238,8 @@ func HandleErrorResponse(w http.ResponseWriter, err error) {
code = http.StatusConflict
}

calReqStatictics(code)

w.Header().Set("Content-Type", "application/json")
w.WriteHeader(code)
enc := json.NewEncoder(w)
Expand All @@ -234,3 +250,13 @@ func HandleErrorResponse(w http.ResponseWriter, err error) {
}
enc.Encode(resp)
}

// calReqStatictics will increase the 4xx count and 5xx count.
func calReqStatictics(code int) {
if code >= http.StatusInternalServerError {
reqStats.increase5xxCount()
}
if code >= http.StatusBadRequest && code < http.StatusInternalServerError {
reqStats.increase4xxCount()
}
}
35 changes: 35 additions & 0 deletions apis/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,20 @@ paths:
schema:
$ref: "#/definitions/AuthConfig"

/stats:
get:
summary: "Get daemon's request dealing result, including all handled request number, 2xx3xx number, 4xx number and 5xx number"
description: "Get daemon's request dealing result, including all handled request number, 2xx3xx number, 4xx number and 5xx number"
consumes:
- "application/json"
produces:
- "application/json"
responses:
200:
description: "The request handling stats have returned"
schema:
$ref: "#/definitions/ResponseStats"

/daemon/update:
post:
summary: "Update daemon's labels and image proxy"
Expand Down Expand Up @@ -1563,6 +1577,27 @@ definitions:
example:
- ["unix:///var/run/pouchd.sock", "tcp://0.0.0.0:4243"]

ResponseStats:
type: "object"
description: ResponseStats contains all request handling result in daemon including 2xx3xx response number, 4xx and 5xx number.
properties:
AllRequests:
description: all requests number handled by daemon no matter success or failure.
type: "integer"
format: "uint64"
req2xx3xxCount:
description: all response number returned by daemon which is 2xx or 3xx status code.
type: "integer"
format: "uint64"
Req4xxCount:
description: all response number returned by daemon which is 4xx status code.
type: "integer"
format: "uint64"
Req5xxCount:
description: all response number returned by daemon which is 5xx status code.
type: "integer"
format: "uint64"

DaemonUpdateConfig:
type: "object"
properties:
Expand Down
67 changes: 67 additions & 0 deletions apis/types/response_stats.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions test/api_system_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,24 @@ func (suite *APISystemSuite) TestRegistryLogin(c *check.C) {
request.DecodeBody(authResp, resp.Body)
c.Assert(util.PartialEqual(authResp.Status, "Login Succeeded"), check.IsNil)
}

// TestStats tests /stats API.
func (suite *APISystemSuite) TestStats(c *check.C) {
resp, err := request.Get("/stats")
c.Assert(err, check.IsNil)
defer resp.Body.Close()

CheckRespStatus(c, resp, 200)

got := types.ResponseStats{}
err = json.NewDecoder(resp.Body).Decode(&got)
c.Assert(err, check.IsNil)

if got.AllRequests <= 1 {
c.Fatalf("daemon handling request should be more than 1, actual: %d", got.AllRequests)
}

if got.Nr2xx3xxResponse <= 1 {
c.Fatalf("daemon handling request should be more than 0, actual: %d", got.Nr2xx3xxResponse)
}
}

0 comments on commit 1ee251a

Please sign in to comment.