Cleanup of stats code (fixed byte alignment issue)
[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_seconds", key, strlen("rusage_user_seconds")))
157 snprintf(buffer, SMALL_STRING_LEN,"%u", stat->rusage_user_seconds);
158 else if (!memcmp("rusage_user_microseconds", key, strlen("rusage_user_microseconds")))
159 snprintf(buffer, SMALL_STRING_LEN,"%u", stat->rusage_user_microseconds);
160 else if (!memcmp("rusage_system_seconds", key, strlen("rusage_system_seconds")))
161 snprintf(buffer, SMALL_STRING_LEN,"%u", stat->rusage_system_seconds);
162 else if (!memcmp("rusage_system_microseconds", key, strlen("rusage_system_microseconds")))
163 snprintf(buffer, SMALL_STRING_LEN,"%u", stat->rusage_system_microseconds);
164 else if (!memcmp("curr_items", key, strlen("curr_items")))
165 snprintf(buffer, SMALL_STRING_LEN,"%u", stat->curr_items);
166 else if (!memcmp("total_items", key, strlen("total_items")))
167 snprintf(buffer, SMALL_STRING_LEN,"%u", stat->total_items);
168 else if (!memcmp("bytes", key, strlen("bytes")))
169 snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->bytes);
170 else if (!memcmp("curr_connections", key, strlen("curr_connections")))
171 snprintf(buffer, SMALL_STRING_LEN,"%u", stat->curr_connections);
172 else if (!memcmp("total_connections", key, strlen("total_connections")))
173 snprintf(buffer, SMALL_STRING_LEN,"%u", stat->total_connections);
174 else if (!memcmp("connection_structures", key, strlen("connection_structures")))
175 snprintf(buffer, SMALL_STRING_LEN,"%u", stat->connection_structures);
176 else if (!memcmp("cmd_get", key, strlen("cmd_get")))
177 snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->cmd_get);
178 else if (!memcmp("cmd_set", key, strlen("cmd_set")))
179 snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->cmd_set);
180 else if (!memcmp("get_hits", key, strlen("get_hits")))
181 snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->get_hits);
182 else if (!memcmp("get_misses", key, strlen("get_misses")))
183 snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->get_misses);
184 else if (!memcmp("evictions", key, strlen("evictions")))
185 snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->evictions);
186 else if (!memcmp("bytes_read", key, strlen("bytes_read")))
187 snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->bytes_read);
188 else if (!memcmp("bytes_written", key, strlen("bytes_written")))
189 snprintf(buffer, SMALL_STRING_LEN,"%llu", (unsigned long long)stat->bytes_written);
190 else if (!memcmp("limit_maxbytes", key, strlen("limit_maxbytes")))
191 snprintf(buffer, SMALL_STRING_LEN,"%u", stat->limit_maxbytes);
192 else if (!memcmp("threads", key, strlen("threads")))
193 snprintf(buffer, SMALL_STRING_LEN,"%u", stat->threads);
194 else
195 {
196 *error= MEMCACHED_NOTFOUND;
197 return NULL;
198 }
199
200 return strdup(buffer);
201 }
202
203 static memcached_return memcached_stats_fetch(memcached_st *ptr,
204 memcached_stat_st *stat,
205 char *args,
206 unsigned int server_key)
207 {
208 memcached_return rc;
209 char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
210 size_t send_length;
211
212 if (args)
213 send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
214 "stats %s\r\n", args);
215 else
216 send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
217 "stats\r\n");
218
219 if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE)
220 return MEMCACHED_WRITE_FAILURE;
221
222 rc= memcached_do(ptr, server_key, buffer, send_length, 1);
223 if (rc != MEMCACHED_SUCCESS)
224 goto error;
225
226 while (1)
227 {
228 rc= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, server_key);
229
230 if (rc == MEMCACHED_STAT)
231 {
232 char *string_ptr, *end_ptr;
233 char *key, *value;
234
235 string_ptr= buffer;
236 string_ptr+= 5; /* Move past STAT */
237 for (end_ptr= string_ptr; isgraph(*end_ptr); end_ptr++);
238 key= string_ptr;
239 key[(size_t)(end_ptr-string_ptr)]= 0;
240
241 string_ptr= end_ptr + 1;
242 for (end_ptr= string_ptr; !(isspace(*end_ptr)); end_ptr++);
243 value= string_ptr;
244 value[(size_t)(end_ptr-string_ptr)]= 0;
245 string_ptr= end_ptr + 2;
246 set_data(stat, key, value);
247 }
248 else
249 break;
250 }
251
252 error:
253 if (rc == MEMCACHED_END)
254 return MEMCACHED_SUCCESS;
255 else
256 return rc;
257 }
258
259 memcached_stat_st *memcached_stat(memcached_st *ptr, char *args, memcached_return *error)
260 {
261 unsigned int x;
262 memcached_return rc;
263 memcached_stat_st *stats;
264
265 stats= (memcached_stat_st *)malloc(sizeof(memcached_stat_st)*(ptr->number_of_hosts));
266 if (!stats)
267 {
268 *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
269 free(stats);
270 return NULL;
271 }
272 memset(stats, 0, sizeof(memcached_st)*(ptr->number_of_hosts));
273
274 rc= MEMCACHED_SUCCESS;
275 for (x= 0; x < ptr->number_of_hosts; x++)
276 {
277 memcached_return temp_return;
278
279 temp_return= memcached_stats_fetch(ptr, stats + x, args, x);
280 if (temp_return != MEMCACHED_SUCCESS)
281 rc= MEMCACHED_SOME_ERRORS;
282 }
283
284 *error= rc;
285 return stats;
286 }
287
288 memcached_return memcached_stat_servername(memcached_stat_st *stat, char *args,
289 char *hostname, unsigned int port)
290 {
291 memcached_return rc;
292 memcached_st memc;
293
294 memcached_create(&memc);
295
296 memcached_server_add(&memc, hostname, port);
297
298 rc= memcached_stats_fetch(&memc, stat, args, 0);
299
300 memcached_free(&memc);
301
302 return rc;
303 }
304
305 /*
306 We make a copy of the keys since at some point in the not so distant future
307 we will add support for "found" keys.
308 */
309 char ** memcached_stat_get_keys(memcached_st *ptr, memcached_stat_st *stat,
310 memcached_return *error)
311 {
312 char **list;
313 size_t length= sizeof(memcached_stat_keys);
314 list= (char **)malloc(length);
315
316 if (!list)
317 {
318 *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
319 return NULL;
320 }
321 memset(list, 0, sizeof(memcached_stat_keys));
322
323 memcpy(list, memcached_stat_keys, sizeof(memcached_stat_keys));
324
325 *error= MEMCACHED_SUCCESS;
326
327 return list;
328 }
329
330 void memcached_stat_free(memcached_st *ptr, memcached_stat_st *stat)
331 {
332 free(stat);
333 }