/// Constructor: get a handle to the memcached connection pool of interest. /// /// For syntax of servers see /// http://docs.libmemcached.org/libmemcached_configuration.html#description, /// e.g., "localhost:11211". MemcachedStore::MemcachedStore(const std::list<std::string>& servers, ///< list of servers to be used int pool_size) ///< size of pool (used as init and max) { // Create the options string to connect to the servers. std::string options; for (std::list<std::string>::const_iterator i = servers.begin(); i != servers.end(); ++i) { options += "--SERVER=" + (*i) + " "; } options += "--BINARY-PROTOCOL"; options += " --POOL-MIN=" + to_string<int>(pool_size, std::dec) + " --POOL-MAX=" + to_string<int>(pool_size, std::dec); _pool = memcached_pool(options.c_str(), options.length()); }
bool ESPMemCached::init(const char * _options) { CriticalBlock block(cacheCrit); if (initialized) return initialized; if (!isEmptyString(_options)) options.set(_options); else options.set("--SERVER=127.0.0.1"); pool = memcached_pool(options.get(), options.length()); assertPool(); setPoolSettings(); connect(); if (connection) initialized = checkServersUp(); return initialized; }
int main ( int argc, char *argv[] ) { int rc; struct stat struct_stat; pthread_t pid; pthread_attr_t attr; int i, num_sources; uid_t gmetad_uid; mode_t rrd_umask; char * gmetad_username; struct passwd *pw; gmetad_config_t *c = &gmetad_config; apr_interval_time_t sleep_time; apr_time_t last_metadata; double random_sleep_factor; unsigned int rand_seed; rc = apr_initialize(); if (rc != APR_SUCCESS) { return -1; } /* create a memory pool. */ apr_pool_create(&global_context, NULL); /* Ignore SIGPIPE */ signal( SIGPIPE, SIG_IGN ); initialize_scoreboard(); /* Mark the time this gmetad started */ started = apr_time_now(); if (cmdline_parser(argc, argv, &args_info) != 0) err_quit("command-line parser error"); num_sources = number_of_datasources( args_info.conf_arg ); if(!num_sources) { err_quit("%s doesn't have any data sources specified", args_info.conf_arg); } memset(&root, 0, sizeof(root)); root.id = ROOT_NODE; /* Get the real number of data sources later */ sources = hash_create( num_sources + 10 ); if (! sources ) { err_quit("Unable to create sources hash\n"); } root.authority = hash_create( num_sources + 10 ); if (!root.authority) { err_quit("Unable to create root authority (our grids and clusters) hash\n"); } root.metric_summary = hash_create (DEFAULT_METRICSIZE); if (!root.metric_summary) { err_quit("Unable to create root summary hash"); } parse_config_file ( args_info.conf_arg ); /* If given, use command line directives over config file ones. */ if (args_info.debug_given) { c->debug_level = args_info.debug_arg; } debug_level = c->debug_level; set_debug_msg_level(debug_level); /* Setup our default authority pointer if the conf file hasnt yet. * Done in the style of hash node strings. */ if (!root.stringslen) { gethostname(hostname, HOSTNAMESZ); root.authority_ptr = 0; sprintf(root.strings, "http://%s/ganglia/", hostname); root.stringslen += strlen(root.strings) + 1; } rand_seed = apr_time_now() * (int)pthread_self(); for(i = 0; i < root.stringslen; rand_seed = rand_seed * root.strings[i++]); /* Debug level 1 is error output only, and no daemonizing. */ if (!debug_level) { rrd_umask = c->umask; daemon_init (argv[0], 0, rrd_umask); } if (args_info.pid_file_given) { update_pidfile (args_info.pid_file_arg); } /* The rrd_rootdir must be writable by the gmetad process */ if( c->should_setuid ) { if(! (pw = getpwnam(c->setuid_username))) { err_sys("Getpwnam error"); } gmetad_uid = pw->pw_uid; gmetad_username = c->setuid_username; } else { gmetad_uid = getuid(); if(! (pw = getpwuid(gmetad_uid))) { err_sys("Getpwnam error"); } gmetad_username = strdup(pw->pw_name); } debug_msg("Going to run as user %s", gmetad_username); if( c->should_setuid ) { become_a_nobody(c->setuid_username); } if( c->write_rrds ) { if( stat( c->rrd_rootdir, &struct_stat ) ) { err_sys("Please make sure that %s exists", c->rrd_rootdir); } if ( struct_stat.st_uid != gmetad_uid ) { err_quit("Please make sure that %s is owned by %s", c->rrd_rootdir, gmetad_username); } if (! (struct_stat.st_mode & S_IWUSR) ) { err_quit("Please make sure %s has WRITE permission for %s", gmetad_username, c->rrd_rootdir); } } if(debug_level) { fprintf(stderr,"Sources are ...\n"); hash_foreach( sources, print_sources, NULL); } #ifdef WITH_MEMCACHED if (c->memcached_parameters != NULL) { memcached_connection_pool = memcached_pool(c->memcached_parameters, strlen(c->memcached_parameters)); } #endif /* WITH_MEMCACHED */ server_socket = g_tcp_socket_server_new( c->xml_port ); if (server_socket == NULL) { err_quit("tcp_listen() on xml_port failed"); } debug_msg("xml listening on port %d", c->xml_port); interactive_socket = g_tcp_socket_server_new( c->interactive_port ); if (interactive_socket == NULL) { err_quit("tcp_listen() on interactive_port failed"); } debug_msg("interactive xml listening on port %d", c->interactive_port); /* Forward metrics to Graphite using carbon protocol */ if (c->carbon_server != NULL) { if (!strcmp(c->carbon_protocol, "udp")) { carbon_udp_socket = init_carbon_udp_socket (c->carbon_server, c->carbon_port); if (carbon_udp_socket == NULL) err_quit("carbon %s socket failed for %s:%d", c->carbon_protocol, c->carbon_server, c->carbon_port); } debug_msg("carbon forwarding ready to send via %s to %s:%d", c->carbon_protocol, c->carbon_server, c->carbon_port); } #ifdef WITH_RIEMANN if (c->riemann_server !=NULL) { if (!strcmp(c->riemann_protocol, "udp")) { riemann_udp_socket = init_riemann_udp_socket (c->riemann_server, c->riemann_port); if (riemann_udp_socket == NULL) err_quit("[riemann] %s socket failed for %s:%d", c->riemann_protocol, c->riemann_server, c->riemann_port); } else { err_quit("[riemann] TCP transport not supported yet."); } debug_msg("[riemann] ready to forward metrics via %s to %s:%d", c->riemann_protocol, c->riemann_server, c->riemann_port); } #endif /* WITH_RIEMANN */ /* initialize summary mutex */ root.sum_finished = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t)); pthread_mutex_init(root.sum_finished, NULL); pthread_attr_init( &attr ); pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED ); /* Spin off the non-interactive server threads. (Half as many as interactive). */ for (i=0; i < c->server_threads/2; i++) pthread_create(&pid, &attr, server_thread, (void*) 0); /* Spin off the interactive server threads. */ for (i=0; i < c->server_threads; i++) pthread_create(&pid, &attr, server_thread, (void*) 1); hash_foreach( sources, spin_off_the_data_threads, NULL ); /* A thread to cleanup old metrics and hosts */ pthread_create(&pid, &attr, cleanup_thread, (void *) NULL); debug_msg("cleanup thread has been started"); /* Meta data */ last_metadata = 0; for(;;) { /* Do at a random interval, between (shortest_step/2) +/- METADATA_SLEEP_RANDOMIZE percent */ random_sleep_factor = (1 + (METADATA_SLEEP_RANDOMIZE / 50.0) * ((rand_r(&rand_seed) - RAND_MAX/2)/(float)RAND_MAX)); sleep_time = random_sleep_factor * apr_time_from_sec(c->shortest_step) / 2; /* Make sure the sleep time is at least 1 second */ if(apr_time_sec(apr_time_now() + sleep_time) < (METADATA_MINIMUM_SLEEP + apr_time_sec(apr_time_now()))) sleep_time += apr_time_from_sec(METADATA_MINIMUM_SLEEP); apr_sleep(sleep_time); /* Need to be sure root is locked while doing summary */ pthread_mutex_lock(root.sum_finished); /* Flush the old values */ hash_foreach(root.metric_summary, zero_out_summary, NULL); root.hosts_up = 0; root.hosts_down = 0; /* Sum the new values */ hash_foreach(root.authority, do_root_summary, NULL ); /* summary completed */ pthread_mutex_unlock(root.sum_finished); /* Save them to RRD */ hash_foreach(root.metric_summary, write_root_summary, NULL); /* Remember our last run */ last_metadata = apr_time_now(); } apr_pool_destroy(global_context); apr_terminate(); return 0; }
static int mcd_load_config(void) { // initialize the timeout that we wait for a memcached pool operation to complete to.tv_sec = 0; to.tv_nsec = 500000; struct ast_config *cfg; struct ast_flags config_flags = { 0 }; if (!(cfg = ast_config_load(CONFIG_FILE_NAME, config_flags))) { ast_log(LOG_ERROR, "missing memcached resource config file '%s'\n", CONFIG_FILE_NAME); return 1; } else if (cfg == CONFIG_STATUS_FILEINVALID) { ast_log(LOG_ERROR, "memcached resource config file '" CONFIG_FILE_NAME "' invalid format.\n"); return 1; } // parse server names for memcached from the [general] section of the config file char mcd_config[2048]; mcd_config[0] = 0; struct ast_variable *serverentry = ast_variable_browse(cfg, "general"); for ( ; serverentry; serverentry = serverentry->next) { if (strcasecmp(serverentry->name, "server") == 0) { strcat(mcd_config, "--SERVER="); strcat(mcd_config, serverentry->value); strcat(mcd_config, " "); } } if (strstr(mcd_config, "--SERVER=") == 0) { ast_log(LOG_DEBUG, "Expecting memcache server on 127.0.0.1\n"); strcpy(mcd_config, "--SERVER=127.0.0.1 "); } ast_log(LOG_DEBUG, "res_memcached configured servers: '%s'\n", mcd_config); // strcat(mcd_config, "--SORT-HOSTS "); not a good idea: turns out that the documentation says: // "Enabling this will cause hosts that are added to be placed // in the host list in sorted order. This will defeat // consisten hashing." mcdttl = 0; const char *ttlvalue; if ((ttlvalue = ast_variable_retrieve(cfg, "general", "ttl"))) mcdttl = atoi(ttlvalue); ast_log(LOG_DEBUG, "default time to live for key-value entries set to %d seconds\n", mcdttl); use_binary_proto = 1; const char *proto_mode; if ((proto_mode = ast_variable_retrieve(cfg, "general", "binary_proto"))) use_binary_proto = ast_true(proto_mode); // if (use_binary_proto) // strcat(mcd_config, "--BINARY-PROTOCOL "); // else // ast_log(LOG_WARNING, "not using memcached binary protocol; MCDCOUNTER() function will be unavailable\n"); /* const char *hashmode; if ((hashmode = ast_variable_retrieve(cfg, "general", "hash"))) { strcat(mcd_config, "--HASH="); strcat(mcd_config, hashmode); strcat(mcd_config, " "); } */ const char *kp; if ((kp = ast_variable_retrieve(cfg, "general", "keyprefix"))) { strcat(mcd_config, "--NAMESPACE="); strcat(mcd_config, kp); strcat(mcd_config, " "); } // launch memcached client (pool of) mcd_config[strlen(mcd_config) - 1] = 0; if ((mcdpool = memcached_pool(mcd_config, strlen(mcd_config)))) ast_log(LOG_DEBUG, "res_memcached starting with config: '%s'\n", mcd_config); else ast_log(LOG_ERROR, "res_memcached failed to start with config: '%s'\n", mcd_config); ast_config_destroy(cfg); return 0; }