6 static char *memcached_stat_keys
[] = {
19 "connection_structures",
33 static void set_data(memcached_stat_st
*stat
, char *key
, char *value
)
38 fprintf(stderr
, "Invalid key %s\n", key
);
40 else if (!strcmp("pid", key
))
42 stat
->pid
= strtol(value
, (char **)NULL
, 10);
44 else if (!strcmp("uptime", key
))
46 stat
->uptime
= strtol(value
, (char **)NULL
, 10);
48 else if (!strcmp("time", key
))
50 stat
->time
= strtol(value
, (char **)NULL
, 10);
52 else if (!strcmp("version", key
))
54 memcpy(stat
->version
, value
, strlen(value
));
55 stat
->version
[strlen(value
)]= 0;
57 else if (!strcmp("pointer_size", key
))
59 stat
->pointer_size
= strtol(value
, (char **)NULL
, 10);
61 else if (!strcmp("rusage_user", key
))
64 for (walk_ptr
= value
; (!ispunct(*walk_ptr
)); walk_ptr
++);
67 stat
->rusage_user_seconds
= strtol(value
, (char **)NULL
, 10);
68 stat
->rusage_user_microseconds
= strtol(walk_ptr
, (char **)NULL
, 10);
70 else if (!strcmp("rusage_system", key
))
73 for (walk_ptr
= value
; (!ispunct(*walk_ptr
)); walk_ptr
++);
76 stat
->rusage_system_seconds
= strtol(value
, (char **)NULL
, 10);
77 stat
->rusage_system_microseconds
= strtol(walk_ptr
, (char **)NULL
, 10);
79 else if (!strcmp("curr_items", key
))
81 stat
->curr_items
= strtol(value
, (char **)NULL
, 10);
83 else if (!strcmp("total_items", key
))
85 stat
->total_items
= strtol(value
, (char **)NULL
, 10);
87 else if (!strcmp("bytes_read", key
))
89 stat
->bytes_read
= strtoll(value
, (char **)NULL
, 10);
91 else if (!strcmp("bytes_written", key
))
93 stat
->bytes_written
= strtoll(value
, (char **)NULL
, 10);
95 else if (!strcmp("bytes", key
))
97 stat
->bytes
= strtoll(value
, (char **)NULL
, 10);
99 else if (!strcmp("curr_connections", key
))
101 stat
->curr_connections
= strtoll(value
, (char **)NULL
, 10);
103 else if (!strcmp("total_connections", key
))
105 stat
->total_connections
= strtoll(value
, (char **)NULL
, 10);
107 else if (!strcmp("connection_structures", key
))
109 stat
->connection_structures
= strtol(value
, (char **)NULL
, 10);
111 else if (!strcmp("cmd_get", key
))
113 stat
->cmd_get
= strtoll(value
, (char **)NULL
, 10);
115 else if (!strcmp("cmd_set", key
))
117 stat
->cmd_set
= strtoll(value
, (char **)NULL
, 10);
119 else if (!strcmp("get_hits", key
))
121 stat
->get_hits
= strtoll(value
, (char **)NULL
, 10);
123 else if (!strcmp("get_misses", key
))
125 stat
->get_misses
= (uint64_t)strtoll(value
, (char **)NULL
, 10);
127 else if (!strcmp("evictions", key
))
129 stat
->evictions
= (uint64_t)strtoll(value
, (char **)NULL
, 10);
131 else if (!strcmp("limit_maxbytes", key
))
133 stat
->limit_maxbytes
= strtoll(value
, (char **)NULL
, 10);
135 else if (!strcmp("threads", key
))
137 stat
->threads
= strtol(value
, (char **)NULL
, 10);
141 fprintf(stderr
, "Unknown key %s\n", key
);
145 char *memcached_stat_get_value(memcached_st
*ptr
, memcached_stat_st
*stat
,
146 const char *key
, memcached_return
*error
)
148 char buffer
[SMALL_STRING_LEN
];
152 *error
= MEMCACHED_SUCCESS
;
154 if (!memcmp("pid", key
, strlen("pid")))
155 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%u", stat
->pid
);
156 else if (!memcmp("uptime", key
, strlen("uptime")))
157 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%u", stat
->uptime
);
158 else if (!memcmp("time", key
, strlen("time")))
159 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%llu", (unsigned long long)stat
->time
);
160 else if (!memcmp("version", key
, strlen("version")))
161 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%s", stat
->version
);
162 else if (!memcmp("pointer_size", key
, strlen("pointer_size")))
163 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%u", stat
->pointer_size
);
164 else if (!memcmp("rusage_user", key
, strlen("rusage_user")))
165 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%u.%u", stat
->rusage_user_seconds
, stat
->rusage_user_microseconds
);
166 else if (!memcmp("rusage_system", key
, strlen("rusage_system")))
167 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%u.%u", stat
->rusage_system_seconds
, stat
->rusage_system_microseconds
);
168 else if (!memcmp("curr_items", key
, strlen("curr_items")))
169 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%u", stat
->curr_items
);
170 else if (!memcmp("total_items", key
, strlen("total_items")))
171 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%u", stat
->total_items
);
172 else if (!memcmp("bytes", key
, strlen("bytes")))
173 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%llu", (unsigned long long)stat
->bytes
);
174 else if (!memcmp("curr_connections", key
, strlen("curr_connections")))
175 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%u", stat
->curr_connections
);
176 else if (!memcmp("total_connections", key
, strlen("total_connections")))
177 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%u", stat
->total_connections
);
178 else if (!memcmp("connection_structures", key
, strlen("connection_structures")))
179 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%u", stat
->connection_structures
);
180 else if (!memcmp("cmd_get", key
, strlen("cmd_get")))
181 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%llu", (unsigned long long)stat
->cmd_get
);
182 else if (!memcmp("cmd_set", key
, strlen("cmd_set")))
183 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%llu", (unsigned long long)stat
->cmd_set
);
184 else if (!memcmp("get_hits", key
, strlen("get_hits")))
185 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%llu", (unsigned long long)stat
->get_hits
);
186 else if (!memcmp("get_misses", key
, strlen("get_misses")))
187 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%llu", (unsigned long long)stat
->get_misses
);
188 else if (!memcmp("evictions", key
, strlen("evictions")))
189 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%llu", (unsigned long long)stat
->evictions
);
190 else if (!memcmp("bytes_read", key
, strlen("bytes_read")))
191 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%llu", (unsigned long long)stat
->bytes_read
);
192 else if (!memcmp("bytes_written", key
, strlen("bytes_written")))
193 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%llu", (unsigned long long)stat
->bytes_written
);
194 else if (!memcmp("limit_maxbytes", key
, strlen("limit_maxbytes")))
195 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%llu", (unsigned long long)stat
->limit_maxbytes
);
196 else if (!memcmp("threads", key
, strlen("threads")))
197 length
= snprintf(buffer
, SMALL_STRING_LEN
,"%u", stat
->threads
);
200 *error
= MEMCACHED_NOTFOUND
;
204 if (ptr
->call_malloc
)
205 ret
= ptr
->call_malloc(ptr
, length
+ 1);
207 ret
= malloc(length
+ 1);
208 memcpy(ret
, buffer
, length
);
214 static memcached_return
binary_stats_fetch(memcached_st
*ptr
,
215 memcached_stat_st
*stat
,
217 unsigned int server_key
)
221 char buffer
[MEMCACHED_DEFAULT_COMMAND_SIZE
];
222 protocol_binary_request_stats request
= {.bytes
= {0}};
223 request
.message
.header
.request
.magic
= PROTOCOL_BINARY_REQ
;
224 request
.message
.header
.request
.opcode
= PROTOCOL_BINARY_CMD_STAT
;
225 request
.message
.header
.request
.datatype
= PROTOCOL_BINARY_RAW_BYTES
;
229 int len
= strlen(args
);
231 rc
= memcached_validate_key_length(len
, true);
232 unlikely (rc
!= MEMCACHED_SUCCESS
)
235 request
.message
.header
.request
.keylen
= htons((uint16_t)len
);
236 request
.message
.header
.request
.bodylen
= htonl(len
);
238 if ((memcached_do(&ptr
->hosts
[server_key
], request
.bytes
,
239 sizeof(request
.bytes
), 0) != MEMCACHED_SUCCESS
) ||
240 (memcached_io_write(&ptr
->hosts
[server_key
], args
, len
, 1) == -1))
242 memcached_io_reset(&ptr
->hosts
[server_key
]);
243 return MEMCACHED_WRITE_FAILURE
;
248 if (memcached_do(&ptr
->hosts
[server_key
], request
.bytes
,
249 sizeof(request
.bytes
), 1) != MEMCACHED_SUCCESS
)
251 memcached_io_reset(&ptr
->hosts
[server_key
]);
252 return MEMCACHED_WRITE_FAILURE
;
256 memcached_server_response_decrement(&ptr
->hosts
[server_key
]);
259 rc
= memcached_response(&ptr
->hosts
[server_key
], buffer
,
260 sizeof(buffer
), NULL
);
261 if (rc
== MEMCACHED_END
)
264 unlikely (rc
!= MEMCACHED_SUCCESS
)
266 memcached_io_reset(&ptr
->hosts
[server_key
]);
270 set_data(stat
, buffer
, buffer
+ strlen(buffer
) + 1);
273 /* shit... memcached_response will decrement the counter, so I need to
274 ** reset it.. todo: look at this and try to find a better solution.
276 ptr
->hosts
[server_key
].cursor_active
= 0;
278 return MEMCACHED_SUCCESS
;
281 static memcached_return
ascii_stats_fetch(memcached_st
*ptr
,
282 memcached_stat_st
*stat
,
284 unsigned int server_key
)
287 char buffer
[MEMCACHED_DEFAULT_COMMAND_SIZE
];
291 send_length
= snprintf(buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
,
292 "stats %s\r\n", args
);
294 send_length
= snprintf(buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
,
297 if (send_length
>= MEMCACHED_DEFAULT_COMMAND_SIZE
)
298 return MEMCACHED_WRITE_FAILURE
;
300 rc
= memcached_do(&ptr
->hosts
[server_key
], buffer
, send_length
, 1);
301 if (rc
!= MEMCACHED_SUCCESS
)
306 rc
= memcached_response(&ptr
->hosts
[server_key
], buffer
, MEMCACHED_DEFAULT_COMMAND_SIZE
, NULL
);
308 if (rc
== MEMCACHED_STAT
)
310 char *string_ptr
, *end_ptr
;
314 string_ptr
+= 5; /* Move past STAT */
315 for (end_ptr
= string_ptr
; isgraph(*end_ptr
); end_ptr
++);
317 key
[(size_t)(end_ptr
-string_ptr
)]= 0;
319 string_ptr
= end_ptr
+ 1;
320 for (end_ptr
= string_ptr
; !(isspace(*end_ptr
)); end_ptr
++);
322 value
[(size_t)(end_ptr
-string_ptr
)]= 0;
323 string_ptr
= end_ptr
+ 2;
324 set_data(stat
, key
, value
);
331 if (rc
== MEMCACHED_END
)
332 return MEMCACHED_SUCCESS
;
337 memcached_stat_st
*memcached_stat(memcached_st
*ptr
, char *args
, memcached_return
*error
)
341 memcached_stat_st
*stats
;
343 if (ptr
->flags
& MEM_USE_UDP
)
345 *error
= MEMCACHED_NOT_SUPPORTED
;
349 if (ptr
->call_malloc
)
350 stats
= (memcached_stat_st
*)ptr
->call_malloc(ptr
, sizeof(memcached_stat_st
)*(ptr
->number_of_hosts
));
352 stats
= (memcached_stat_st
*)malloc(sizeof(memcached_stat_st
)*(ptr
->number_of_hosts
));
356 *error
= MEMCACHED_MEMORY_ALLOCATION_FAILURE
;
359 memset(stats
, 0, sizeof(memcached_stat_st
)*(ptr
->number_of_hosts
));
361 rc
= MEMCACHED_SUCCESS
;
362 for (x
= 0; x
< ptr
->number_of_hosts
; x
++)
364 memcached_return temp_return
;
366 if (ptr
->flags
& MEM_BINARY_PROTOCOL
)
367 temp_return
= binary_stats_fetch(ptr
, stats
+ x
, args
, x
);
369 temp_return
= ascii_stats_fetch(ptr
, stats
+ x
, args
, x
);
371 if (temp_return
!= MEMCACHED_SUCCESS
)
372 rc
= MEMCACHED_SOME_ERRORS
;
379 memcached_return
memcached_stat_servername(memcached_stat_st
*stat
, char *args
,
380 char *hostname
, unsigned int port
)
385 memcached_create(&memc
);
387 memcached_server_add(&memc
, hostname
, port
);
389 if (memc
.flags
& MEM_BINARY_PROTOCOL
)
390 rc
= binary_stats_fetch(&memc
, stat
, args
, 0);
392 rc
= ascii_stats_fetch(&memc
, stat
, args
, 0);
394 memcached_free(&memc
);
400 We make a copy of the keys since at some point in the not so distant future
401 we will add support for "found" keys.
403 char ** memcached_stat_get_keys(memcached_st
*ptr
, memcached_stat_st
*stat
__attribute__((unused
)),
404 memcached_return
*error
)
407 size_t length
= sizeof(memcached_stat_keys
);
409 if (ptr
->call_malloc
)
410 list
= (char **)ptr
->call_malloc(ptr
, length
);
412 list
= (char **)malloc(length
);
416 *error
= MEMCACHED_MEMORY_ALLOCATION_FAILURE
;
419 memset(list
, 0, sizeof(memcached_stat_keys
));
421 memcpy(list
, memcached_stat_keys
, sizeof(memcached_stat_keys
));
423 *error
= MEMCACHED_SUCCESS
;
428 void memcached_stat_free(memcached_st
*ptr
, memcached_stat_st
*stat
)
432 WATCHPOINT_ASSERT(0); /* Be polite, but when debugging catch this as an error */
436 if (ptr
&& ptr
->call_free
)
437 ptr
->call_free(ptr
, stat
);