Example #1
0
  /// 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());
  }
Example #2
0
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;
}
Example #3
0
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;

}