16
34
#define PROGRAM_DESCRIPTION "Output the state of a memcached cluster."
19
void options_parse(int argc, char *argv[]);
37
static void options_parse(int argc, char *argv[]);
38
static void run_analyzer(memcached_st *memc, memcached_stat_st *memc_stat);
39
static void print_analysis_report(memcached_st *memc,
40
memcached_analysis_st *report);
21
static int opt_verbose= 0;
22
static int opt_displayflag= 0;
42
static bool opt_binary= false;
43
static bool opt_verbose= false;
44
static bool opt_server_version= false;
45
static bool opt_analyze= false;
23
46
static char *opt_servers= NULL;
47
static char *stat_args= NULL;
48
static char *analyze_mode= NULL;
50
static struct option long_options[]=
52
{(OPTIONSTRING)"args", required_argument, NULL, OPT_STAT_ARGS},
53
{(OPTIONSTRING)"version", no_argument, NULL, OPT_VERSION},
54
{(OPTIONSTRING)"help", no_argument, NULL, OPT_HELP},
55
{(OPTIONSTRING)"quiet", no_argument, NULL, OPT_QUIET},
56
{(OPTIONSTRING)"verbose", no_argument, NULL, OPT_VERBOSE},
57
{(OPTIONSTRING)"binary", no_argument, NULL, OPT_BINARY},
58
{(OPTIONSTRING)"debug", no_argument, NULL, OPT_DEBUG},
59
{(OPTIONSTRING)"server-version", no_argument, NULL, OPT_SERVER_VERSION},
60
{(OPTIONSTRING)"servers", required_argument, NULL, OPT_SERVERS},
61
{(OPTIONSTRING)"analyze", optional_argument, NULL, OPT_ANALYZE},
66
static memcached_return_t stat_printer(memcached_server_instance_st instance,
67
const char *key, size_t key_length,
68
const char *value, size_t value_length,
71
static memcached_server_instance_st last= NULL;
76
printf("Server: %s (%u)\n", memcached_server_name(instance),
77
(uint32_t)memcached_server_port(instance));
81
printf("\t %.*s: %.*s\n", (int)key_length, key, (int)value_length, value);
83
return MEMCACHED_SUCCESS;
86
static memcached_return_t server_print_callback(const memcached_st *,
87
const memcached_server_st *instance,
90
std::cerr << memcached_server_name(instance) << ":" << memcached_server_port(instance) <<
91
" " << int(instance->major_version) <<
92
"." << int(instance->minor_version) <<
93
"." << int(instance->micro_version) << std::endl;
95
return MEMCACHED_SUCCESS;
25
98
int main(int argc, char *argv[])
30
memcached_stat_st *stat;
31
memcached_server_st *servers;
32
memcached_server_st *server_list;
34
100
options_parse(argc, argv);
101
initialize_sockets();
103
if (opt_servers == false)
40
106
if ((temp= getenv("MEMCACHED_SERVERS")))
41
108
opt_servers= strdup(temp);
44
fprintf(stderr, "No Servers provided\n");
112
std::cerr << "No Servers provided" << std::endl;
49
memc= memcached_create(NULL);
51
servers= memcached_servers_parse(opt_servers);
52
memcached_server_push(memc, servers);
117
memcached_st *memc= memcached_create(NULL);
118
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, opt_binary);
120
memcached_server_st *servers= memcached_servers_parse(opt_servers);
123
memcached_return_t rc= memcached_server_push(memc, servers);
53
124
memcached_server_list_free(servers);
55
stat= memcached_stat(memc, NULL, &rc);
57
if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_SOME_ERRORS)
126
if (rc != MEMCACHED_SUCCESS and rc != MEMCACHED_SOME_ERRORS)
59
128
printf("Failure to communicate with servers (%s)\n",
60
memcached_strerror(memc, rc));
64
server_list= memcached_server_list(memc);
66
printf("Listing %u Server\n\n", memcached_server_count(memc));
67
for (x= 0; x < memcached_server_count(memc); x++)
72
list= memcached_stat_get_keys(memc, &stat[x], &rc);
74
printf("Server: %s (%u)\n", memcached_server_name(memc, server_list[x]),
75
memcached_server_port(memc, server_list[x]));
76
for (ptr= list; *ptr; ptr++)
79
char *value= memcached_stat_get_value(memc, &stat[x], *ptr, &rc);
81
printf("\t %s: %s\n", *ptr, value);
129
memcached_strerror(memc, rc));
133
if (opt_server_version)
135
if (memcached_failed(memcached_version(memc)))
137
std::cerr << "Unable to obtain server version";
141
memcached_server_fn callbacks[1];
142
callbacks[0]= server_print_callback;
143
memcached_server_cursor(memc, callbacks, NULL, 1);
145
else if (opt_analyze)
147
memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
149
if (memc_stat == NULL)
154
run_analyzer(memc, memc_stat);
156
memcached_stat_free(memc, memc_stat);
160
rc= memcached_stat_execute(memc, stat_args, stat_printer, NULL);
163
memcached_free(memc);
165
return rc == MEMCACHED_SUCCESS ? EXIT_SUCCESS: EXIT_FAILURE;
168
static void run_analyzer(memcached_st *memc, memcached_stat_st *memc_stat)
170
memcached_return_t rc;
172
if (analyze_mode == NULL)
174
memcached_analysis_st *report;
175
report= memcached_analyze(memc, memc_stat, &rc);
176
if (rc != MEMCACHED_SUCCESS || report == NULL)
178
printf("Failure to analyze servers (%s)\n",
179
memcached_strerror(memc, rc));
182
print_analysis_report(memc, report);
185
else if (strcmp(analyze_mode, "latency") == 0)
187
uint32_t flags, server_count= memcached_server_count(memc);
188
uint32_t num_of_tests= 32;
189
const char *test_key= "libmemcached_test_key";
191
memcached_st **servers;
192
servers= static_cast<memcached_st**>(malloc(sizeof(memcached_st*) * server_count));
195
fprintf(stderr, "Failed to allocate memory\n");
199
for (uint32_t x= 0; x < server_count; x++)
201
memcached_server_instance_st instance=
202
memcached_server_instance_by_position(memc, x);
204
if ((servers[x]= memcached_create(NULL)) == NULL)
206
fprintf(stderr, "Failed to memcached_create()\n");
208
memcached_free(servers[0]);
212
memcached_free(servers[x]);
217
memcached_server_add(servers[x],
218
memcached_server_name(instance),
219
memcached_server_port(instance));
222
printf("Network Latency Test:\n\n");
223
struct timeval start_time, end_time;
224
uint32_t slowest_server= 0;
225
long elapsed_time, slowest_time= 0;
227
for (uint32_t x= 0; x < server_count; x++)
229
memcached_server_instance_st instance=
230
memcached_server_instance_by_position(memc, x);
231
gettimeofday(&start_time, NULL);
233
for (uint32_t y= 0; y < num_of_tests; y++)
236
char *val= memcached_get(servers[x], test_key, strlen(test_key),
238
if (rc != MEMCACHED_NOTFOUND && rc != MEMCACHED_SUCCESS)
242
gettimeofday(&end_time, NULL);
244
elapsed_time= (long) timedif(end_time, start_time);
245
elapsed_time /= (long) num_of_tests;
247
if (elapsed_time > slowest_time)
250
slowest_time= elapsed_time;
253
if (rc != MEMCACHED_NOTFOUND && rc != MEMCACHED_SUCCESS)
255
printf("\t %s (%d) => failed to reach the server\n",
256
memcached_server_name(instance),
257
memcached_server_port(instance));
261
printf("\t %s (%d) => %ld.%ld seconds\n",
262
memcached_server_name(instance),
263
memcached_server_port(instance),
264
elapsed_time / 1000, elapsed_time % 1000);
268
if (server_count > 1 && slowest_time > 0)
270
memcached_server_instance_st slowest=
271
memcached_server_instance_by_position(memc, slowest_server);
274
printf("Slowest Server: %s (%d) => %ld.%ld seconds\n",
275
memcached_server_name(slowest),
276
memcached_server_port(slowest),
277
slowest_time / 1000, slowest_time % 1000);
97
void options_parse(int argc, char *argv[])
281
for (uint32_t x= 0; x < server_count; x++)
282
memcached_free(servers[x]);
289
fprintf(stderr, "Invalid Analyzer Option provided\n");
294
static void print_analysis_report(memcached_st *memc,
295
memcached_analysis_st *report)
298
uint32_t server_count= memcached_server_count(memc);
299
memcached_server_instance_st most_consumed_server= memcached_server_instance_by_position(memc, report->most_consumed_server);
300
memcached_server_instance_st least_free_server= memcached_server_instance_by_position(memc, report->least_free_server);
301
memcached_server_instance_st oldest_server= memcached_server_instance_by_position(memc, report->oldest_server);
303
printf("Memcached Cluster Analysis Report\n\n");
305
printf("\tNumber of Servers Analyzed : %u\n", server_count);
306
printf("\tAverage Item Size (incl/overhead) : %u bytes\n",
307
report->average_item_size);
309
if (server_count == 1)
311
printf("\nFor a detailed report, you must supply multiple servers.\n");
316
printf("\tNode with most memory consumption : %s:%u (%llu bytes)\n",
317
memcached_server_name(most_consumed_server),
318
(uint32_t)memcached_server_port(most_consumed_server),
319
(unsigned long long)report->most_used_bytes);
320
printf("\tNode with least free space : %s:%u (%llu bytes remaining)\n",
321
memcached_server_name(least_free_server),
322
(uint32_t)memcached_server_port(least_free_server),
323
(unsigned long long)report->least_remaining_bytes);
324
printf("\tNode with longest uptime : %s:%u (%us)\n",
325
memcached_server_name(oldest_server),
326
(uint32_t)memcached_server_port(oldest_server),
327
report->longest_uptime);
328
printf("\tPool-wide Hit Ratio : %1.f%%\n", report->pool_hit_ratio);
332
static void options_parse(int argc, char *argv[])
99
334
memcached_programs_help_st help_options[]=
104
static struct option long_options[]=
106
{"version", no_argument, NULL, OPT_VERSION},
107
{"help", no_argument, NULL, OPT_HELP},
108
{"verbose", no_argument, &opt_verbose, OPT_VERBOSE},
109
{"debug", no_argument, &opt_verbose, OPT_DEBUG},
110
{"servers", required_argument, NULL, OPT_SERVERS},
111
{"flag", no_argument, &opt_displayflag, OPT_FLAG},
115
339
int option_index= 0;
341
bool opt_version= false;
342
bool opt_help= false;
120
option_rv= getopt_long(argc, argv, "Vhvds:", long_options, &option_index);
121
if (option_rv == -1) break;
345
int option_rv= getopt_long(argc, argv, "Vhvds:a", long_options, &option_index);
122
350
switch (option_rv)
126
355
case OPT_VERBOSE: /* --verbose or -v */
127
opt_verbose = OPT_VERBOSE;
129
359
case OPT_DEBUG: /* --debug or -d */
130
opt_verbose = OPT_DEBUG;
367
case OPT_SERVER_VERSION:
368
opt_server_version= true;
132
371
case OPT_VERSION: /* --version or -V */
133
version_command(PROGRAM_NAME);
135
375
case OPT_HELP: /* --help or -h */
136
help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, help_options);
138
379
case OPT_SERVERS: /* --servers or -s */
139
380
opt_servers= strdup(optarg);
384
stat_args= strdup(optarg);
387
case OPT_ANALYZE: /* --analyze or -a */
388
opt_analyze= OPT_ANALYZE;
389
analyze_mode= (optarg) ? strdup(optarg) : NULL;
142
397
/* getopt_long already printed an error message. */