6 static const char *memcached_stat_keys
[] = {
19 "connection_structures",
33 static memcached_return_t
set_data(memcached_stat_st
*memc_stat
, char *key
, char *value
)
38 WATCHPOINT_STRING(key
);
39 return MEMCACHED_UNKNOWN_STAT_KEY
;
41 else if (!strcmp("pid", key
))
43 memc_stat
->pid
= (uint32_t) strtol(value
, (char **)NULL
, 10);
45 else if (!strcmp("uptime", key
))
47 memc_stat
->uptime
= (uint32_t) strtol(value
, (char **)NULL
, 10);
49 else if (!strcmp("time", key
))
51 memc_stat
->time
= (uint32_t) strtol(value
, (char **)NULL
, 10);
53 else if (!strcmp("version", key
))
55 memcpy(memc_stat
->version
, value
, strlen(value
));
56 memc_stat
->version
[strlen(value
)]= 0;
58 else if (!strcmp("pointer_size", key
))
60 memc_stat
->pointer_size
= (uint32_t) strtol(value
, (char **)NULL
, 10);
62 else if (!strcmp("rusage_user", key
))
65 for (walk_ptr
= value
; (!ispunct(*walk_ptr
)); walk_ptr
++);
68 memc_stat
->rusage_user_seconds
= (uint32_t) strtol(value
, (char **)NULL
, 10);
69 memc_stat
->rusage_user_microseconds
= (uint32_t) strtol(walk_ptr
, (char **)NULL
, 10);
71 else if (!strcmp("rusage_system", key
))
74 for (walk_ptr
= value
; (!ispunct(*walk_ptr
)); walk_ptr
++);
77 memc_stat
->rusage_system_seconds
= (uint32_t) strtol(value
, (char **)NULL
, 10);
78 memc_stat
->rusage_system_microseconds
= (uint32_t) strtol(walk_ptr
, (char **)NULL
, 10);
80 else if (!strcmp("curr_items", key
))
82 memc_stat
->curr_items
= (uint32_t) strtol(value
, (char **)NULL
, 10);
84 else if (!strcmp("total_items", key
))
86 memc_stat
->total_items
= (uint32_t) strtol(value
, (char **)NULL
, 10);
88 else if (!strcmp("bytes_read", key
))
90 memc_stat
->bytes_read
= (uint32_t) strtoll(value
, (char **)NULL
, 10);
92 else if (!strcmp("bytes_written", key
))
94 memc_stat
->bytes_written
= (uint32_t) strtoll(value
, (char **)NULL
, 10);
96 else if (!strcmp("bytes", key
))
98 memc_stat
->bytes
= (uint32_t) strtoll(value
, (char **)NULL
, 10);
100 else if (!strcmp("curr_connections", key
))
102 memc_stat
->curr_connections
= (uint32_t) strtoll(value
, (char **)NULL
, 10);
104 else if (!strcmp("total_connections", key
))
106 memc_stat
->total_connections
= (uint32_t) strtoll(value
, (char **)NULL
, 10);
108 else if (!strcmp("connection_structures", key
))
110 memc_stat
->connection_structures
= (uint32_t) strtol(value
, (char **)NULL
, 10);
112 else if (!strcmp("cmd_get", key
))
114 memc_stat
->cmd_get
= (uint64_t) strtoll(value
, (char **)NULL
, 10);
116 else if (!strcmp("cmd_set", key
))
118 memc_stat
->cmd_set
= (uint64_t) strtoll(value
, (char **)NULL
, 10);
120 else if (!strcmp("get_hits", key
))
122 memc_stat
->get_hits
= (uint64_t) strtoll(value
, (char **)NULL
, 10);
124 else if (!strcmp("get_misses", key
))
126 memc_stat
->get_misses
= (uint64_t)strtoll(value
, (char **)NULL
, 10);
128 else if (!strcmp("evictions", key
))
130 memc_stat
->evictions
= (uint64_t)strtoll(value
, (char **)NULL
, 10);
132 else if (!strcmp("limit_maxbytes", key
))
134 memc_stat
->limit_maxbytes
= (uint64_t) strtoll(value
, (char **)NULL
, 10);
136 else if (!strcmp("threads", key
))
138 memc_stat
->threads
= (uint32_t) strtol(value
, (char **)NULL
, 10);
140 else if (!(strcmp("delete_misses", key
) == 0 ||/* New stats in the 1.3 beta */
141 strcmp("delete_hits", key
) == 0 ||/* Just swallow them for now.. */
142 strcmp("incr_misses", key
) == 0 ||
143 strcmp("incr_hits", key
) == 0 ||
144 strcmp("decr_misses", key
) == 0 ||
145 strcmp("decr_hits", key
) == 0 ||
146 strcmp("cas_misses", key
) == 0 ||
147 strcmp("cas_hits", key
) == 0 ||
148 strcmp("cas_badval", key
) == 0 ||
149 strcmp("cmd_flush", key
) == 0 ||
150 strcmp("accepting_conns", key
) == 0 ||
151 strcmp("listen_disabled_num", key
) == 0 ||
152 strcmp("conn_yields", key
) == 0 ||
153 strcmp("auth_cmds", key
) == 0 ||
154 strcmp("auth_errors", key
) == 0 ||
155 strcmp("reclaimed", key
) == 0))
157 WATCHPOINT_STRING(key
);
158 return MEMCACHED_UNKNOWN_STAT_KEY
;
161 return MEMCACHED_SUCCESS
;
164 char *memcached_stat_get_value(memcached_st
*ptr
, memcached_stat_st
*memc_stat
,
165 const char *key
, memcached_return_t
*error
)
167 char buffer
[SMALL_STRING_LEN
];
171 *error
= MEMCACHED_SUCCESS
;
173 if (!memcmp("pid", key
, strlen("pid")))
174 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%u", memc_stat
->pid
);
175 else if (!memcmp("uptime", key
, strlen("uptime")))
176 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%u", memc_stat
->uptime
);
177 else if (!memcmp("time", key
, strlen("time")))
178 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%llu", (unsigned long long)memc_stat
->time
);
179 else if (!memcmp("version", key
, strlen("version")))
180 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%s", memc_stat
->version
);
181 else if (!memcmp("pointer_size", key
, strlen("pointer_size")))
182 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%u", memc_stat
->pointer_size
);
183 else if (!memcmp("rusage_user", key
, strlen("rusage_user")))
184 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%u.%u", memc_stat
->rusage_user_seconds
, memc_stat
->rusage_user_microseconds
);
185 else if (!memcmp("rusage_system", key
, strlen("rusage_system")))
186 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%u.%u", memc_stat
->rusage_system_seconds
, memc_stat
->rusage_system_microseconds
);
187 else if (!memcmp("curr_items", key
, strlen("curr_items")))
188 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%u", memc_stat
->curr_items
);
189 else if (!memcmp("total_items", key
, strlen("total_items")))
190 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%u", memc_stat
->total_items
);
191 else if (!memcmp("curr_connections", key
, strlen("curr_connections")))
192 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%u", memc_stat
->curr_connections
);
193 else if (!memcmp("total_connections", key
, strlen("total_connections")))
194 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%u", memc_stat
->total_connections
);
195 else if (!memcmp("connection_structures", key
, strlen("connection_structures")))
196 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%u", memc_stat
->connection_structures
);
197 else if (!memcmp("cmd_get", key
, strlen("cmd_get")))
198 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%llu", (unsigned long long)memc_stat
->cmd_get
);
199 else if (!memcmp("cmd_set", key
, strlen("cmd_set")))
200 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%llu", (unsigned long long)memc_stat
->cmd_set
);
201 else if (!memcmp("get_hits", key
, strlen("get_hits")))
202 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%llu", (unsigned long long)memc_stat
->get_hits
);
203 else if (!memcmp("get_misses", key
, strlen("get_misses")))
204 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%llu", (unsigned long long)memc_stat
->get_misses
);
205 else if (!memcmp("evictions", key
, strlen("evictions")))
206 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%llu", (unsigned long long)memc_stat
->evictions
);
207 else if (!memcmp("bytes_read", key
, strlen("bytes_read")))
208 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%llu", (unsigned long long)memc_stat
->bytes_read
);
209 else if (!memcmp("bytes_written", key
, strlen("bytes_written")))
210 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%llu", (unsigned long long)memc_stat
->bytes_written
);
211 else if (!memcmp("bytes", key
, strlen("bytes")))
212 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%llu", (unsigned long long)memc_stat
->bytes
);
213 else if (!memcmp("limit_maxbytes", key
, strlen("limit_maxbytes")))
214 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%llu", (unsigned long long)memc_stat
->limit_maxbytes
);
215 else if (!memcmp("threads", key
, strlen("threads")))
216 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%u", memc_stat
->threads
);
219 *error
= MEMCACHED_NOTFOUND
;
223 ret
= libmemcached_malloc(ptr
, (size_t) (length
+ 1));
224 memcpy(ret
, buffer
, (size_t) length
);
230 static memcached_return_t
binary_stats_fetch(memcached_stat_st
*memc_stat
,
232 memcached_server_instance_st
*instance
)
234 memcached_return_t rc
;
236 char buffer
[MEMCACHED_DEFAULT_COMMAND_SIZE
];
237 protocol_binary_request_stats request
= {.bytes
= {0}};
238 request
.message
.header
.request
.magic
= PROTOCOL_BINARY_REQ
;
239 request
.message
.header
.request
.opcode
= PROTOCOL_BINARY_CMD_STAT
;
240 request
.message
.header
.request
.datatype
= PROTOCOL_BINARY_RAW_BYTES
;
244 size_t len
= strlen(args
);
246 rc
= memcached_validate_key_length(len
, true);
247 unlikely (rc
!= MEMCACHED_SUCCESS
)
250 request
.message
.header
.request
.keylen
= htons((uint16_t)len
);
251 request
.message
.header
.request
.bodylen
= htonl((uint32_t) len
);
253 if ((memcached_do(instance
, request
.bytes
,
254 sizeof(request
.bytes
), false) != MEMCACHED_SUCCESS
) ||
255 (memcached_io_write(instance
, args
, len
, true) == -1))
257 memcached_io_reset(instance
);
258 return MEMCACHED_WRITE_FAILURE
;
263 if (memcached_do(instance
, request
.bytes
,
264 sizeof(request
.bytes
), true) != MEMCACHED_SUCCESS
)
266 memcached_io_reset(instance
);
267 return MEMCACHED_WRITE_FAILURE
;
271 memcached_server_response_decrement(instance
);
274 rc
= memcached_response(instance
, buffer
,
275 sizeof(buffer
), NULL
);
276 if (rc
== MEMCACHED_END
)
279 unlikely (rc
!= MEMCACHED_SUCCESS
)
281 memcached_io_reset(instance
);
285 unlikely((set_data(memc_stat
, buffer
, buffer
+ strlen(buffer
) + 1)) == MEMCACHED_UNKNOWN_STAT_KEY
)
287 WATCHPOINT_ERROR(MEMCACHED_UNKNOWN_STAT_KEY
);
288 WATCHPOINT_ASSERT(0);
292 /* shit... memcached_response will decrement the counter, so I need to
293 ** reset it.. todo: look at this and try to find a better solution.
295 instance
->cursor_active
= 0;
297 return MEMCACHED_SUCCESS
;
300 static memcached_return_t
ascii_stats_fetch(memcached_stat_st
*memc_stat
,
302 memcached_server_instance_st
*instance
)
304 memcached_return_t rc
;
305 char buffer
[MEMCACHED_DEFAULT_COMMAND_SIZE
];
309 send_length
= (size_t) snprintf(buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
,
310 "stats %s\r\n", args
);
312 send_length
= (size_t) snprintf(buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
,
315 if (send_length
>= MEMCACHED_DEFAULT_COMMAND_SIZE
)
316 return MEMCACHED_WRITE_FAILURE
;
318 rc
= memcached_do(instance
, buffer
, send_length
, true);
319 if (rc
!= MEMCACHED_SUCCESS
)
324 rc
= memcached_response(instance
, buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
, NULL
);
326 if (rc
== MEMCACHED_STAT
)
328 char *string_ptr
, *end_ptr
;
332 string_ptr
+= 5; /* Move past STAT */
333 for (end_ptr
= string_ptr
; isgraph(*end_ptr
); end_ptr
++);
335 key
[(size_t)(end_ptr
-string_ptr
)]= 0;
337 string_ptr
= end_ptr
+ 1;
338 for (end_ptr
= string_ptr
; !(isspace(*end_ptr
)); end_ptr
++);
340 value
[(size_t)(end_ptr
-string_ptr
)]= 0;
341 string_ptr
= end_ptr
+ 2;
342 unlikely((set_data(memc_stat
, key
, value
)) == MEMCACHED_UNKNOWN_STAT_KEY
)
344 WATCHPOINT_ERROR(MEMCACHED_UNKNOWN_STAT_KEY
);
345 WATCHPOINT_ASSERT(0);
353 if (rc
== MEMCACHED_END
)
354 return MEMCACHED_SUCCESS
;
359 memcached_stat_st
*memcached_stat(memcached_st
*ptr
, char *args
, memcached_return_t
*error
)
361 memcached_return_t rc
;
362 memcached_stat_st
*stats
;
364 unlikely (ptr
->flags
.use_udp
)
366 *error
= MEMCACHED_NOT_SUPPORTED
;
370 stats
= libmemcached_calloc(ptr
, memcached_server_count(ptr
), sizeof(memcached_stat_st
));
374 *error
= MEMCACHED_MEMORY_ALLOCATION_FAILURE
;
378 rc
= MEMCACHED_SUCCESS
;
379 for (uint32_t x
= 0; x
< memcached_server_count(ptr
); x
++)
381 memcached_return_t temp_return
;
382 memcached_server_instance_st
*instance
;
383 memcached_stat_st
*stat_instance
;
385 stat_instance
= stats
+ x
;
387 stat_instance
->root
= ptr
;
389 instance
= memcached_server_instance_fetch(ptr
, x
);
391 if (ptr
->flags
.binary_protocol
)
393 temp_return
= binary_stats_fetch(stat_instance
, args
, instance
);
397 temp_return
= ascii_stats_fetch(stat_instance
, args
, instance
);
400 if (temp_return
!= MEMCACHED_SUCCESS
)
401 rc
= MEMCACHED_SOME_ERRORS
;
408 memcached_return_t
memcached_stat_servername(memcached_stat_st
*memc_stat
, char *args
,
409 const char *hostname
, in_port_t port
)
411 memcached_return_t rc
;
413 memcached_st
*memc_ptr
;
414 memcached_server_instance_st
*instance
;
416 memc_ptr
= memcached_create(&memc
);
417 WATCHPOINT_ASSERT(memc_ptr
);
419 memcached_server_add(&memc
, hostname
, port
);
421 instance
= memcached_server_instance_fetch(memc_ptr
, 0);
423 if (memc
.flags
.binary_protocol
)
425 rc
= binary_stats_fetch(memc_stat
, args
, instance
);
429 rc
= ascii_stats_fetch(memc_stat
, args
, instance
);
432 memcached_free(&memc
);
438 We make a copy of the keys since at some point in the not so distant future
439 we will add support for "found" keys.
441 char ** memcached_stat_get_keys(memcached_st
*ptr
,
442 memcached_stat_st
*memc_stat
,
443 memcached_return_t
*error
)
446 size_t length
= sizeof(memcached_stat_keys
);
450 list
= libmemcached_malloc(ptr
, length
);
454 *error
= MEMCACHED_MEMORY_ALLOCATION_FAILURE
;
458 memcpy(list
, memcached_stat_keys
, sizeof(memcached_stat_keys
));
460 *error
= MEMCACHED_SUCCESS
;
465 void memcached_stat_free(memcached_st
*ptr
, memcached_stat_st
*memc_stat
)
467 if (memc_stat
== NULL
)
469 WATCHPOINT_ASSERT(0); /* Be polite, but when debugging catch this as an error */
475 libmemcached_free(memc_stat
->root
, memc_stat
);
479 libmemcached_free(ptr
, memc_stat
);