예제 #1
0
int 
main(int argc, char **argv)
{
  cerebro_err_init(argv[0]);
  cerebro_err_set_flags(CEREBRO_ERROR_STDERR | CEREBRO_ERROR_SYSLOG);

  cerebrod_config_setup(argc, argv);

#if CEREBRO_DEBUG
  if (!conf.debug)
    {
      cerebrod_daemon_init();
      cerebro_err_set_flags(CEREBRO_ERROR_SYSLOG);
    }
  else
    cerebro_err_set_flags(CEREBRO_ERROR_STDERR);
#else  /* !CEREBRO_DEBUG */
  cerebrod_daemon_init();
  cerebro_err_set_flags(CEREBRO_ERROR_SYSLOG);
#endif /* !CEREBRO_DEBUG */

  /* Call after daemonization, since daemonization closes currently
   * open fds 
   */
  openlog(argv[0], LOG_ODELAY | LOG_PID, LOG_DAEMON);

#if !WITH_CEREBROD_SPEAKER_ONLY

  /* Start metric server before the listener begins receiving data. */
  if (conf.metric_server)
    {
      pthread_t thread;
      pthread_attr_t attr;

      Pthread_attr_init(&attr);
      Pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
      Pthread_attr_setstacksize(&attr, CEREBROD_THREAD_STACKSIZE);
      Pthread_create(&thread, &attr, cerebrod_metric_server, NULL);
      Pthread_attr_destroy(&attr);

      /* Wait for initialization to complete */
      Pthread_mutex_lock(&metric_server_init_lock);
      while (!metric_server_init)
        Pthread_cond_wait(&metric_server_init_cond, &metric_server_init_lock);
      Pthread_mutex_unlock(&metric_server_init_lock);
    }

  /* Start listening server before speaker so that listener
   * can receive packets from a later created speaker
   */
  if (conf.listen)
    {
      int i;

      for (i = 0; i < conf.listen_threads; i++)
        {
          pthread_t thread;
          pthread_attr_t attr;

          Pthread_attr_init(&attr);
          Pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
          Pthread_attr_setstacksize(&attr, CEREBROD_THREAD_STACKSIZE);
          Pthread_create(&thread, &attr, cerebrod_listener, NULL);
          Pthread_attr_destroy(&attr);
        }

      /* Wait for initialization to complete */
      Pthread_mutex_lock(&listener_init_lock);
      while (!listener_init)
        Pthread_cond_wait(&listener_init_cond, &listener_init_lock);
      Pthread_mutex_unlock(&listener_init_lock);
    }

  /* Start all the event server, queue monitor, and node timeout
   * threads after the listener thread, since they use data created by
   * the listener thread.
   */
  if (conf.event_server)
    {
      pthread_t thread;
      pthread_attr_t attr;

      Pthread_attr_init(&attr);
      Pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
      Pthread_attr_setstacksize(&attr, CEREBROD_THREAD_STACKSIZE);
      Pthread_create(&thread, &attr, cerebrod_event_queue_monitor, NULL);
      Pthread_attr_destroy(&attr);

      /* Wait for initialization to complete */
      Pthread_mutex_lock(&event_queue_monitor_init_lock);
      while (!event_queue_monitor_init)
        Pthread_cond_wait(&event_queue_monitor_init_cond, &event_queue_monitor_init_lock);
      Pthread_mutex_unlock(&event_queue_monitor_init_lock);

      Pthread_attr_init(&attr);
      Pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
      Pthread_attr_setstacksize(&attr, CEREBROD_THREAD_STACKSIZE);
      Pthread_create(&thread, &attr, cerebrod_event_server, NULL);
      Pthread_attr_destroy(&attr);

      /* Wait for initialization to complete */
      Pthread_mutex_lock(&event_server_init_lock);
      while (!event_server_init)
        Pthread_cond_wait(&event_server_init_cond, &event_server_init_lock);
      Pthread_mutex_unlock(&event_server_init_lock);

      Pthread_attr_init(&attr);
      Pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
      Pthread_attr_setstacksize(&attr, CEREBROD_THREAD_STACKSIZE);
      Pthread_create(&thread, &attr, cerebrod_event_node_timeout_monitor, NULL);
      Pthread_attr_destroy(&attr);

      /* Wait for initialization to complete */
      Pthread_mutex_lock(&event_node_timeout_monitor_init_lock);
      while (!event_node_timeout_monitor_init)
        Pthread_cond_wait(&event_node_timeout_monitor_init_cond, 
                          &event_node_timeout_monitor_init_lock);
      Pthread_mutex_unlock(&event_node_timeout_monitor_init_lock);
    }

  /* Start metric controller - see comments at speaker below */ 
  if (conf.metric_controller)
    {
      pthread_t thread;
      pthread_attr_t attr;

      Pthread_attr_init(&attr);
      Pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
      Pthread_attr_setstacksize(&attr, CEREBROD_THREAD_STACKSIZE);
      Pthread_create(&thread, &attr, cerebrod_metric_controller, NULL);
      Pthread_attr_destroy(&attr);

      /* Wait for initialization to complete */
      Pthread_mutex_lock(&metric_controller_init_lock);
      while (!metric_controller_init)
        Pthread_cond_wait(&metric_controller_init_cond, 
                          &metric_controller_init_lock);
      Pthread_mutex_unlock(&metric_controller_init_lock);
    }

#endif /* !WITH_CEREBROD_SPEAKER_ONLY */

  /* Start speaker  
   *
   * It may make more logical sense to start the metric controller
   * after the speaker since metric data cannot be propogated until
   * after the speaker has finished being setup.  We run the speaker
   * last b/c it is the common case.  Most machines (particularly
   * compute nodes in a cluster) will only speak, and do nothing else.
   * By having the speaker last, it does not need to run in a thread.
   * We run it out of "main" instead to minimize memory usage by
   * not needing to start the speaker in a thread.
   */
  if (conf.speak)
    cerebrod_speaker(NULL);

  /* If speak is set, we do not reach this point */

  for (;;) 
    sleep(INT_MAX);

  return 0;			/* NOT REACHED */
}
예제 #2
0
/* 
 * _cmdline_parse
 *
 * parse all cmdline input
 */
