Added tests for consistent hash.
[awesomized/libmemcached] / lib / memcached_stats.c
1 /*
2 */
3
4 #include "common.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 "curr_items",
15 "total_items",
16 "bytes",
17 "curr_connections",
18 "total_connections",
19 "connection_structures",
20 "cmd_get",
21 "cmd_set",
22 "get_hits",
23 "get_misses",
24 "evictions",
25 "bytes_read",
26 "bytes_written",
27 "limit_maxbytes",
28 "threads",
29 NULL
30 };
31
32
33 static void set_data(memcached_stat_st *stat, char *key, char *value)
34 {
35 if (!memcmp("pid", key, strlen("pid")))
36 {
37 stat->pid= strtol(value, (char **)NULL, 10);
38 }
39 else if (!memcmp("uptime", key, strlen("uptime")))
40 {
41 stat->uptime= strtol(value, (char **)NULL, 10);
42 }
43 else if (!memcmp("time", key, strlen("time")))
44 {
45 stat->time= strtol(value, (char **)NULL, 10);
46 }
47 else if (!memcmp("version", key, strlen("version")))
48 {
49 memcpy(stat->version, value, strlen(value));
50 stat->version[strlen(value)]= 0;
51 }
52 else if (!memcmp("pointer_size", key, strlen("pointer_size")))
53 {
54 stat->pointer_size= strtol(value, (char **)NULL, 10);
55 }
56 else if (!memcmp("rusage_user", key, strlen("rusage_user")))
57 {
58 char *walk_ptr;
59 for (walk_ptr= value; (!ispunct(*walk_ptr)); walk_ptr++);
60 *walk_ptr= 0;
61 walk_ptr++;
62 stat->rusage_user_seconds= strtol(value, (char **)NULL, 10);
63 stat->rusage_user_microseconds= strtol(walk_ptr, (char **)NULL, 10);
64 }
65 else if (!memcmp("rusage_system", key, strlen("rusage_system")))
66 {
67 char *walk_ptr;
68 for (walk_ptr= value; (!ispunct(*walk_ptr)); walk_ptr++);
69 *walk_ptr= 0;
70 walk_ptr++;
71 stat->rusage_system_seconds= strtol(value, (char **)NULL, 10);
72 stat->rusage_system_microseconds= strtol(walk_ptr, (char **)NULL, 10);
73 }
74 else if (!memcmp("curr_items", key, strlen("curr_items")))
75 {
76 stat->curr_items= strtol(value, (char **)NULL, 10);
77 }
78 else if (!memcmp("total_items", key, strlen("total_items")))
79 {
80 stat->total_items= strtol(value, (char **)NULL, 10);
81 }
82 else if (!memcmp("bytes", key, strlen("bytes")))
83 {
84 //stat->bytes= strtoll(value, (char **)NULL, 10);
85 }
86 else if (!memcmp("curr_connections", key, strlen("curr_connections")))
87 {
88 //stat->curr_connections= strtoll(value, (char **)NULL, 10);
89 }
90 else if (!memcmp("total_connections", key, strlen("total_connections")))
91 {
92 //stat->total_connections= strtoll(value, (char **)NULL, 10);
93 }
94 else if (!memcmp("connection_structures", key, strlen("connection_structures")))
95 {
96 stat->connection_structures= strtol(value, (char **)NULL, 10);
97 }
98 else if (!memcmp("cmd_get", key, strlen("cmd_get")))
99 {
100 stat->cmd_get= strtoll(value, (char **)NULL, 10);
101 }
102 else if (!memcmp("cmd_set", key, strlen("cmd_set")))
103 {
104 stat->cmd_set= strtoll(value, (char **)NULL, 10);
105 }
106 else if (!memcmp("get_hits", key, strlen("get_hits")))
107 {
108 stat->get_hits= strtoll(value, (char **)NULL, 10);
109 }
110 else if (!memcmp("get_misses", key, strlen("get_misses")))
111 {
112 stat->get_misses= (uint64_t)strtoll(value, (char **)NULL, 10);
113 }
114 else if (!memcmp("evictions", key, strlen("evictions")))
115 {
116 stat->evictions= (uint64_t)strtoll(value, (char **)NULL, 10);
117 }
118 else if (!memcmp("bytes_read", key, strlen("bytes_read")))
119 {
120 stat->bytes_read= strtoll(value, (char **)NULL, 10);
121 }
122 else if (!memcmp("bytes_written", key, strlen("bytes_written")))
123 {
124 stat->bytes_written= strtoll(value, (char **)NULL, 10);
125 }
126 else if (!memcmp("limit_maxbytes", key, strlen("limit_maxbytes")))
127 {
128 stat->limit_maxbytes= strtol(value, (char **)NULL, 10);
129 }
130 else if (!memcmp("threads", key, strlen("threads")))
131 {
132 stat->threads= strtol(key, (char **)NULL, 10);
133 }
134 else
135 {
136 fprintf(stderr, "Unknown key %s\n", key);
137 }
138 }
139
140 char *memcached_stat_get_value(memcached_st *ptr, memcached_stat_st *stat,
141 char *key, memcached_return *error)
142 {
143 char buffer[SMALL_STRING_LEN];
144 *error= MEMCACHED_SUCCESS;
145
146 if (!memcmp("pid", key, strlen("pid")))
147 snprintf(buffer, SMALL_STRING_LEN,"%u", stat->pid);
148 else if (!memcmp("uptime", key, strlen("uptime")))
149 snprintf(buffer, SMALL_STRING_LEN,"%u", stat->uptime);
150 else if (!memcmp("time", key, strlen("time")))
151 snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->time);
152 else if (!memcmp("version", key, strlen("version")))
153 snprintf(buffer, SMALL_STRING_LEN,"%s", stat->version);
154 else if (!memcmp("pointer_size", key, strlen("pointer_size")))
155 snprintf(buffer, SMALL_STRING_LEN,"%u", stat->pointer_size);
156 else if (!memcmp("rusage_user", key, strlen("rusage_user")))
157 snprintf(buffer, SMALL_STRING_LEN,"%u.%u", stat->rusage_user_seconds, stat->rusage_user_microseconds);
158 else if (!memcmp("rusage_system", key, strlen("rusage_system")))
159 snprintf(buffer, SMALL_STRING_LEN,"%u.%u", stat->rusage_system_seconds, stat->rusage_system_microseconds);
160 else if (!memcmp("curr_items", key, strlen("curr_items")))
161 snprintf(buffer, SMALL_STRING_LEN,"%u", stat->curr_items);
162 else if (!memcmp("total_items", key, strlen("total_items")))
163 snprintf(buffer, SMALL_STRING_LEN,"%u", stat->total_items);
164 else if (!memcmp("bytes", key, strlen("bytes")))
165 snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->bytes);
166 else if (!memcmp("curr_connections", key, strlen("curr_connections")))
167 snprintf(buffer, SMALL_STRING_LEN,"%u", stat->curr_connections);
168 else if (!memcmp("total_connections", key, strlen("total_connections")))
169 snprintf(buffer, SMALL_STRING_LEN,"%u", stat->total_connections);
170 else if (!memcmp("connection_structures", key, strlen("connection_structures")))
171 snprintf(buffer, SMALL_STRING_LEN,"%u", stat->connection_structures);
172 else if (!memcmp("cmd_get", key, strlen("cmd_get")))
173 snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->cmd_get);
174 else if (!memcmp("cmd_set", key, strlen("cmd_set")))
175 snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->cmd_set);
176 else if (!memcmp("get_hits", key, strlen("get_hits")))
177 snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->get_hits);
178 else if (!memcmp("get_misses", key, strlen("get_misses")))
179 snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->get_misses);
180 else if (!memcmp("evictions", key, strlen("evictions")))
181 snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->evictions);
182 else if (!memcmp("bytes_read", key, strlen("bytes_read")))
183 snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->bytes_read);
184 else if (!memcmp("bytes_written", key, strlen("bytes_written")))
185 snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->bytes_written);
186 else if (!memcmp("limit_maxbytes", key, strlen("limit_maxbytes")))
187 snprintf(buffer, SMALL_STRING_LEN,"%u", stat->limit_maxbytes);
188 else if (!memcmp("threads", key, strlen("threads")))
189 snprintf(buffer, SMALL_STRING_LEN,"%u", stat->threads);
190 else
191 {
192 *error= MEMCACHED_NOTFOUND;
193 return NULL;
194 }
195
196 return strdup(buffer);
197 }
198
199 static memcached_return memcached_stats_fetch(memcached_st *ptr,
200 memcached_stat_st *stat,
201 char *args,
202 unsigned int server_key)
203 {
204 memcached_return rc;
205 char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
206 size_t send_length;
207
208 if (args)
209 send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
210 "stats %s\r\n", args);
211 else
212 send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
213 "stats\r\n");
214
215 if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE)
216 return MEMCACHED_WRITE_FAILURE;
217
218 rc= memcached_do(ptr, server_key, buffer, send_length, 1);
219 if (rc != MEMCACHED_SUCCESS)
220 goto error;
221
222 while (1)
223 {
224 rc= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, server_key);
225
226 if (rc == MEMCACHED_STAT)
227 {
228 char *string_ptr, *end_ptr;
229 char *key, *value;
230
231 string_ptr= buffer;
232 string_ptr+= 5; /* Move past STAT */
233 for (end_ptr= string_ptr; isgraph(*end_ptr); end_ptr++);
234 key= string_ptr;
235 key[(size_t)(end_ptr-string_ptr)]= 0;
236
237 string_ptr= end_ptr + 1;
238 for (end_ptr= string_ptr; !(isspace(*end_ptr)); end_ptr++);
239 value= string_ptr;
240 value[(size_t)(end_ptr-string_ptr)]= 0;
241 string_ptr= end_ptr + 2;
242 set_data(stat, key, value);
243 }
244 else
245 break;
246 }
247
248 error:
249 if (rc == MEMCACHED_END)
250 return MEMCACHED_SUCCESS;
251 else
252 return rc;
253 }
254
255 memcached_stat_st *memcached_stat(memcached_st *ptr, char *args, memcached_return *error)
256 {
257 unsigned int x;
258 memcached_return rc;
259 memcached_stat_st *stats;
260
261 stats= (memcached_stat_st *)malloc(sizeof(memcached_stat_st)*(ptr->number_of_hosts));
262 if (!stats)
263 {
264 *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
265 free(stats);
266 return NULL;
267 }
268 memset(stats, 0, sizeof(memcached_stat_st)*(ptr->number_of_hosts));
269
270 rc= MEMCACHED_SUCCESS;
271 for (x= 0; x < ptr->number_of_hosts; x++)
272 {
273 memcached_return temp_return;
274
275 temp_return= memcached_stats_fetch(ptr, stats + x, args, x);
276 if (temp_return != MEMCACHED_SUCCESS)
277 rc= MEMCACHED_SOME_ERRORS;
278 }
279
280 *error= rc;
281 return stats;
282 }
283
284 memcached_return memcached_stat_servername(memcached_stat_st *stat, char *args,
285 char *hostname, unsigned int port)
286 {
287 memcached_return rc;
288 memcached_st memc;
289
290 memcached_create(&memc);
291
292 memcached_server_add(&memc, hostname, port);
293
294 rc= memcached_stats_fetch(&memc, stat, args, 0);
295
296 memcached_free(&memc);
297
298 return rc;
299 }
300
301 /*
302 We make a copy of the keys since at some point in the not so distant future
303 we will add support for "found" keys.
304 */
305 char ** memcached_stat_get_keys(memcached_st *ptr, memcached_stat_st *stat,
306 memcached_return *error)
307 {
308 char **list;
309 size_t length= sizeof(memcached_stat_keys);
310 list= (char **)malloc(length);
311
312 if (!list)
313 {
314 *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
315 return NULL;
316 }
317 memset(list, 0, sizeof(memcached_stat_keys));
318
319 memcpy(list, memcached_stat_keys, sizeof(memcached_stat_keys));
320
321 *error= MEMCACHED_SUCCESS;
322
323 return list;
324 }
325
326 void memcached_stat_free(memcached_st *ptr, memcached_stat_st *stat)
327 {
328 free(stat);
329 }