X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=clients%2Fmemstat.c;h=e6783b68c095c7a8de4b2f88309a2ce5f53aceed;hb=8270650b0a22bc6e8ad83aa39b05c5b6aff1faf8;hp=68c78e403858d06d8d20ef330d3e187a571cc76c;hpb=cc5be1b75fe90e8c73871f4bd135c9e7cf1d1984;p=m6w6%2Flibmemcached diff --git a/clients/memstat.c b/clients/memstat.c index 68c78e40..e6783b68 100644 --- a/clients/memstat.c +++ b/clients/memstat.c @@ -1,3 +1,4 @@ +#include "libmemcached/common.h" #include #include #include @@ -6,6 +7,7 @@ #include #include #include +#include #include @@ -17,7 +19,9 @@ /* Prototypes */ static void options_parse(int argc, char *argv[]); -static void print_server_listing(memcached_st *memc, memcached_stat_st *stat, +static void run_analyzer(memcached_st *memc, memcached_stat_st *memc_stat, + memcached_server_st *server_list); +static void print_server_listing(memcached_st *memc, memcached_stat_st *memc_stat, memcached_server_st *server_list); static void print_analysis_report(memcached_st *memc, memcached_analysis_st *report, @@ -27,16 +31,17 @@ static int opt_verbose= 0; static int opt_displayflag= 0; static int opt_analyze= 0; static char *opt_servers= NULL; +static char *analyze_mode= NULL; static struct option long_options[]= { - {"version", no_argument, NULL, OPT_VERSION}, - {"help", no_argument, NULL, OPT_HELP}, - {"verbose", no_argument, &opt_verbose, OPT_VERBOSE}, - {"debug", no_argument, &opt_verbose, OPT_DEBUG}, - {"servers", required_argument, NULL, OPT_SERVERS}, - {"flag", no_argument, &opt_displayflag, OPT_FLAG}, - {"analyze", no_argument, NULL, OPT_ANALYZE}, + {(OPTIONSTRING)"version", no_argument, NULL, OPT_VERSION}, + {(OPTIONSTRING)"help", no_argument, NULL, OPT_HELP}, + {(OPTIONSTRING)"verbose", no_argument, &opt_verbose, OPT_VERBOSE}, + {(OPTIONSTRING)"debug", no_argument, &opt_verbose, OPT_DEBUG}, + {(OPTIONSTRING)"servers", required_argument, NULL, OPT_SERVERS}, + {(OPTIONSTRING)"flag", no_argument, &opt_displayflag, OPT_FLAG}, + {(OPTIONSTRING)"analyze", optional_argument, NULL, OPT_ANALYZE}, {0, 0, 0, 0}, }; @@ -44,10 +49,9 @@ int main(int argc, char *argv[]) { memcached_return rc; memcached_st *memc; - memcached_stat_st *stat; + memcached_stat_st *memc_stat; memcached_server_st *servers; memcached_server_st *server_list; - memcached_analysis_st *report; options_parse(argc, argv); @@ -71,7 +75,7 @@ int main(int argc, char *argv[]) memcached_server_push(memc, servers); memcached_server_list_free(servers); - stat= memcached_stat(memc, NULL, &rc); + memc_stat= memcached_stat(memc, NULL, &rc); if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_SOME_ERRORS) { @@ -83,8 +87,27 @@ int main(int argc, char *argv[]) server_list= memcached_server_list(memc); if (opt_analyze) + run_analyzer(memc, memc_stat, server_list); + else + print_server_listing(memc, memc_stat, server_list); + + free(memc_stat); + free(opt_servers); + + memcached_free(memc); + + return 0; +} + +static void run_analyzer(memcached_st *memc, memcached_stat_st *memc_stat, + memcached_server_st *server_list) +{ + memcached_return rc; + + if (analyze_mode == NULL) { - report= memcached_analyze(memc, stat, &rc); + memcached_analysis_st *report; + report= memcached_analyze(memc, memc_stat, &rc); if (rc != MEMCACHED_SUCCESS || report == NULL) { printf("Failure to analyze servers (%s)\n", @@ -94,18 +117,105 @@ int main(int argc, char *argv[]) print_analysis_report(memc, report, server_list); free(report); } - else - print_server_listing(memc, stat, server_list); + else if (strcmp(analyze_mode, "latency") == 0) + { + memcached_st **servers; + uint32_t x, y, flags, server_count= memcached_server_count(memc); + uint32_t num_of_tests= 32; + const char *test_key= "libmemcached_test_key"; - free(stat); - free(opt_servers); + servers= malloc(sizeof(memcached_st*) * server_count); + if (!servers) + { + fprintf(stderr, "Failed to allocate memory\n"); + return; + } - memcached_free(memc); + for (x= 0; x < server_count; x++) + { + if((servers[x]= memcached_create(NULL)) == NULL) + { + fprintf(stderr, "Failed to memcached_create()\n"); + if (x > 0) + memcached_free(servers[0]); + x--; + for (; x > 0; x--) + memcached_free(servers[x]); + + free(servers); + return; + } + memcached_server_add(servers[x], + memcached_server_name(memc, server_list[x]), + memcached_server_port(memc, server_list[x])); + } - return 0; + printf("Network Latency Test:\n\n"); + struct timeval start_time, end_time; + long elapsed_time, slowest_time= 0, slowest_server= 0; + + for (x= 0; x < server_count; x++) + { + gettimeofday(&start_time, NULL); + for (y= 0; y < num_of_tests; y++) + { + size_t vlen; + char *val= memcached_get(servers[x], test_key, strlen(test_key), + &vlen, &flags, &rc); + if (rc != MEMCACHED_NOTFOUND && rc != MEMCACHED_SUCCESS) + break; + free(val); + } + gettimeofday(&end_time, NULL); + + elapsed_time= timedif(end_time, start_time); + elapsed_time /= (long)num_of_tests; + + if (elapsed_time > slowest_time) + { + slowest_server= (long)x; + slowest_time= elapsed_time; + } + + if (rc != MEMCACHED_NOTFOUND && rc != MEMCACHED_SUCCESS) + { + printf("\t %s (%d) => failed to reach the server\n", + memcached_server_name(memc, server_list[x]), + memcached_server_port(memc, server_list[x])); + } + else + { + printf("\t %s (%d) => %ld.%ld seconds\n", + memcached_server_name(memc, server_list[x]), + memcached_server_port(memc, server_list[x]), + elapsed_time / 1000, elapsed_time % 1000); + } + } + + if (server_count > 1 && slowest_time > 0) + { + printf("---\n"); + printf("Slowest Server: %s (%d) => %ld.%ld seconds\n", + memcached_server_name(memc, server_list[slowest_server]), + memcached_server_port(memc, server_list[slowest_server]), + slowest_time / 1000, slowest_time % 1000); + } + printf("\n"); + + for (x= 0; x < server_count; x++) + memcached_free(servers[x]); + + free(servers); + free(analyze_mode); + } + else + { + fprintf(stderr, "Invalid Analyzer Option provided\n"); + free(analyze_mode); + } } -static void print_server_listing(memcached_st *memc, memcached_stat_st *stat, +static void print_server_listing(memcached_st *memc, memcached_stat_st *memc_stat, memcached_server_st *server_list) { unsigned int x; @@ -117,14 +227,13 @@ static void print_server_listing(memcached_st *memc, memcached_stat_st *stat, char **list; char **ptr; - list= memcached_stat_get_keys(memc, &stat[x], &rc); + list= memcached_stat_get_keys(memc, &memc_stat[x], &rc); printf("Server: %s (%u)\n", memcached_server_name(memc, server_list[x]), memcached_server_port(memc, server_list[x])); for (ptr= list; *ptr; ptr++) { - memcached_return rc; - char *value= memcached_stat_get_value(memc, &stat[x], *ptr, &rc); + char *value= memcached_stat_get_value(memc, &memc_stat[x], *ptr, &rc); printf("\t %s: %s\n", *ptr, value); free(value); @@ -154,14 +263,14 @@ static void print_analysis_report(memcached_st *memc, } printf("\n"); - printf("\tNode with most memory consumption : %s:%u (%u bytes)\n", + printf("\tNode with most memory consumption : %s:%u (%llu bytes)\n", memcached_server_name(memc, server_list[report->most_consumed_server]), memcached_server_port(memc, server_list[report->most_consumed_server]), - report->most_used_bytes); - printf("\tNode with least free space : %s:%u (%u bytes remaining)\n", + (unsigned long long)report->most_used_bytes); + printf("\tNode with least free space : %s:%u (%llu bytes remaining)\n", memcached_server_name(memc, server_list[report->least_free_server]), memcached_server_port(memc, server_list[report->least_free_server]), - report->least_remaining_bytes); + (unsigned long long)report->least_remaining_bytes); printf("\tNode with longest uptime : %s:%u (%us)\n", memcached_server_name(memc, server_list[report->oldest_server]), memcached_server_port(memc, server_list[report->oldest_server]), @@ -205,6 +314,7 @@ static void options_parse(int argc, char *argv[]) break; case OPT_ANALYZE: /* --analyze or -a */ opt_analyze= OPT_ANALYZE; + analyze_mode= (optarg) ? strdup(optarg) : NULL; break; case '?': /* getopt_long already printed an error message. */