Расширенная статистика кеша memcached
--- items.h.orig 2008-04-28 04:37:56.000000000 +0400
+++ items.h 2008-11-14 13:10:36.000000000 +0300
@@ -13,6 +13,7 @@
/*@null@*/
char *do_item_cachedump(const unsigned int slabs_clsid, const unsigned int limit, unsigned int *bytes);
+char *do_item_cachestat(const unsigned int flags, const unsigned int limit, const unsigned int memlimit, unsigned int *bytes);
char *do_item_stats(int *bytes);
/*@null@*/
--- items.c.orig 2008-07-29 20:37:27.000000000 +0400
+++ items.c 2008-11-14 13:10:36.000000000 +0300
@@ -333,6 +333,61 @@
return buffer;
}
+char *do_item_cachestat(const unsigned int flags, const unsigned int limit, const unsigned int memlimit, unsigned int *bytes) {
+ char *buffer;
+ unsigned int bufcurr;
+ item *it;
+ unsigned int len;
+ unsigned int shown = 0;
+ unsigned int done = 0;
+ char temp[512];
+ unsigned int slabs_clsid;
+ unsigned int memlimitb;
+ rel_time_t now = current_time;
+
+ if (memlimit<=0) return NULL;
+ memlimitb = memlimit * 1024 * 1024;
+ buffer = malloc((size_t)memlimitb);
+ if (buffer == 0) return NULL;
+ bufcurr = 0;
+
+ len = snprintf(temp, sizeof(temp), "KEY BYTES EXPIRE ATIME\r\n");
+ strcpy(buffer + bufcurr, temp);
+ bufcurr += len;
+ if (limit) {
+ len = snprintf(temp, sizeof(temp), "LIMITED TO %u\r\n", limit);
+ strcpy(buffer + bufcurr, temp);
+ bufcurr += len;
+ }
+
+ for (slabs_clsid=0; slabs_clsid<=LARGEST_ID && !done; slabs_clsid++) {
+ it = heads[slabs_clsid];
+ while (it != NULL && (limit == 0 || shown < limit)) {
+ if ((!(flags & 1) && it->exptime) || (!(flags & 2) && !it->exptime)) {
+ it = it->next;
+ continue;
+ }
+ len = snprintf(temp, sizeof(temp), "%s %d %d %d\r\n", ITEM_key(it), it->nbytes - 2, (it->exptime ? it->exptime - now : 0), now - it->time);
+ if (bufcurr + len + 29 > memlimitb) { /* 29 is MEMORY LIMIT EXCEEDED\r\nEND\r\n\0 */
+ strcpy(buffer + bufcurr, "MEMORY LIMIT EXCEEDED\r\n");
+ bufcurr += 23;
+ done = 1;
+ break;
+ }
+ strcpy(buffer + bufcurr, temp);
+ bufcurr += len;
+ shown++;
+ it = it->next;
+ }
+ }
+
+ memcpy(buffer + bufcurr, "END\r\n", 6);
+ bufcurr += 5;
+
+ *bytes = bufcurr;
+ return buffer;
+}
+
char *do_item_stats(int *bytes) {
size_t bufleft = (size_t) LARGEST_ID * 160;
char *buffer = malloc(bufleft);
--- memcached.h.orig 2008-07-29 20:37:27.000000000 +0400
+++ memcached.h 2008-11-14 13:10:36.000000000 +0300
@@ -69,6 +69,7 @@
unsigned int conn_structs;
uint64_t get_cmds;
uint64_t set_cmds;
+ uint64_t set_cmds_forever;
uint64_t get_hits;
uint64_t get_misses;
uint64_t evictions;
@@ -345,6 +346,7 @@
# define is_listen_thread() 1
# define item_alloc(x,y,z,a,b) do_item_alloc(x,y,z,a,b)
# define item_cachedump(x,y,z) do_item_cachedump(x,y,z)
+# define item_cachestat(w,x,y,z) do_item_cachestat(w,x,y,z)
# define item_flush_expired() do_item_flush_expired()
# define item_get_notedeleted(x,y,z) do_item_get_notedeleted(x,y,z)
# define item_link(x) do_item_link(x)
--- memcached.c.orig 2008-07-29 20:37:27.000000000 +0400
+++ memcached.c 2008-11-14 13:10:36.000000000 +0300
@@ -142,7 +142,7 @@
static void stats_init(void) {
stats.curr_items = stats.total_items = stats.curr_conns = stats.total_conns = stats.conn_structs = 0;
- stats.get_cmds = stats.set_cmds = stats.get_hits = stats.get_misses = stats.evictions = 0;
+ stats.get_cmds = stats.set_cmds = stats.set_cmds_forever = stats.get_hits = stats.get_misses = stats.evictions = 0;
stats.curr_bytes = stats.bytes_read = stats.bytes_written = 0;
/* make the time we started always be 2 seconds before we really
@@ -156,7 +156,7 @@
static void stats_reset(void) {
STATS_LOCK();
stats.total_items = stats.total_conns = 0;
- stats.get_cmds = stats.set_cmds = stats.get_hits = stats.get_misses = stats.evictions = 0;
+ stats.get_cmds = stats.set_cmds = stats.set_cmds_forever = stats.get_hits = stats.get_misses = stats.evictions = 0;
stats.bytes_read = stats.bytes_written = 0;
stats_prefix_clear();
STATS_UNLOCK();
@@ -782,6 +782,7 @@
STATS_LOCK();
stats.set_cmds++;
+ if (!it->exptime) stats.set_cmds_forever++;
STATS_UNLOCK();
if (strncmp(ITEM_data(it) + it->nbytes - 2, "\r\n", 2) != 0) {
@@ -1089,6 +1090,7 @@
pos += sprintf(pos, "STAT connection_structures %u\r\n", stats.conn_structs);
pos += sprintf(pos, "STAT cmd_get %llu\r\n", stats.get_cmds);
pos += sprintf(pos, "STAT cmd_set %llu\r\n", stats.set_cmds);
+ pos += sprintf(pos, "STAT cmd_set_forever %llu\r\n", stats.set_cmds_forever);
pos += sprintf(pos, "STAT get_hits %llu\r\n", stats.get_hits);
pos += sprintf(pos, "STAT get_misses %llu\r\n", stats.get_misses);
pos += sprintf(pos, "STAT evictions %llu\r\n", stats.evictions);
@@ -1194,6 +1196,30 @@
return;
}
+ if (strcmp(subcommand, "cachestat") == 0) {
+
+ char *buf;
+ unsigned int bytes, flags = 0, limit = 10, memlimit = 2;
+
+ if(ntokens < 3) {
+ out_string(c, "CLIENT_ERROR bad command line");
+ return;
+ }
+
+ if (ntokens>3) flags = strtoul(tokens[2].value, NULL, 10);
+ if (ntokens>4) limit = strtoul(tokens[3].value, NULL, 10);
+ if (ntokens>5) memlimit = strtoul(tokens[4].value, NULL, 10);
+
+ if(errno == ERANGE) {
+ out_string(c, "CLIENT_ERROR bad command line format");
+ return;
+ }
+
+ buf = item_cachestat(flags, limit, memlimit, &bytes);
+ write_and_free(c, buf, bytes);
+ return;
+ }
+
if (strcmp(subcommand, "slabs") == 0) {
int bytes = 0;
char *buf = slabs_stats(&bytes);