static void
_cmdline_parse(int argc, char **argv) 
{
  const char *func = __FUNCTION__;
  char options[1024];
  char *ptr;
  int c;

#if HAVE_GETOPT_LONG
  struct option loptions[] = 
    {
      {"help",                  0, NULL, 'h'},
      {"version",               0, NULL, 'v'},
      {"hostname",              1, NULL, 'o'},
      {"port",                  1, NULL, 'p'},
      {"metric",                1, NULL, 'm'},
      {"metric-list",           0, NULL, 'l'},
      {"up-only",               0, NULL, 'U'},
      {"none-if-down",          0, NULL, 'D'},
      {"none-if-not-monitored", 0, NULL, 'N'},
      {"newline",               0, NULL, 'n'},
      {"hostrange",             0, NULL, 'q'},
      {"metric-received-time",  0, NULL, 't'},
      {"event",                 1, NULL, 'e'},
      {"event-list",            0, NULL, 'z'},
#if CEREBRO_DEBUG
      {"debug",                 0, NULL, 'd'},
#endif /* CEREBRO_DEBUG */
      {0, 0, 0, 0},
    };
#endif /* HAVE_GETOPT_LONG */

  assert(argv);

  strcpy(options, "hvo:p:ze:lm:UDNnqt");
#if CEREBRO_DEBUG
  strcat(options, "d");
#endif /* CEREBRO_DEBUG */
  
  /* turn off output messages printed by getopt_long */
  opterr = 0;
  
#if HAVE_GETOPT_LONG
  while ((c = getopt_long(argc, argv, options, loptions, NULL)) != -1)
#else
  while ((c = getopt(argc, argv, options)) != -1)
#endif
    {
    switch(c) 
      {
      case 'h':
        _usage();
      case 'v':
        _version();
      case 'o':
        hostname = optarg;
        if (cerebro_set_hostname(handle, hostname) < 0)
          {
            char *msg = cerebro_strerror(cerebro_errnum(handle));
            err_exit("%s: cerebro_set_hostname: %s", func, msg);
          }
        break;
      case 'p':
        port = strtol(optarg, &ptr, 10);
        if (ptr != (optarg + strlen(optarg)))
          err_exit("invalid port specified");
        if (cerebro_set_port(handle, port) < 0)
          {
            char *msg = cerebro_strerror(cerebro_errnum(handle));
            err_exit("%s: cerebro_set_port: %s", func, msg);
          }
        break;
      case 'm':
        metric_name = optarg;
        break;
      case 'l':
        metric_list_flag++;
        break;
      case 'U':
        _cerebro_set_flags(CEREBRO_METRIC_DATA_FLAGS_UP_ONLY);
        break;
      case 'D':
        _cerebro_set_flags(CEREBRO_METRIC_DATA_FLAGS_NONE_IF_DOWN);
        break;
      case 'N':
        _cerebro_set_flags(CEREBRO_METRIC_DATA_FLAGS_NONE_IF_NOT_MONITORED);
        break;
      case 'n':
        output_type = CEREBRO_STAT_NEWLINE;
        break;
      case 'q':
        output_type = CEREBRO_STAT_HOSTRANGE;
        break;
      case 't':
        metric_received_time_flag++;
        break;
      case 'e':
        event_name = optarg;
        break;
      case 'z':
        event_list_flag++;
        break;
#if CEREBRO_DEBUG
      case 'd':
        cerebro_err_set_flags(CEREBRO_ERROR_STDERR);
        break;
#endif /* CEREBRO_DEBUG */
      default:
      case '?':
        fprintf(stderr, "command line option error\n");
        _usage();
      }
    }

  if (((metric_list_flag ? 1 : 0)
       + (metric_name ? 1 : 0)
       + (event_name ? 1 : 0)
       + (event_list_flag ? 1 : 0)) > 1)
    err_exit("Specify one of --event-list, --event, --metric-list, and --metric options");
  
  if (!event_name && !event_list_flag && !metric_list_flag && !metric_name)
    _usage();
}
예제 #3
0
/* 
 * _cmdline_parse
 *
 * parse all cmdline input
 */
