Пример #1
0
static int latency_config_add_percentile(latency_config_t *conf,
                                         oconfig_item_t *ci) {
  double percent;
  int status = cf_util_get_double(ci, &percent);
  if (status != 0)
    return status;

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

  double *tmp = realloc(conf->percentile,
                        sizeof(*conf->percentile) * (conf->percentile_num + 1));
  if (tmp == NULL) {
    P_ERROR("realloc failed.");
    return ENOMEM;
  }
  conf->percentile = tmp;
  conf->percentile[conf->percentile_num] = percent;
  conf->percentile_num++;

  return 0;
} /* int latency_config_add_percentile */
Пример #2
0
static int statsd_config_timer_percentile (statsd_config_t *conf, 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 (double) * (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 */
Пример #3
0
/*
 * Configuration
 * =============
 * The following approximately two hundred functions are used to handle the
 * configuration and fill the threshold list.
 * {{{ */
static int ut_config_type(const threshold_t *th_orig, oconfig_item_t *ci) {
  threshold_t th;
  int status = 0;

  if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
    WARNING("threshold values: The `Type' block needs exactly one string "
            "argument.");
    return -1;
  }

  if (ci->children_num < 1) {
    WARNING("threshold values: The `Type' block needs at least one option.");
    return -1;
  }

  memcpy(&th, th_orig, sizeof(th));
  sstrncpy(th.type, ci->values[0].value.string, sizeof(th.type));

  th.warning_min = NAN;
  th.warning_max = NAN;
  th.failure_min = NAN;
  th.failure_max = NAN;
  th.hits = 0;
  th.hysteresis = 0;
  th.flags = UT_FLAG_INTERESTING; /* interesting by default */

  for (int i = 0; i < ci->children_num; i++) {
    oconfig_item_t *option = ci->children + i;

    if (strcasecmp("Instance", option->key) == 0)
      status = cf_util_get_string_buffer(option, th.type_instance,
                                         sizeof(th.type_instance));
    else if (strcasecmp("DataSource", option->key) == 0)
      status = cf_util_get_string_buffer(option, th.data_source,
                                         sizeof(th.data_source));
    else if (strcasecmp("WarningMax", option->key) == 0)
      status = cf_util_get_double(option, &th.warning_max);
    else if (strcasecmp("FailureMax", option->key) == 0)
      status = cf_util_get_double(option, &th.failure_max);
    else if (strcasecmp("WarningMin", option->key) == 0)
      status = cf_util_get_double(option, &th.warning_min);
    else if (strcasecmp("FailureMin", option->key) == 0)
      status = cf_util_get_double(option, &th.failure_min);
    else if (strcasecmp("Interesting", option->key) == 0)
      status = cf_util_get_flag(option, &th.flags, UT_FLAG_INTERESTING);
    else if (strcasecmp("Invert", option->key) == 0)
      status = cf_util_get_flag(option, &th.flags, UT_FLAG_INVERT);
    else if (strcasecmp("Persist", option->key) == 0)
      status = cf_util_get_flag(option, &th.flags, UT_FLAG_PERSIST);
    else if (strcasecmp("PersistOK", option->key) == 0)
      status = cf_util_get_flag(option, &th.flags, UT_FLAG_PERSIST_OK);
    else if (strcasecmp("Percentage", option->key) == 0)
      status = cf_util_get_flag(option, &th.flags, UT_FLAG_PERCENTAGE);
    else if (strcasecmp("Hits", option->key) == 0)
      status = cf_util_get_int(option, &th.hits);
    else if (strcasecmp("Hysteresis", option->key) == 0)
      status = cf_util_get_double(option, &th.hysteresis);
    else {
      WARNING("threshold values: Option `%s' not allowed inside a `Type' "
              "block.",
              option->key);
      status = -1;
    }

    if (status != 0)
      break;
  }

  if (status == 0) {
    status = ut_threshold_add(&th);
  }

  return status;
} /* int ut_config_type */
Пример #4
0
static int riemann_config_node(oconfig_item_t *ci) /* {{{ */
{
    struct riemann_host	*host = NULL;
    int			 status = 0;
    int			 i;
    oconfig_item_t		*child;
    char			 callback_name[DATA_MAX_NAME_LEN];
    user_data_t		 ud;

    if ((host = calloc(1, sizeof (*host))) == NULL) {
        ERROR ("write_riemann plugin: calloc failed.");
        return ENOMEM;
    }
    pthread_mutex_init (&host->lock, NULL);
    host->reference_count = 1;
    host->node = NULL;
    host->service = NULL;
    host->store_rates = 1;
    host->always_append_ds = 0;
    host->use_tcp = 0;
    host->ttl_factor = RIEMANN_TTL_FACTOR;

    status = cf_util_get_string (ci, &host->name);
    if (status != 0) {
        WARNING("write_riemann plugin: Required host name is missing.");
        riemann_free (host);
        return -1;
    }

    for (i = 0; i < ci->children_num; i++) {
        /*
         * The code here could be simplified but makes room
         * for easy adding of new options later on.
         */
        child = &ci->children[i];
        status = 0;

        if (strcasecmp ("Host", child->key) == 0) {
            status = cf_util_get_string (child, &host->node);
            if (status != 0)
                break;
        } else if (strcasecmp ("Port", child->key) == 0) {
            status = cf_util_get_service (child, &host->service);
            if (status != 0) {
                ERROR ("write_riemann plugin: Invalid argument "
                       "configured for the \"Port\" "
                       "option.");
                break;
            }
        } else if (strcasecmp ("Protocol", child->key) == 0) {
            char tmp[16];
            status = cf_util_get_string_buffer (child,
                                                tmp, sizeof (tmp));
            if (status != 0)
            {
                ERROR ("write_riemann plugin: cf_util_get_"
                       "string_buffer failed with "
                       "status %i.", status);
                break;
            }

            if (strcasecmp ("UDP", tmp) == 0)
                host->use_tcp = 0;
            else if (strcasecmp ("TCP", tmp) == 0)
                host->use_tcp = 1;
            else
                WARNING ("write_riemann plugin: The value "
                         "\"%s\" is not valid for the "
                         "\"Protocol\" option. Use "
                         "either \"UDP\" or \"TCP\".",
                         tmp);
        } else if (strcasecmp ("StoreRates", child->key) == 0) {
            status = cf_util_get_boolean (child, &host->store_rates);
            if (status != 0)
                break;
        } else if (strcasecmp ("AlwaysAppendDS", child->key) == 0) {
            status = cf_util_get_boolean (child,
                                          &host->always_append_ds);
            if (status != 0)
                break;
        } else if (strcasecmp ("TTLFactor", child->key) == 0) {
            double tmp = NAN;
            status = cf_util_get_double (child, &tmp);
            if (status != 0)
                break;
            if (tmp >= 2.0) {
                host->ttl_factor = tmp;
            } else if (tmp >= 1.0) {
                NOTICE ("write_riemann plugin: The configured "
                        "TTLFactor is very small "
                        "(%.1f). A value of 2.0 or "
                        "greater is recommended.",
                        tmp);
                host->ttl_factor = tmp;
            } else if (tmp > 0.0) {
                WARNING ("write_riemann plugin: The configured "
                         "TTLFactor is too small to be "
                         "useful (%.1f). I'll use it "
                         "since the user knows best, "
                         "but under protest.",
                         tmp);
                host->ttl_factor = tmp;
            } else { /* zero, negative and NAN */
                ERROR ("write_riemann plugin: The configured "
                       "TTLFactor is invalid (%.1f).",
                       tmp);
            }
        } else {
            WARNING("write_riemann plugin: ignoring unknown config "
                    "option: \"%s\"", child->key);
        }
    }
    if (status != 0) {
        riemann_free (host);
        return status;
    }

    ssnprintf (callback_name, sizeof (callback_name), "write_riemann/%s",
               host->name);
    ud.data = host;
    ud.free_func = riemann_free;

    pthread_mutex_lock (&host->lock);

    status = plugin_register_write (callback_name, riemann_write, &ud);
    if (status != 0)
        WARNING ("write_riemann plugin: plugin_register_write (\"%s\") "
                 "failed with status %i.",
                 callback_name, status);
    else /* success */
        host->reference_count++;

    status = plugin_register_notification (callback_name,
                                           riemann_notification, &ud);
    if (status != 0)
        WARNING ("write_riemann plugin: plugin_register_notification (\"%s\") "
                 "failed with status %i.",
                 callback_name, status);
    else /* success */
        host->reference_count++;

    if (host->reference_count <= 1)
    {
        /* Both callbacks failed => free memory.
         * We need to unlock here, because riemann_free() will lock.
         * This is not a race condition, because we're the only one
         * holding a reference. */
        pthread_mutex_unlock (&host->lock);
        riemann_free (host);
        return (-1);
    }

    host->reference_count--;
    pthread_mutex_unlock (&host->lock);

    return status;
} /* }}} int riemann_config_node */
Пример #5
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 */
Пример #6
0
static int csnmp_config_add_data (oconfig_item_t *ci)
{
  data_definition_t *dd;
  int status = 0;
  int i;

  dd = (data_definition_t *) malloc (sizeof (data_definition_t));
  if (dd == NULL)
    return (-1);
  memset (dd, '\0', sizeof (data_definition_t));

  status = cf_util_get_string(ci, &dd->name);
  if (status != 0)
  {
    free (dd);
    return (-1);
  }

  dd->scale = 1.0;
  dd->shift = 0.0;

  for (i = 0; i < ci->children_num; i++)
  {
    oconfig_item_t *option = ci->children + i;

    if (strcasecmp ("Type", option->key) == 0)
      status = cf_util_get_string(option, &dd->type);
    else if (strcasecmp ("Table", option->key) == 0)
      status = cf_util_get_boolean(option, &dd->is_table);
    else if (strcasecmp ("Instance", option->key) == 0)
      status = csnmp_config_add_data_instance (dd, option);
    else if (strcasecmp ("InstancePrefix", option->key) == 0)
      status = csnmp_config_add_data_instance_prefix (dd, option);
    else if (strcasecmp ("Values", option->key) == 0)
      status = csnmp_config_add_data_values (dd, option);
    else if (strcasecmp ("Shift", option->key) == 0)
      status = cf_util_get_double(option, &dd->shift);
    else if (strcasecmp ("Scale", option->key) == 0)
      status = cf_util_get_double(option, &dd->scale);
    else if (strcasecmp ("Ignore", option->key) == 0)
      status = csnmp_config_add_data_blacklist(dd, option);
    else if (strcasecmp ("InvertMatch", option->key) == 0)
      status = csnmp_config_add_data_blacklist_match_inverted(dd, option);
    else
    {
      WARNING ("snmp plugin: Option `%s' not allowed here.", option->key);
      status = -1;
    }

    if (status != 0)
      break;
  } /* for (ci->children) */

  while (status == 0)
  {
    if (dd->type == NULL)
    {
      WARNING ("snmp plugin: `Type' not given for data `%s'", dd->name);
      status = -1;
      break;
    }
    if (dd->values == NULL)
    {
      WARNING ("snmp plugin: No `Value' given for data `%s'", dd->name);
      status = -1;
      break;
    }

    break;
  } /* while (status == 0) */

  if (status != 0)
  {
    sfree (dd->name);
    sfree (dd->instance_prefix);
    sfree (dd->values);
    sfree (dd->ignores);
    sfree (dd);
    return (-1);
  }

  DEBUG ("snmp plugin: dd = { name = %s, type = %s, is_table = %s, values_len = %zu }",
      dd->name, dd->type, (dd->is_table != 0) ? "true" : "false", dd->values_len);

  if (data_head == NULL)
    data_head = dd;
  else
  {
    data_definition_t *last;
    last = data_head;
    while (last->next != NULL)
      last = last->next;
    last->next = dd;
  }

  return (0);
} /* int csnmp_config_add_data */