Esempio n. 1
0
static void *statsd_network_thread (void *args) /* {{{ */
{
  statsd_config_t *conf = args;
  fds_poll_t fds;
  int status;
  size_t i;

  memset(&fds, 0, sizeof(fds_poll_t));

  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);

  status = statsd_network_init (conf, &fds);
  if (status != 0)
  {
    ERROR ("statsd plugin: Unable to open listening sockets.");
    pthread_exit ((void *) 0);
  }

  pthread_cleanup_push(statsd_network_release, &fds);

  pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);

  while (1) {

    status = poll (fds.fds, (nfds_t) fds.fds_num, /* timeout = */ -1);

    if (status < 0) {
      char errbuf[1024] = {0};

      if (EAGAIN == errno)
        continue;

      if (EINTR == errno) {
        DEBUG("statsd plugin: poll(2) has been interrupted");
        break;
      }

      ERROR ("statsd plugin: poll(2) failed: %s",
             sstrerror (errno, errbuf, sizeof (errbuf)));
      break;
    }

    DEBUG("statsd plugin: ohh some moving in the sockets");

    for (i = 0; i < fds.fds_num; i++) {
      if ((fds.fds[i].revents & (POLLIN | POLLPRI)) == 0)
        continue;

      statsd_network_read(conf, fds.fds[i].fd);
      fds.fds[i].revents = 0;
    }
    pthread_testcancel();
  } /* wait for pthread_cancel */

  pthread_cleanup_pop(1);

  return ((void *) 0);
} /* }}} void *statsd_network_thread */
Esempio n. 2
0
static void *statsd_network_thread (void *args) /* {{{ */
{
  struct pollfd *fds = NULL;
  size_t fds_num = 0;
  int status;
  size_t i;

  status = statsd_network_init (&fds, &fds_num);
  if (status != 0)
  {
    ERROR ("statsd plugin: Unable to open listening sockets.");
    pthread_exit ((void *) 0);
  }

  while (!network_thread_shutdown)
  {
    status = poll (fds, (nfds_t) fds_num, /* timeout = */ -1);
    if (status < 0)
    {
      char errbuf[1024];

      if ((errno == EINTR) || (errno == EAGAIN))
        continue;

      ERROR ("statsd plugin: poll(2) failed: %s",
          sstrerror (errno, errbuf, sizeof (errbuf)));
      break;
    }

    for (i = 0; i < fds_num; i++)
    {
      if ((fds[i].revents & (POLLIN | POLLPRI)) == 0)
        continue;

      statsd_network_read (fds[i].fd);
      fds[i].revents = 0;
    }
  } /* while (!network_thread_shutdown) */

  /* Clean up */
  for (i = 0; i < fds_num; i++)
    close (fds[i].fd);
  sfree (fds);

  return ((void *) 0);
} /* }}} void *statsd_network_thread */
Esempio n. 3
0
static int statsd_network_init(struct pollfd **ret_fds, /* {{{ */
                               size_t *ret_fds_num) {
  struct pollfd *fds = NULL;
  size_t fds_num = 0;

  struct addrinfo *ai_list;
  int status;

  char const *node = (conf_node != NULL) ? conf_node : STATSD_DEFAULT_NODE;
  char const *service =
      (conf_service != NULL) ? conf_service : STATSD_DEFAULT_SERVICE;

  struct addrinfo ai_hints = {.ai_family = AF_UNSPEC,
                              .ai_flags = AI_PASSIVE | AI_ADDRCONFIG,
                              .ai_socktype = SOCK_DGRAM};

  status = getaddrinfo(node, service, &ai_hints, &ai_list);
  if (status != 0) {
    ERROR("statsd plugin: getaddrinfo (\"%s\", \"%s\") failed: %s", node,
          service, gai_strerror(status));
    return status;
  }

  for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL;
       ai_ptr = ai_ptr->ai_next) {
    int fd;
    struct pollfd *tmp;

    char dbg_node[NI_MAXHOST];
    char dbg_service[NI_MAXSERV];

    fd = socket(ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol);
    if (fd < 0) {
      ERROR("statsd plugin: socket(2) failed: %s", STRERRNO);
      continue;
    }

    getnameinfo(ai_ptr->ai_addr, ai_ptr->ai_addrlen, dbg_node, sizeof(dbg_node),
                dbg_service, sizeof(dbg_service),
                NI_DGRAM | NI_NUMERICHOST | NI_NUMERICSERV);
    DEBUG("statsd plugin: Trying to bind to [%s]:%s ...", dbg_node,
          dbg_service);

    status = bind(fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
    if (status != 0) {
      ERROR("statsd plugin: bind(2) failed: %s", STRERRNO);
      close(fd);
      continue;
    }

    tmp = realloc(fds, sizeof(*fds) * (fds_num + 1));
    if (tmp == NULL) {
      ERROR("statsd plugin: realloc failed.");
      close(fd);
      continue;
    }
    fds = tmp;
    tmp = fds + fds_num;
    fds_num++;

    memset(tmp, 0, sizeof(*tmp));
    tmp->fd = fd;
    tmp->events = POLLIN | POLLPRI;
  }

  freeaddrinfo(ai_list);

  if (fds_num == 0) {
    ERROR("statsd plugin: Unable to create listening socket for [%s]:%s.",
          (node != NULL) ? node : "::", service);
    return ENOENT;
  }

  *ret_fds = fds;
  *ret_fds_num = fds_num;
  return 0;
} /* }}} int statsd_network_init */

static void *statsd_network_thread(void *args) /* {{{ */
{
  struct pollfd *fds = NULL;
  size_t fds_num = 0;
  int status;

  status = statsd_network_init(&fds, &fds_num);
  if (status != 0) {
    ERROR("statsd plugin: Unable to open listening sockets.");
    pthread_exit((void *)0);
  }

  while (!network_thread_shutdown) {
    status = poll(fds, (nfds_t)fds_num, /* timeout = */ -1);
    if (status < 0) {

      if ((errno == EINTR) || (errno == EAGAIN))
        continue;

      ERROR("statsd plugin: poll(2) failed: %s", STRERRNO);
      break;
    }

    for (size_t i = 0; i < fds_num; i++) {
      if ((fds[i].revents & (POLLIN | POLLPRI)) == 0)
        continue;

      statsd_network_read(fds[i].fd);
      fds[i].revents = 0;
    }
  } /* while (!network_thread_shutdown) */

  /* Clean up */
  for (size_t i = 0; i < fds_num; i++)
    close(fds[i].fd);
  sfree(fds);

  return (void *)0;
} /* }}} void *statsd_network_thread */

static int statsd_config_timer_percentile(oconfig_item_t *ci) /* {{{ */
{
  double percent = NAN;
  double *tmp;
  int status;

  status = cf_util_get_double(ci, &percent);
  if (status != 0)
    return status;

  if ((percent <= 0.0) || (percent >= 100)) {
    ERROR("statsd plugin: The value for \"%s\" must be between 0 and 100, "
          "exclusively.",
          ci->key);
    return ERANGE;
  }

  tmp =
      realloc(conf_timer_percentile,
              sizeof(*conf_timer_percentile) * (conf_timer_percentile_num + 1));
  if (tmp == NULL) {
    ERROR("statsd plugin: realloc failed.");
    return ENOMEM;
  }
  conf_timer_percentile = tmp;
  conf_timer_percentile[conf_timer_percentile_num] = percent;
  conf_timer_percentile_num++;

  return 0;
} /* }}} int statsd_config_timer_percentile */