static void
_cmdline_parse(int argc, char **argv) 
{
  char options[1024];
  char *ptr;
  int c;

#if HAVE_GETOPT_LONG
  struct option loptions[] = 
    {
      {"help",              0, NULL, 'h'},
      {"version",           0, NULL, 'v'},
      {"metric",            1, NULL, 'm'},
      {"register",          0, NULL, 'r'},
      {"unregister",        0, NULL, 'u'},
      {"update",            0, NULL, 'p'},
      {"resend",            0, NULL, 's'},
      {"flush",             0, NULL, 'f'},
      {"metric-value-type", 1, NULL, 't'},
      {"metric-value",      1, NULL, 'l'},
      {"send-now",          0, NULL, 'N'},
#if CEREBRO_DEBUG
      {"debug",       0, NULL, 'd'},
#endif /* CEREBRO_DEBUG */
      {0, 0, 0, 0},
  };
#endif /* HAVE_GETOPT_LONG */

  assert(argv);

  strcpy(options, "hvm:rupsft:l:N");
#if CEREBRO_DEBUG
  strcat(options, "d");
#endif /* CEREBRO_DEBUG */

  /* turn off output messages printed by getopt_long */
  opterr = 0;

#if HAVE_GETOPT_LONG
  while ((c = getopt_long(argc, argv, options, loptions, NULL)) != -1)
#else
  while ((c = getopt(argc, argv, options)) != -1)
#endif
    {
    switch(c) 
      {
      case 'h':
        _usage();
      case 'v':
        _version();
      case 'm':
        metric_name = optarg;
        break;
      case 'r':
        operation = CEREBRO_ADMIN_REGISTER;
        break;
      case 'u':
        operation = CEREBRO_ADMIN_UNREGISTER;
        break;
      case 'p':
        operation = CEREBRO_ADMIN_UPDATE;
        break;
      case 's':
        operation = CEREBRO_ADMIN_RESEND;
        break;
      case 'f':
        operation = CEREBRO_ADMIN_FLUSH;
        break;
      case 't':
        metric_value_type = strtol(optarg, &ptr, 10);
        if ((ptr != (optarg + strlen(optarg)))
            || !(metric_value_type >= CEREBRO_DATA_VALUE_TYPE_NONE
                 && metric_value_type <= CEREBRO_DATA_VALUE_TYPE_U_INT64))
          err_exit("invalid metric value type specified");
        break;
      case 'l':
        metric_value = optarg;
        break;
      case 'N':
        _cerebro_set_flags(CEREBRO_METRIC_CONTROL_FLAGS_SEND_NOW);
        break;
#if CEREBRO_DEBUG
      case 'd':
        cerebro_err_set_flags(CEREBRO_ERROR_STDERR);
        break;
#endif /* CEREBRO_DEBUG */
      default:
      case '?':
        fprintf(stderr, "command line option error\n");
        _usage();
      }
    }

  if (!metric_name || operation < 0)
    _usage();

  if (metric_value_type != CEREBRO_DATA_VALUE_TYPE_NONE && !metric_value)
    err_exit("invalid metric value specified");

  if (metric_value_type == CEREBRO_DATA_VALUE_TYPE_NONE)
    {
      metric_value_len = 0;
      metric_value_ptr = NULL;
    }
  else if (metric_value_type == CEREBRO_DATA_VALUE_TYPE_INT32)
    {
      metric_value_int32 = (int32_t)strtol(metric_value, &ptr, 10);
      if (ptr != (metric_value + strlen(metric_value)))
        err_exit("invalid metric value specified");
      metric_value_len = sizeof(int32_t);
      metric_value_ptr = &metric_value_int32;
    }
  else if (metric_value_type == CEREBRO_DATA_VALUE_TYPE_U_INT32)
    {
      metric_value_u_int32 = (u_int32_t)strtoul(metric_value, &ptr, 10);
      if (ptr != (metric_value + strlen(metric_value)))
        err_exit("invalid metric value specified");
      metric_value_len = sizeof(u_int32_t);
      metric_value_ptr = &metric_value_u_int32;
    }
  else if (metric_value_type == CEREBRO_DATA_VALUE_TYPE_FLOAT)
    {
      metric_value_float = (float)strtod(metric_value, &ptr);
      if (ptr != (metric_value + strlen(metric_value)))
        err_exit("invalid metric value specified");
      metric_value_len = sizeof(float);
      metric_value_ptr = &metric_value_float;
    }
  else if (metric_value_type == CEREBRO_DATA_VALUE_TYPE_DOUBLE)
    {
      metric_value_double = strtod(metric_value, &ptr);
      if (ptr != (metric_value + strlen(metric_value)))
        err_exit("invalid metric value specified");
      metric_value_len = sizeof(double);
      metric_value_ptr = &metric_value_double;
    }
  else if (metric_value_type == CEREBRO_DATA_VALUE_TYPE_STRING)
    {
      metric_value_string = metric_value;
      metric_value_len = strlen(metric_value_string);
      if (metric_value_len > CEREBRO_MAX_DATA_STRING_LEN)
        err_exit("string metric value too long");
      metric_value_ptr = metric_value_string;
    }
  else if (metric_value_type == CEREBRO_DATA_VALUE_TYPE_INT64)
    {
      metric_value_int64 = (int64_t)strtoll(metric_value, &ptr, 10);
      if (ptr != (metric_value + strlen(metric_value)))
        err_exit("invalid metric value specified");
      metric_value_len = sizeof(int64_t);
      metric_value_ptr = &metric_value_int64;
    }
  else if (metric_value_type == CEREBRO_DATA_VALUE_TYPE_U_INT64)
    {
      metric_value_u_int64 = (u_int64_t)strtoull(metric_value, &ptr, 10);
      if (ptr != (metric_value + strlen(metric_value)))
        err_exit("invalid metric value specified");
      metric_value_len = sizeof(u_int64_t);
      metric_value_ptr = &metric_value_u_int64;
    }
}