Started to abstract out the stats calls.
[m6w6/libmemcached] / lib / memcached_stats.c
1 /*
2 */
3
4 #include <memcached.h>
5
6 static char *memcached_stat_keys[] = {
7 "pid",
8 "uptime",
9 "time",
10 "version",
11 "pointer_size",
12 "rusage_user",
13 "rusage_system",
14 "rusage_user_seconds",
15 "rusage_user_microseconds",
16 "rusage_system_seconds",
17 "rusage_system_microseconds",
18 "curr_items",
19 "total_items",
20 "bytes",
21 "curr_connections",
22 "total_connections",
23 "connection_structures",
24 "cmd_get",
25 "cmd_set",
26 "get_hits",
27 "get_misses",
28 "evictions",
29 "bytes_read",
30 "bytes_written",
31 "limit_maxbytes",
32 "threads",
33 NULL
34 };
35
36
37 static void set_data(memcached_stat_st *stat, char *key, char *value)
38 {
39 if (!memcmp("pid", key, strlen("pid")))
40 {
41 stat->pid= strtol(value, (char **)NULL, 10);
42 }
43 else if (!memcmp("uptime", key, strlen("uptime")))
44 {
45 stat->uptime= strtol(value, (char **)NULL, 10);
46 }
47 else if (!memcmp("time", key, strlen("time")))
48 {
49 stat->time= strtoll(value, (char **)NULL, 10);
50 }
51 else if (!memcmp("version", key, strlen("version")))
52 {
53 memcpy(stat->version, value, 8);
54 }
55 else if (!memcmp("pointer_size", key, strlen("pointer_size")))
56 {
57 stat->pointer_size= strtoll(value, (char **)NULL, 10);
58 }
59 else if (!memcmp("rusage_user", key, strlen("rusage_user")))
60 {
61 stat->rusage_user= strtoll(value, (char **)NULL, 10);
62 }
63 else if (!memcmp("rusage_system", key, strlen("rusage_system")))
64 {
65 stat->rusage_system= strtoll(value, (char **)NULL, 10);
66 }
67 else if (!memcmp("rusage_user_seconds", key, strlen("rusage_user_seconds")))
68 {
69 stat->rusage_user_seconds= strtoll(value, (char **)NULL, 10);
70 }
71 else if (!memcmp("rusage_user_microseconds", key, strlen("rusage_user_microseconds")))
72 {
73 stat->rusage_user_microseconds= strtoll(value, (char **)NULL, 10);
74 }
75 else if (!memcmp("rusage_system_seconds", key, strlen("rusage_system_seconds")))
76 {
77 stat->rusage_system_seconds= strtoll(value, (char **)NULL, 10);
78 }
79 else if (!memcmp("rusage_system_microseconds", key, strlen("rusage_system_microseconds")))
80 {
81 stat->rusage_system_microseconds= strtoll(value, (char **)NULL, 10);
82 }
83 else if (!memcmp("curr_items", key, strlen("curr_items")))
84 {
85 stat->curr_items= strtoll(value, (char **)NULL, 10);
86 }
87 else if (!memcmp("total_items", key, strlen("total_items")))
88 {
89 stat->total_items= strtoll(value, (char **)NULL, 10);
90 }
91 else if (!memcmp("bytes", key, strlen("bytes")))
92 {
93 stat->bytes= strtoll(value, (char **)NULL, 10);
94 }
95 else if (!memcmp("curr_connections", key, strlen("curr_connections")))
96 {
97 stat->curr_connections= strtoll(value, (char **)NULL, 10);
98 }
99 else if (!memcmp("total_connections", key, strlen("total_connections")))
100 {
101 stat->total_connections= strtoll(value, (char **)NULL, 10);
102 }
103 else if (!memcmp("connection_structures", key, strlen("connection_structures")))
104 {
105 stat->connection_structures= strtoll(value, (char **)NULL, 10);
106 }
107 else if (!memcmp("cmd_get", key, strlen("cmd_get")))
108 {
109 stat->cmd_get= strtoll(value, (char **)NULL, 10);
110 }
111 else if (!memcmp("cmd_set", key, strlen("cmd_set")))
112 {
113 stat->cmd_set= strtoll(value, (char **)NULL, 10);
114 }
115 else if (!memcmp("get_hits", key, strlen("get_hits")))
116 {
117 stat->get_hits= strtoll(value, (char **)NULL, 10);
118 }
119 else if (!memcmp("get_misses", key, strlen("get_misses")))
120 {
121 stat->get_misses= strtoll(value, (char **)NULL, 10);
122 }
123 else if (!memcmp("evictions", key, strlen("evictions")))
124 {
125 stat->evictions= strtoll(value, (char **)NULL, 10);
126 }
127 else if (!memcmp("bytes_read", key, strlen("bytes_read")))
128 {
129 stat->bytes_read= strtoll(value, (char **)NULL, 10);
130 }
131 else if (!memcmp("bytes_written", key, strlen("bytes_written")))
132 {
133 stat->bytes_written= strtoll(value, (char **)NULL, 10);
134 }
135 else if (!memcmp("limit_maxbytes", key, strlen("limit_maxbytes")))
136 {
137 stat->limit_maxbytes= strtoll(value, (char **)NULL, 10);
138 }
139 else if (!memcmp("threads", key, strlen("threads")))
140 {
141 stat->threads= strtol(key, (char **)NULL, 10);
142 }
143 else
144 {
145 fprintf(stderr, "Unknown key %s\n", key);
146 }
147 }
148
149 memcached_return memcached_stat_get_value(memcached_stat_st *stat, char *key,
150 char *value, size_t value_length)
151 {
152 memcached_return rc;
153
154 rc= MEMCACHED_SUCCESS;
155
156 if (!memcmp("pid", key, strlen("pid")))
157 {
158 snprintf(value, value_length,"%u", stat->pid);
159 }
160 else if (!memcmp("uptime", key, strlen("uptime")))
161 {
162 snprintf(value, value_length,"%u", stat->uptime);
163 }
164 else if (!memcmp("time", key, strlen("time")))
165 {
166 snprintf(value, value_length,"%llu", (unsigned long long)stat->time);
167 }
168 else if (!memcmp("version", key, strlen("version")))
169 {
170 snprintf(value, value_length,"%s", stat->version);
171 }
172 else if (!memcmp("pointer_size", key, strlen("pointer_size")))
173 {
174 snprintf(value, value_length,"%u", stat->pointer_size);
175 }
176 else if (!memcmp("rusage_user", key, strlen("rusage_user")))
177 {
178 snprintf(value, value_length,"%u", stat->rusage_user);
179 }
180 else if (!memcmp("rusage_system", key, strlen("rusage_system")))
181 {
182 snprintf(value, value_length,"%u", stat->rusage_system);
183 }
184 else if (!memcmp("rusage_user_seconds", key, strlen("rusage_user_seconds")))
185 {
186 snprintf(value, value_length,"%u", stat->rusage_user_seconds);
187 }
188 else if (!memcmp("rusage_user_microseconds", key, strlen("rusage_user_microseconds")))
189 {
190 snprintf(value, value_length,"%u", stat->rusage_user_microseconds);
191 }
192 else if (!memcmp("rusage_system_seconds", key, strlen("rusage_system_seconds")))
193 {
194 snprintf(value, value_length,"%u", stat->rusage_system_seconds);
195 }
196 else if (!memcmp("rusage_system_microseconds", key, strlen("rusage_system_microseconds")))
197 {
198 snprintf(value, value_length,"%u", stat->rusage_system_microseconds);
199 }
200 else if (!memcmp("curr_items", key, strlen("curr_items")))
201 {
202 snprintf(value, value_length,"%u", stat->curr_items);
203 }
204 else if (!memcmp("total_items", key, strlen("total_items")))
205 {
206 snprintf(value, value_length,"%u", stat->total_items);
207 }
208 else if (!memcmp("bytes", key, strlen("bytes")))
209 {
210 snprintf(value, value_length,"%llu", stat->bytes);
211 }
212 else if (!memcmp("curr_connections", key, strlen("curr_connections")))
213 {
214 snprintf(value, value_length,"%u", stat->curr_connections);
215 }
216 else if (!memcmp("total_connections", key, strlen("total_connections")))
217 {
218 snprintf(value, value_length,"%u", stat->total_connections);
219 }
220 else if (!memcmp("connection_structures", key, strlen("connection_structures")))
221 {
222 snprintf(value, value_length,"%u", stat->connection_structures);
223 }
224 else if (!memcmp("cmd_get", key, strlen("cmd_get")))
225 {
226 snprintf(value, value_length,"%llu", stat->cmd_get);
227 }
228 else if (!memcmp("cmd_set", key, strlen("cmd_set")))
229 {
230 snprintf(value, value_length,"%llu", stat->cmd_set);
231 }
232 else if (!memcmp("get_hits", key, strlen("get_hits")))
233 {
234 snprintf(value, value_length,"%llu", stat->get_hits);
235 }
236 else if (!memcmp("get_misses", key, strlen("get_misses")))
237 {
238 snprintf(value, value_length,"%llu", stat->get_misses);
239 }
240 else if (!memcmp("evictions", key, strlen("evictions")))
241 {
242 snprintf(value, value_length,"%llu", stat->evictions);
243 }
244 else if (!memcmp("bytes_read", key, strlen("bytes_read")))
245 {
246 snprintf(value, value_length,"%llu", stat->bytes_read);
247 }
248 else if (!memcmp("bytes_written", key, strlen("bytes_written")))
249 {
250 snprintf(value, value_length,"%llu", stat->bytes_written);
251 }
252 else if (!memcmp("limit_maxbytes", key, strlen("limit_maxbytes")))
253 {
254 snprintf(value, value_length,"%u", stat->limit_maxbytes);
255 }
256 else if (!memcmp("threads", key, strlen("threads")))
257 {
258 snprintf(value, value_length,"%u", stat->threads);
259 }
260 else
261 {
262 rc= MEMCACHED_NOTFOUND;
263 }
264
265 return rc;
266 }
267
268 static memcached_return memcached_stats_fetch(memcached_st *ptr,
269 memcached_stat_st *stat,
270 char *args,
271 unsigned int server_key)
272 {
273 memcached_return rc;
274 char buffer[HUGE_STRING_LEN];
275 size_t send_length, sent_length;
276
277 rc= memcached_connect(ptr);
278
279 if (rc != MEMCACHED_SUCCESS)
280 return rc;
281
282 if (args)
283 send_length= snprintf(buffer, HUGE_STRING_LEN,
284 "stats %s\r\n", args);
285 else
286 send_length= snprintf(buffer, HUGE_STRING_LEN,
287 "stats\r\n");
288
289 if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE)
290 return MEMCACHED_WRITE_FAILURE;
291
292 sent_length= write(ptr->hosts[server_key].fd, buffer, send_length);
293
294 if (sent_length == -1 || sent_length != send_length)
295 return MEMCACHED_WRITE_FAILURE;
296
297 rc= memcached_response(ptr, buffer, HUGE_STRING_LEN, 0);
298
299 if (rc == MEMCACHED_SUCCESS)
300 {
301 char *string_ptr, *end_ptr;
302 char *key, *value;
303
304 string_ptr= buffer;
305 while (1)
306 {
307 if (memcmp(string_ptr, "STAT ", 5))
308 break;
309 string_ptr+= 5;
310 for (end_ptr= string_ptr; *end_ptr != ' '; end_ptr++);
311 key= string_ptr;
312 key[(size_t)(end_ptr-string_ptr)]= 0;
313
314 string_ptr= end_ptr + 1;
315 for (end_ptr= string_ptr; *end_ptr != '\r'; end_ptr++);
316 value= string_ptr;
317 value[(size_t)(end_ptr-string_ptr)]= 0;
318 string_ptr= end_ptr + 2;
319 set_data(stat, key, value);
320 }
321 }
322
323 return rc;
324 }
325
326 memcached_stat_st *memcached_stat(memcached_st *ptr, char *args, memcached_return *error)
327 {
328 unsigned int x;
329 memcached_return rc;
330 memcached_stat_st *stats;
331 rc= memcached_connect(ptr);
332
333 if (rc != MEMCACHED_SUCCESS)
334 {
335 *error= rc;
336 return NULL;
337 }
338
339 stats= (memcached_stat_st *)malloc(sizeof(memcached_st)*(ptr->number_of_hosts+1));
340 if (stats)
341 {
342 *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
343 return NULL;
344 }
345 memset(stats, 0, sizeof(memcached_st)*(ptr->number_of_hosts+1));
346
347 for (x= 0; x < ptr->number_of_hosts; x++)
348 {
349 rc= memcached_stats_fetch(ptr, stats+x, args, x);
350 if (rc != MEMCACHED_SUCCESS)
351 rc= MEMCACHED_SOME_ERRORS;
352 }
353
354 *error= x == 0 ? MEMCACHED_SUCCESS : rc;
355 return stats;
356 }
357
358 memcached_return memcached_stat_hostname(memcached_stat_st *stat, char *args,
359 char *hostname, unsigned int port)
360 {
361 memcached_return rc;
362 memcached_st memc;
363
364 memcached_init(&memc);
365
366 memcached_server_add(&memc, hostname, port);
367
368 rc= memcached_connect(&memc);
369
370 if (rc != MEMCACHED_SUCCESS)
371 return rc;
372
373 rc= memcached_stats_fetch(&memc, stat, args, 0);
374
375 memcached_deinit(&memc);
376
377 return rc;
378 }
379
380 /*
381 We make a copy of the keys since at some point in the not so distant future
382 we will add support for "found" keys.
383 */
384 char ** memcached_stat_get_keys(memcached_stat_st *stat, memcached_return *error)
385 {
386 char **list= (char **)malloc(sizeof(memcached_stat_keys));
387
388 memcpy(list, memcached_stat_keys, sizeof(memcached_stat_keys));
389
390 return list;
391 }