Skip to content

Commit

Permalink
Fetching Statistics from memcached server
Browse files Browse the repository at this point in the history
  • Loading branch information
Konstantin Nikitin committed Sep 27, 2015
1 parent 72a6864 commit d2245ca
Showing 1 changed file with 82 additions and 0 deletions.
82 changes: 82 additions & 0 deletions memcache/memcache.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ var (
resultTouched = []byte("TOUCHED\r\n")

resultClientErrorPrefix = []byte("CLIENT_ERROR ")

statsGetHits = []byte("STAT get_hits ")
statsGetMisses = []byte("STAT get_misses ")
statsBytesWritten = []byte("STAT bytes_written ")
statsItems = []byte("STAT curr_items ")
statsBytes = []byte("STAT bytes ")
)

// New returns a memcache client using the provided server(s)
Expand Down Expand Up @@ -171,6 +177,24 @@ type conn struct {
c *Client
}

// Statistics is a record of memcached usage stats.
type Statistics struct {
// Counter of cache hits.
Hits uint64

// Counter of cache misses.
Misses uint64

// Counter of bytes transferred for gets.
ByteHits uint64

// Items currently in the cache.
Items uint64

// Size of all items currently in the cache.
Bytes uint64
}

// release returns this connection back to the client's free pool
func (cn *conn) release() {
cn.c.putFreeConn(cn.addr, cn)
Expand Down Expand Up @@ -667,3 +691,61 @@ func (c *Client) incrDecr(verb, key string, delta uint64) (uint64, error) {
})
return val, err
}

func parseStatsLine(s []byte, expectedPrefix []byte) (uint64, error) {
if !bytes.HasPrefix(s, expectedPrefix) {
return 0, errors.New("line does not start with exceptedPrefix")
}
return strconv.ParseUint(
string(s[len(expectedPrefix):len(s)-2]), 10, 64)
}

func parseStatsResponse(r *bufio.Reader, stats *Statistics) error {
for {
line, err := r.ReadSlice('\n')
if err != nil {
return err
}
if bytes.Equal(line, resultEnd) {
return nil
}
if hits, err := parseStatsLine(line, statsGetHits); err == nil {
stats.Hits = hits
continue
}
if misses, err := parseStatsLine(line, statsGetMisses); err == nil {
stats.Misses = misses
continue
}
if bytesWritten, err := parseStatsLine(line, statsBytesWritten); err == nil {
stats.ByteHits = bytesWritten
continue
}
if items, err := parseStatsLine(line, statsItems); err == nil {
stats.Items = items
continue
}
if bytes_total, err := parseStatsLine(line, statsBytes); err == nil {
stats.Bytes = bytes_total
continue
}
}
}


func (c *Client) Stats(addr net.Addr) (*Statistics, error) {
stats := new(Statistics)
err := c.withAddrRw(addr, func(rw *bufio.ReadWriter) error {
if _, err := fmt.Fprintf(rw, "stats\r\n"); err != nil {
return err
}
if err := rw.Flush(); err != nil {
return err
}
if err := parseStatsResponse(rw.Reader, stats); err != nil {
return err
}
return nil
})
return stats, err
}

0 comments on commit d2245ca

Please sign in to comment.