示例#1
0
文件: lua.c 项目: bzed/collectd
static int lua_cb_dispatch_values(lua_State *L) /* {{{ */
{
  int nargs = lua_gettop(L);

  if (nargs != 1)
    return luaL_error(L, "Invalid number of arguments (%d != 1)", nargs);

  luaL_checktype(L, 1, LUA_TTABLE);

  value_list_t *vl = luaC_tovaluelist(L, -1);
  if (vl == NULL)
    return luaL_error(L, "%s", "luaC_tovaluelist failed");

#if COLLECT_DEBUG
  char identifier[6 * DATA_MAX_NAME_LEN];
  FORMAT_VL(identifier, sizeof(identifier), vl);

  DEBUG("Lua plugin: collectd.dispatch_values(): Received value list \"%s\", "
        "time %.3f, interval %.3f.",
        identifier, CDTIME_T_TO_DOUBLE(vl->time),
        CDTIME_T_TO_DOUBLE(vl->interval));
#endif

  plugin_dispatch_values(vl);

  sfree(vl->values);
  sfree(vl);
  return 0;
} /* }}} lua_cb_dispatch_values */
示例#2
0
void latency_counter_reset(latency_counter_t *lc) /* {{{ */
{
  if (lc == NULL)
    return;

  cdtime_t bin_width = lc->bin_width;
  cdtime_t max_bin = (lc->max - 1) / lc->bin_width;

/*
  If max latency is REDUCE_THRESHOLD times less than histogram's range,
  then cut it in half. REDUCE_THRESHOLD must be >= 2.
  Value of 4 is selected to reduce frequent changes of bin width.
*/
#define REDUCE_THRESHOLD 4
  if ((lc->num > 0) && (lc->bin_width >= HISTOGRAM_DEFAULT_BIN_WIDTH * 2) &&
      (max_bin < HISTOGRAM_NUM_BINS / REDUCE_THRESHOLD)) {
    /* new bin width will be the previous power of 2 */
    bin_width = bin_width / 2;

    DEBUG("utils_latency: latency_counter_reset: max_latency = %.3f; "
          "max_bin = %" PRIu64 "; old_bin_width = %.3f; new_bin_width = %.3f;",
          CDTIME_T_TO_DOUBLE(lc->max), max_bin,
          CDTIME_T_TO_DOUBLE(lc->bin_width), CDTIME_T_TO_DOUBLE(bin_width));
  }

  memset(lc, 0, sizeof(*lc));

  /* preserve bin width */
  lc->bin_width = bin_width;
  lc->start_time = cdtime();
} /* }}} void latency_counter_reset */
示例#3
0
int create_putval (char *ret, size_t ret_len, /* {{{ */
	const data_set_t *ds, const value_list_t *vl)
{
	char buffer_ident[6 * DATA_MAX_NAME_LEN];
	char buffer_values[1024];
	int status;

	status = FORMAT_VL (buffer_ident, sizeof (buffer_ident), vl);
	if (status != 0)
		return (status);
	escape_string (buffer_ident, sizeof (buffer_ident));

	status = format_values (buffer_values, sizeof (buffer_values),
			ds, vl, /* store rates = */ 0);
	if (status != 0)
		return (status);
	escape_string (buffer_values, sizeof (buffer_values));

	ssnprintf (ret, ret_len,
			"PUTVAL %s interval=%.3f %s",
			buffer_ident,
			(vl->interval > 0)
			? CDTIME_T_TO_DOUBLE (vl->interval)
			: CDTIME_T_TO_DOUBLE (interval_g),
			buffer_values);

	return (0);
} /* }}} int create_putval */
示例#4
0
文件: amqp.c 项目: Mindera/collectd
static void *camqp_subscribe_thread (void *user_data) /* {{{ */
{
    camqp_config_t *conf = user_data;
    int status;

    cdtime_t interval = plugin_get_interval ();

    while (subscriber_threads_running)
    {
        amqp_frame_t frame;

        status = camqp_connect (conf);
        if (status != 0)
        {
            struct timespec ts_interval;
            ERROR ("amqp plugin: camqp_connect failed. "
                    "Will sleep for %.3f seconds.",
                    CDTIME_T_TO_DOUBLE (interval));
            CDTIME_T_TO_TIMESPEC (interval, &ts_interval);
            nanosleep (&ts_interval, /* remaining = */ NULL);
            continue;
        }

        status = amqp_simple_wait_frame (conf->connection, &frame);
        if (status < 0)
        {
            struct timespec ts_interval;
            ERROR ("amqp plugin: amqp_simple_wait_frame failed. "
                    "Will sleep for %.3f seconds.",
                    CDTIME_T_TO_DOUBLE (interval));
            camqp_close_connection (conf);
            CDTIME_T_TO_TIMESPEC (interval, &ts_interval);
            nanosleep (&ts_interval, /* remaining = */ NULL);
            continue;
        }

        if (frame.frame_type != AMQP_FRAME_METHOD)
        {
            DEBUG ("amqp plugin: Unexpected frame type: %#"PRIx8,
                    frame.frame_type);
            continue;
        }

        if (frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD)
        {
            DEBUG ("amqp plugin: Unexpected method id: %#"PRIx32,
                    frame.payload.method.id);
            continue;
        }

        camqp_read_header (conf);

        amqp_maybe_release_buffers (conf->connection);
    } /* while (subscriber_threads_running) */

    camqp_config_free (conf);
    pthread_exit (NULL);
    return (NULL);
} /* }}} void *camqp_subscribe_thread */
示例#5
0
文件: snmp.c 项目: kmiku7/collectd
static int csnmp_read_host (user_data_t *ud)
{
  host_definition_t *host;
  cdtime_t time_start;
  cdtime_t time_end;
  int status;
  int success;
  int i;

  host = ud->data;

  if (host->interval == 0)
    host->interval = plugin_get_interval ();

  time_start = cdtime ();

  if (host->sess_handle == NULL)
    csnmp_host_open_session (host);

  if (host->sess_handle == NULL)
    return (-1);

  success = 0;
  for (i = 0; i < host->data_list_len; i++)
  {
    data_definition_t *data = host->data_list[i];

    if (data->is_table)
      status = csnmp_read_table (host, data);
    else
      status = csnmp_read_value (host, data);

    if (status == 0)
      success++;
  }

  time_end = cdtime ();
  if ((time_end - time_start) > host->interval)
  {
    WARNING ("snmp plugin: Host `%s' should be queried every %.3f "
        "seconds, but reading all values takes %.3f seconds.",
        host->name,
        CDTIME_T_TO_DOUBLE (host->interval),
        CDTIME_T_TO_DOUBLE (time_end - time_start));
  }

  if (success == 0)
    return (-1);

  return (0);
} /* int csnmp_read_host */
示例#6
0
cdtime_t latency_counter_get_percentile (latency_counter_t *lc, /* {{{ */
    double percent)
{
  double percent_upper;
  double percent_lower;
  double p;
  cdtime_t latency_lower;
  cdtime_t latency_interpolated;
  int sum;
  size_t i;

  if ((lc == NULL) || (lc->num == 0) || !((percent > 0.0) && (percent < 100.0)))
    return (0);

  /* Find index i so that at least "percent" events are within i+1 ms. */
  percent_upper = 0.0;
  percent_lower = 0.0;
  sum = 0;
  for (i = 0; i < HISTOGRAM_NUM_BINS; i++)
  {
    percent_lower = percent_upper;
    sum += lc->histogram[i];
    if (sum == 0)
      percent_upper = 0.0;
    else
      percent_upper = 100.0 * ((double) sum) / ((double) lc->num);

    if (percent_upper >= percent)
      break;
  }

  if (i >= HISTOGRAM_NUM_BINS)
    return (0);

  assert (percent_upper >= percent);
  assert (percent_lower < percent);

  if (i == 0)
    return (lc->bin_width);

  latency_lower = ((cdtime_t) i) * lc->bin_width;
  p = (percent - percent_lower) / (percent_upper - percent_lower);

  latency_interpolated = latency_lower
    + DOUBLE_TO_CDTIME_T (p * CDTIME_T_TO_DOUBLE (lc->bin_width));

  DEBUG ("latency_counter_get_percentile: latency_interpolated = %.3f",
      CDTIME_T_TO_DOUBLE (latency_interpolated));
  return (latency_interpolated);
} /* }}} cdtime_t latency_counter_get_percentile */
示例#7
0
文件: collectd.c 项目: octo/collectd
static int do_loop(void) {
  cdtime_t interval = cf_get_default_interval();
  cdtime_t wait_until = cdtime() + interval;

  while (loop == 0) {
#if HAVE_LIBKSTAT
    update_kstat();
#endif

    /* Issue all plugins */
    plugin_read_all();

    cdtime_t now = cdtime();
    if (now >= wait_until) {
      WARNING("Not sleeping because the next interval is "
              "%.3f seconds in the past!",
              CDTIME_T_TO_DOUBLE(now - wait_until));
      wait_until = now + interval;
      continue;
    }

    struct timespec ts_wait = CDTIME_T_TO_TIMESPEC(wait_until - now);
    wait_until = wait_until + interval;

    while ((loop == 0) && (nanosleep(&ts_wait, &ts_wait) != 0)) {
      if (errno != EINTR) {
        ERROR("nanosleep failed: %s", STRERRNO);
        return -1;
      }
    }
  } /* while (loop == 0) */

  return 0;
} /* int do_loop */
示例#8
0
int tail_match_add_match(cu_tail_match_t *obj, cu_match_t *match,
                         int (*submit_match)(cu_match_t *match,
                                             void *user_data),
                         void *user_data,
                         void (*free_user_data)(void *user_data)) {
  cu_tail_match_match_t *temp;

  temp = realloc(obj->matches,
                 sizeof(cu_tail_match_match_t) * (obj->matches_num + 1));
  if (temp == NULL)
    return (-1);

  obj->matches = temp;
  obj->matches_num++;

  DEBUG("tail_match_add_match interval %lf",
        CDTIME_T_TO_DOUBLE(((cu_tail_match_simple_t *)user_data)->interval));
  temp = obj->matches + (obj->matches_num - 1);

  temp->match = match;
  temp->user_data = user_data;
  temp->submit = submit_match;
  temp->free = free_user_data;

  return (0);
} /* int tail_match_add_match */
示例#9
0
static int we_flush_nolock (cdtime_t timeout, we_callback_t *cb) 
{
  int status;

  DEBUG("write_extremon plugin: we_flush_nolock: timeout = %.3f; "
        "send_buffer_fill = %zu;", CDTIME_T_TO_DOUBLE (timeout),
                                  cb->send_buffer_fill);

  if(timeout>0)
  {
    cdtime_t now;
    now = cdtime ();
    if ((cb->send_buffer_init_time + timeout) > now)
      return (0);
  }

/*  if (cb->send_buffer_fill <= 0)
# {
#   cb->send_buffer_init_time = cdtime ();
#   return (0);
# } */

  status = we_send_buffer (cb);
  we_reset_buffer (cb);

  return (status);
} 
示例#10
0
double latency_counter_get_rate(const latency_counter_t *lc, /* {{{ */
                                cdtime_t lower, cdtime_t upper,
                                const cdtime_t now) {
  if ((lc == NULL) || (lc->num == 0))
    return NAN;

  if (upper && (upper < lower))
    return NAN;
  if (lower == upper)
    return 0;

  /* Buckets have an exclusive lower bound and an inclusive upper bound. That
   * means that the first bucket, index 0, represents (0-bin_width]. That means
   * that latency==bin_width needs to result in bin=0, that's why we need to
   * subtract one before dividing by bin_width. */
  cdtime_t lower_bin = 0;
  if (lower)
    /* lower is *exclusive* => determine bucket for lower+1 */
    lower_bin = ((lower + 1) - 1) / lc->bin_width;

  /* lower is greater than the longest latency observed => rate is zero. */
  if (lower_bin >= HISTOGRAM_NUM_BINS)
    return 0;

  cdtime_t upper_bin = HISTOGRAM_NUM_BINS - 1;
  if (upper)
    upper_bin = (upper - 1) / lc->bin_width;

  if (upper_bin >= HISTOGRAM_NUM_BINS) {
    upper_bin = HISTOGRAM_NUM_BINS - 1;
    upper = 0;
  }

  double sum = 0;
  for (size_t i = lower_bin; i <= upper_bin; i++)
    sum += lc->histogram[i];

  if (lower) {
    /* Approximate ratio of requests in lower_bin, that fall between
     * lower_bin_boundary and lower. This ratio is then subtracted from sum to
     * increase accuracy. */
    cdtime_t lower_bin_boundary = lower_bin * lc->bin_width;
    assert(lower >= lower_bin_boundary);
    double lower_ratio =
        (double)(lower - lower_bin_boundary) / ((double)lc->bin_width);
    sum -= lower_ratio * lc->histogram[lower_bin];
  }

  if (upper) {
    /* As above: approximate ratio of requests in upper_bin, that fall between
     * upper and upper_bin_boundary. */
    cdtime_t upper_bin_boundary = (upper_bin + 1) * lc->bin_width;
    assert(upper <= upper_bin_boundary);
    double ratio = (double)(upper_bin_boundary - upper) / (double)lc->bin_width;
    sum -= ratio * lc->histogram[upper_bin];
  }

  return sum / (CDTIME_T_TO_DOUBLE(now - lc->start_time));
} /* }}} double latency_counter_get_rate */
示例#11
0
文件: disk.c 项目: BrianB2/collectd
static counter_t disk_calc_time_incr (counter_t delta_time, counter_t delta_ops)
{
	double interval = CDTIME_T_TO_DOUBLE (plugin_get_interval ());
	double avg_time = ((double) delta_time) / ((double) delta_ops);
	double avg_time_incr = interval * avg_time;

	return ((counter_t) (avg_time_incr + .5));
}
示例#12
0
cdtime_t latency_counter_get_average (latency_counter_t *lc) /* {{{ */
{
  double average;

  if ((lc == NULL) || (lc->num == 0))
    return (0);

  average = CDTIME_T_TO_DOUBLE (lc->sum) / ((double) lc->num);
  return (DOUBLE_TO_CDTIME_T (average));
} /* }}} cdtime_t latency_counter_get_average */
示例#13
0
static int ts_invoke_absolute(const data_set_t *ds, value_list_t *vl, /* {{{ */
                              ts_data_t *data, int dsrc_index) {
  uint64_t curr_absolute;
  double rate;
  int status;

  /* Required meta data */
  double int_fraction;
  char key_int_fraction[128];

  curr_absolute = (uint64_t)vl->values[dsrc_index].absolute;

  snprintf(key_int_fraction, sizeof(key_int_fraction),
           "target_scale[%p,%i]:int_fraction", (void *)data, dsrc_index);

  int_fraction = 0.0;

  /* Query the meta data */
  status = uc_meta_data_get_double(vl, key_int_fraction, &int_fraction);
  if (status != 0)
    int_fraction = 0.0;

  rate = ((double)curr_absolute) / CDTIME_T_TO_DOUBLE(vl->interval);

  /* Modify the rate. */
  if (!isnan(data->factor))
    rate *= data->factor;
  if (!isnan(data->offset))
    rate += data->offset;

  /* Calculate the new absolute. */
  int_fraction += (rate * CDTIME_T_TO_DOUBLE(vl->interval));
  curr_absolute = (uint64_t)int_fraction;
  int_fraction -= ((double)curr_absolute);

  vl->values[dsrc_index].absolute = (absolute_t)curr_absolute;

  /* Update to the new absolute value */
  uc_meta_data_add_double(vl, key_int_fraction, int_fraction);

  return 0;
} /* }}} int ts_invoke_absolute */
示例#14
0
/*
* Histogram represents the distribution of data, it has a list of "bins".
* Each bin represents an interval and has a count (frequency) of
* number of values fall within its interval.
*
* Histogram's range is determined by the number of bins and the bin width,
* There are 1000 bins and all bins have the same width of default 1 millisecond.
* When a value above this range is added, Histogram's range is increased by
* increasing the bin width (note that number of bins remains always at 1000).
* This operation of increasing bin width is little expensive as each bin need
* to be visited to update its count. To reduce frequent change of bin width,
* new bin width will be the next nearest power of 2. Example: 2, 4, 8, 16, 32,
* 64, 128, 256, 512, 1024, 2048, 5086, ...
*
* So, if the required bin width is 300, then new bin width will be 512 as it is
* the next nearest power of 2.
*/
static void change_bin_width(latency_counter_t *lc, cdtime_t latency) /* {{{ */
{
  /* This function is called because the new value is above histogram's range.
   * First find the required bin width:
   *           requiredBinWidth = (value + 1) / numBins
   * then get the next nearest power of 2
   *           newBinWidth = 2^(ceil(log2(requiredBinWidth)))
   */
  double required_bin_width =
      ((double)(latency + 1)) / ((double)HISTOGRAM_NUM_BINS);
  double required_bin_width_logbase2 = log(required_bin_width) / log(2.0);
  cdtime_t new_bin_width =
      (cdtime_t)(pow(2.0, ceil(required_bin_width_logbase2)) + .5);
  cdtime_t old_bin_width = lc->bin_width;

  lc->bin_width = new_bin_width;

  /* bin_width has been increased, now iterate through all bins and move the
   * old bin's count to new bin. */
  if (lc->num > 0) // if the histogram has data then iterate else skip
  {
    double width_change_ratio =
        ((double)old_bin_width) / ((double)new_bin_width);

    for (size_t i = 0; i < HISTOGRAM_NUM_BINS; i++) {
      size_t new_bin = (size_t)(((double)i) * width_change_ratio);
      if (i == new_bin)
        continue;
      assert(new_bin < i);

      lc->histogram[new_bin] += lc->histogram[i];
      lc->histogram[i] = 0;
    }
  }

  DEBUG("utils_latency: change_bin_width: latency = %.3f; "
        "old_bin_width = %.3f; new_bin_width = %.3f;",
        CDTIME_T_TO_DOUBLE(latency), CDTIME_T_TO_DOUBLE(old_bin_width),
        CDTIME_T_TO_DOUBLE(new_bin_width));
} /* }}} void change_bin_width */
示例#15
0
/**
 * Read configuration.
 */
static int cgps_config (oconfig_item_t *ci)
{
  int i;

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

    if (strcasecmp ("Host", child->key) == 0)
      cf_util_get_string (child, &cgps_config_data.host);
    else if (strcasecmp ("Port", child->key) == 0)
      cf_util_get_service (child, &cgps_config_data.port);
    else if (strcasecmp ("Timeout", child->key) == 0)
      cf_util_get_cdtime (child, &cgps_config_data.timeout);
    else if (strcasecmp ("PauseConnect", child->key) == 0)
      cf_util_get_cdtime (child, &cgps_config_data.pause_connect);
    else
      WARNING ("gps plugin: Ignoring unknown config option \"%s\".", child->key);
  }

  // Controlling the value for timeout:
  // If set too high it blocks the reading (> 5 s), too low it gets not reading (< 500 us).
  // To avoid any issues we replace "out of range" value by the default value.
  if (
    cgps_config_data.timeout > TIME_T_TO_CDTIME_T(5)
    ||
    cgps_config_data.timeout < US_TO_CDTIME_T(500)
  ) 
  {
    WARNING ("gps plugin: timeout set to %.6f sec. setting to default (%.6f).", 
      CDTIME_T_TO_DOUBLE(cgps_config_data.timeout),
      CDTIME_T_TO_DOUBLE(CGPS_DEFAULT_TIMEOUT)
    );
    cgps_config_data.timeout = CGPS_DEFAULT_TIMEOUT;
  } 

  return (0);
}
示例#16
0
int handle_listval (FILE *fh, char *buffer)
{
  char *command;
  char **names = NULL;
  cdtime_t *times = NULL;
  size_t number = 0;
  size_t i;
  int status;

  DEBUG ("utils_cmd_listval: handle_listval (fh = %p, buffer = %s);",
      (void *) fh, buffer);

  command = NULL;
  status = parse_string (&buffer, &command);
  if (status != 0)
  {
    print_to_socket (fh, "-1 Cannot parse command.\n");
    free_everything_and_return (-1);
  }
  assert (command != NULL);

  if (strcasecmp ("LISTVAL", command) != 0)
  {
    print_to_socket (fh, "-1 Unexpected command: `%s'.\n", command);
    free_everything_and_return (-1);
  }

  if (*buffer != 0)
  {
    print_to_socket (fh, "-1 Garbage after end of command: %s\n", buffer);
    free_everything_and_return (-1);
  }

  status = uc_get_names (&names, &times, &number);
  if (status != 0)
  {
    DEBUG ("command listval: uc_get_names failed with status %i", status);
    print_to_socket (fh, "-1 uc_get_names failed.\n");
    free_everything_and_return (-1);
  }

  print_to_socket (fh, "%i Value%s found\n",
      (int) number, (number == 1) ? "" : "s");
  for (i = 0; i < number; i++)
    print_to_socket (fh, "%.3f %s\n", CDTIME_T_TO_DOUBLE (times[i]),
       	names[i]);

  free_everything_and_return (0);
} /* int handle_listval */
示例#17
0
/**
 * Init.
 */
static int cgps_init (void)
{
  int status;

  if (cgps_thread_running == CGPS_TRUE)
  {
    DEBUG ("gps plugin: error gps thread already running ... ");
    return 0;
  }

  DEBUG ("gps plugin: config{host: \"%s\", port: \"%s\", timeout: %.6f sec., pause connect: %.3f sec.}",
         cgps_config_data.host, cgps_config_data.port,
         CDTIME_T_TO_DOUBLE (cgps_config_data.timeout),
         CDTIME_T_TO_DOUBLE (cgps_config_data.pause_connect));

  status = plugin_thread_create (&cgps_thread_id, NULL, cgps_thread, NULL);
  if (status != 0)
  {
    ERROR ("gps plugin: pthread_create() failed.");
    return (-1);
  }

  return (0);
}
示例#18
0
static void cc_submit_response_time (const web_page_t *wp, /* {{{ */
    cdtime_t response_time)
{
  value_t values[1];
  value_list_t vl = VALUE_LIST_INIT;

  values[0].gauge = CDTIME_T_TO_DOUBLE (response_time);

  vl.values = values;
  vl.values_len = 1;
  sstrncpy (vl.host, hostname_g, sizeof (vl.host));
  sstrncpy (vl.plugin, "curl", sizeof (vl.plugin));
  sstrncpy (vl.plugin_instance, wp->instance, sizeof (vl.plugin_instance));
  sstrncpy (vl.type, "response_time", sizeof (vl.type));

  plugin_dispatch_values (&vl);
} /* }}} void cc_submit_response_time */
示例#19
0
static PGresult *c_psql_exec_query_params (c_psql_database_t *db,
		udb_query_t *q, c_psql_user_data_t *data)
{
	char *params[db->max_params_num];
	char  interval[64];
	int   i;

	if ((data == NULL) || (data->params_num == 0))
		return (c_psql_exec_query_noparams (db, q));

	assert (db->max_params_num >= data->params_num);

	for (i = 0; i < data->params_num; ++i) {
		switch (data->params[i]) {
			case C_PSQL_PARAM_HOST:
				params[i] = C_PSQL_IS_UNIX_DOMAIN_SOCKET (db->host)
					? "localhost" : db->host;
				break;
			case C_PSQL_PARAM_DB:
				params[i] = db->database;
				break;
			case C_PSQL_PARAM_USER:
				params[i] = db->user;
				break;
			case C_PSQL_PARAM_INTERVAL:
				ssnprintf (interval, sizeof (interval), "%.3f",
						(db->interval > 0)
						? CDTIME_T_TO_DOUBLE (db->interval)
						: plugin_get_interval ());
				params[i] = interval;
				break;
			case C_PSQL_PARAM_INSTANCE:
				params[i] = db->instance;
				break;
			default:
				assert (0);
		}
	}

	return PQexecParams (db->conn, udb_query_get_statement (q),
			data->params_num, NULL,
			(const char *const *) params,
			NULL, NULL, /* return text data */ 0);
} /* c_psql_exec_query_params */
示例#20
0
/* wg_force_reconnect_check closes cb->sock_fd when it was open for longer
 * than cb->reconnect_interval. Must hold cb->send_lock when calling. */
static void wg_force_reconnect_check (struct wg_callback *cb)
{
    cdtime_t now;

    if (cb->reconnect_interval == 0)
        return;

    /* check if address changes if addr_timeout */
    now = cdtime ();
    if ((now - cb->last_reconnect_time) < cb->reconnect_interval)
        return;

    /* here we should close connection on next */
    close (cb->sock_fd);
    cb->sock_fd = -1;
    cb->last_reconnect_time = now;
    cb->reconnect_interval_reached = 1;

    INFO ("write_graphite plugin: Connection closed after %.3f seconds.",
          CDTIME_T_TO_DOUBLE (now - cb->last_reconnect_time));
}
示例#21
0
文件: collectd.c 项目: octo/collectd
static int init_global_variables(void) {
  interval_g = cf_get_default_interval();
  assert(interval_g > 0);
  DEBUG("interval_g = %.3f;", CDTIME_T_TO_DOUBLE(interval_g));

  const char *str = global_option_get("Timeout");
  if (str == NULL)
    str = "2";
  timeout_g = atoi(str);
  if (timeout_g <= 1) {
    fprintf(stderr, "Cannot set the timeout to a correct value.\n"
                    "Please check your settings.\n");
    return -1;
  }
  DEBUG("timeout_g = %i;", timeout_g);

  if (init_hostname() != 0)
    return -1;
  DEBUG("hostname_g = %s;", hostname_g);

  return 0;
} /* int init_global_variables */
示例#22
0
static int apcups_config (oconfig_item_t *ci)
{
	int i;
	_Bool persistent_conn_set = 0;

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

		if (strcasecmp (child->key, "Host") == 0)
			cf_util_get_string (child, &conf_node);
		else if (strcasecmp (child->key, "Port") == 0)
			cf_util_get_service (child, &conf_service);
		else if (strcasecmp (child->key, "ReportSeconds") == 0)
			cf_util_get_boolean (child, &conf_report_seconds);
		else if (strcasecmp (child->key, "PersistentConnection") == 0) {
			cf_util_get_boolean (child, &conf_persistent_conn);
			persistent_conn_set = 1;
		}
		else
			ERROR ("apcups plugin: Unknown config option \"%s\".", child->key);
	}

	if (!persistent_conn_set) {
		double interval = CDTIME_T_TO_DOUBLE(plugin_get_interval());
		if (interval > APCUPS_SERVER_TIMEOUT) {
			NOTICE ("apcups plugin: Plugin poll interval set to %.3f seconds. "
				"Apcupsd NIS socket timeout is %.3f seconds, "
				"PersistentConnection disabled by default.",
				interval, APCUPS_SERVER_TIMEOUT);
			conf_persistent_conn = 0;
		}
	}

	return (0);
} /* int apcups_config */
示例#23
0
static riemann_event_t *
wrr_value_to_event(struct riemann_host const *host, /* {{{ */
                   data_set_t const *ds, value_list_t const *vl, size_t index,
                   gauge_t const *rates, int status) {
  riemann_event_t *event;
  char name_buffer[5 * DATA_MAX_NAME_LEN];
  char service_buffer[6 * DATA_MAX_NAME_LEN];
  size_t i;

  event = riemann_event_new();
  if (event == NULL) {
    ERROR("write_riemann plugin: riemann_event_new() failed.");
    return NULL;
  }

  format_name(name_buffer, sizeof(name_buffer),
              /* host = */ "", vl->plugin, vl->plugin_instance, vl->type,
              vl->type_instance);
  if (host->always_append_ds || (ds->ds_num > 1)) {
    if (host->event_service_prefix == NULL)
      snprintf(service_buffer, sizeof(service_buffer), "%s/%s", &name_buffer[1],
               ds->ds[index].name);
    else
      snprintf(service_buffer, sizeof(service_buffer), "%s%s/%s",
               host->event_service_prefix, &name_buffer[1], ds->ds[index].name);
  } else {
    if (host->event_service_prefix == NULL)
      sstrncpy(service_buffer, &name_buffer[1], sizeof(service_buffer));
    else
      snprintf(service_buffer, sizeof(service_buffer), "%s%s",
               host->event_service_prefix, &name_buffer[1]);
  }

  riemann_event_set(
      event, RIEMANN_EVENT_FIELD_HOST, vl->host, RIEMANN_EVENT_FIELD_TIME,
      (int64_t)CDTIME_T_TO_TIME_T(vl->time), RIEMANN_EVENT_FIELD_TTL,
      (float)CDTIME_T_TO_DOUBLE(vl->interval) * host->ttl_factor,
      RIEMANN_EVENT_FIELD_STRING_ATTRIBUTES, "plugin", vl->plugin, "type",
      vl->type, "ds_name", ds->ds[index].name, NULL,
      RIEMANN_EVENT_FIELD_SERVICE, service_buffer, RIEMANN_EVENT_FIELD_NONE);

#if RCC_VERSION_NUMBER >= 0x010A00
  riemann_event_set(event, RIEMANN_EVENT_FIELD_TIME_MICROS,
                    (int64_t)CDTIME_T_TO_US(vl->time));
#endif

  if (host->check_thresholds) {
    const char *state = NULL;

    switch (status) {
    case STATE_OKAY:
      state = "ok";
      break;
    case STATE_ERROR:
      state = "critical";
      break;
    case STATE_WARNING:
      state = "warning";
      break;
    case STATE_MISSING:
      state = "unknown";
      break;
    }
    if (state)
      riemann_event_set(event, RIEMANN_EVENT_FIELD_STATE, state,
                        RIEMANN_EVENT_FIELD_NONE);
  }

  if (vl->plugin_instance[0] != 0)
    riemann_event_string_attribute_add(event, "plugin_instance",
                                       vl->plugin_instance);
  if (vl->type_instance[0] != 0)
    riemann_event_string_attribute_add(event, "type_instance",
                                       vl->type_instance);

  if ((ds->ds[index].type != DS_TYPE_GAUGE) && (rates != NULL)) {
    char ds_type[DATA_MAX_NAME_LEN];

    snprintf(ds_type, sizeof(ds_type), "%s:rate",
             DS_TYPE_TO_STRING(ds->ds[index].type));
    riemann_event_string_attribute_add(event, "ds_type", ds_type);
  } else {
    riemann_event_string_attribute_add(event, "ds_type",
                                       DS_TYPE_TO_STRING(ds->ds[index].type));
  }

  {
    char ds_index[DATA_MAX_NAME_LEN];

    snprintf(ds_index, sizeof(ds_index), "%" PRIsz, index);
    riemann_event_string_attribute_add(event, "ds_index", ds_index);
  }

  for (i = 0; i < riemann_attrs_num; i += 2)
    riemann_event_string_attribute_add(event, riemann_attrs[i],
                                       riemann_attrs[i + 1]);

  for (i = 0; i < riemann_tags_num; i++)
    riemann_event_tag_add(event, riemann_tags[i]);

  if (ds->ds[index].type == DS_TYPE_GAUGE) {
    riemann_event_set(event, RIEMANN_EVENT_FIELD_METRIC_D,
                      (double)vl->values[index].gauge,
                      RIEMANN_EVENT_FIELD_NONE);
  } else if (rates != NULL) {
    riemann_event_set(event, RIEMANN_EVENT_FIELD_METRIC_D, (double)rates[index],
                      RIEMANN_EVENT_FIELD_NONE);
  } else {
    int64_t metric;

    if (ds->ds[index].type == DS_TYPE_DERIVE)
      metric = (int64_t)vl->values[index].derive;
    else if (ds->ds[index].type == DS_TYPE_ABSOLUTE)
      metric = (int64_t)vl->values[index].absolute;
    else
      metric = (int64_t)vl->values[index].counter;

    riemann_event_set(event, RIEMANN_EVENT_FIELD_METRIC_S64, (int64_t)metric,
                      RIEMANN_EVENT_FIELD_NONE);
  }

  DEBUG("write_riemann plugin: Successfully created message for metric: "
        "host = \"%s\", service = \"%s\"",
        event->host, event->service);
  return event;
} /* }}} riemann_event_t *wrr_value_to_event */
示例#24
0
static Event *riemann_value_to_protobuf (struct riemann_host const *host, /* {{{ */
        data_set_t const *ds,
        value_list_t const *vl, size_t index,
        gauge_t const *rates)
{
    Event *event;
    char name_buffer[5 * DATA_MAX_NAME_LEN];
    char service_buffer[6 * DATA_MAX_NAME_LEN];
    double ttl;
    int i;

    event = malloc (sizeof (*event));
    if (event == NULL)
    {
        ERROR ("write_riemann plugin: malloc failed.");
        return (NULL);
    }
    memset (event, 0, sizeof (*event));
    event__init (event);

    event->host = strdup (vl->host);
    event->time = CDTIME_T_TO_TIME_T (vl->time);
    event->has_time = 1;

    ttl = CDTIME_T_TO_DOUBLE (vl->interval) * host->ttl_factor;
    event->ttl = (float) ttl;
    event->has_ttl = 1;

    riemann_event_add_attribute (event, "plugin", vl->plugin);
    if (vl->plugin_instance[0] != 0)
        riemann_event_add_attribute (event, "plugin_instance",
                                     vl->plugin_instance);

    riemann_event_add_attribute (event, "type", vl->type);
    if (vl->type_instance[0] != 0)
        riemann_event_add_attribute (event, "type_instance",
                                     vl->type_instance);

    if ((ds->ds[index].type != DS_TYPE_GAUGE) && (rates != NULL))
    {
        char ds_type[DATA_MAX_NAME_LEN];

        ssnprintf (ds_type, sizeof (ds_type), "%s:rate",
                   DS_TYPE_TO_STRING(ds->ds[index].type));
        riemann_event_add_attribute (event, "ds_type", ds_type);
    }
    else
    {
        riemann_event_add_attribute (event, "ds_type",
                                     DS_TYPE_TO_STRING(ds->ds[index].type));
    }
    riemann_event_add_attribute (event, "ds_name", ds->ds[index].name);
    {
        char ds_index[DATA_MAX_NAME_LEN];

        ssnprintf (ds_index, sizeof (ds_index), "%zu", index);
        riemann_event_add_attribute (event, "ds_index", ds_index);
    }

    for (i = 0; i < riemann_attrs_num; i += 2)
        riemann_event_add_attribute(event,
                                    riemann_attrs[i],
                                    riemann_attrs[i +1]);

    for (i = 0; i < riemann_tags_num; i++)
        riemann_event_add_tag (event, riemann_tags[i]);

    if (ds->ds[index].type == DS_TYPE_GAUGE)
    {
        event->has_metric_d = 1;
        event->metric_d = (double) vl->values[index].gauge;
    }
    else if (rates != NULL)
    {
        event->has_metric_d = 1;
        event->metric_d = (double) rates[index];
    }
    else
    {
        event->has_metric_sint64 = 1;
        if (ds->ds[index].type == DS_TYPE_DERIVE)
            event->metric_sint64 = (int64_t) vl->values[index].derive;
        else if (ds->ds[index].type == DS_TYPE_ABSOLUTE)
            event->metric_sint64 = (int64_t) vl->values[index].absolute;
        else
            event->metric_sint64 = (int64_t) vl->values[index].counter;
    }

    format_name (name_buffer, sizeof (name_buffer),
                 /* host = */ "", vl->plugin, vl->plugin_instance,
                 vl->type, vl->type_instance);
    if (host->always_append_ds || (ds->ds_num > 1))
        ssnprintf (service_buffer, sizeof (service_buffer),
                   "%s/%s", &name_buffer[1], ds->ds[index].name);
    else
        sstrncpy (service_buffer, &name_buffer[1],
                  sizeof (service_buffer));

    event->service = strdup (service_buffer);

    DEBUG ("write_riemann plugin: Successfully created protobuf for metric: "
           "host = \"%s\", service = \"%s\"",
           event->host, event->service);
    return (event);
} /* }}} Event *riemann_value_to_protobuf */
示例#25
0
int uc_update (const data_set_t *ds, const value_list_t *vl)
{
    char name[6 * DATA_MAX_NAME_LEN];
    cache_entry_t *ce = NULL;
    int status;
    size_t i;

    if (FORMAT_VL (name, sizeof (name), vl) != 0)
    {
        ERROR ("uc_update: FORMAT_VL failed.");
        return (-1);
    }

    pthread_mutex_lock (&cache_lock);

    status = c_avl_get (cache_tree, name, (void *) &ce);
    if (status != 0) /* entry does not yet exist */
    {
        status = uc_insert (ds, vl, name);
        pthread_mutex_unlock (&cache_lock);
        return (status);
    }

    assert (ce != NULL);
    assert (ce->values_num == ds->ds_num);

    if (ce->last_time >= vl->time)
    {
        pthread_mutex_unlock (&cache_lock);
        NOTICE ("uc_update: Value too old: name = %s; value time = %.3f; "
                "last cache update = %.3f;",
                name,
                CDTIME_T_TO_DOUBLE (vl->time),
                CDTIME_T_TO_DOUBLE (ce->last_time));
        return (-1);
    }

    for (i = 0; i < ds->ds_num; i++)
    {
        switch (ds->ds[i].type)
        {
        case DS_TYPE_COUNTER:
        {
            counter_t diff = counter_diff (ce->values_raw[i].counter, vl->values[i].counter);
            ce->values_gauge[i] = ((double) diff)
                                  / (CDTIME_T_TO_DOUBLE (vl->time - ce->last_time));
            ce->values_raw[i].counter = vl->values[i].counter;
        }
        break;

        case DS_TYPE_GAUGE:
            ce->values_raw[i].gauge = vl->values[i].gauge;
            ce->values_gauge[i] = vl->values[i].gauge;
            break;

        case DS_TYPE_DERIVE:
        {
            derive_t diff = vl->values[i].derive - ce->values_raw[i].derive;

            ce->values_gauge[i] = ((double) diff)
                                  / (CDTIME_T_TO_DOUBLE (vl->time - ce->last_time));
            ce->values_raw[i].derive = vl->values[i].derive;
        }
        break;

        case DS_TYPE_ABSOLUTE:
            ce->values_gauge[i] = ((double) vl->values[i].absolute)
                                  / (CDTIME_T_TO_DOUBLE (vl->time - ce->last_time));
            ce->values_raw[i].absolute = vl->values[i].absolute;
            break;

        default:
            /* This shouldn't happen. */
            pthread_mutex_unlock (&cache_lock);
            ERROR ("uc_update: Don't know how to handle data source type %i.",
                   ds->ds[i].type);
            return (-1);
        } /* switch (ds->ds[i].type) */

        DEBUG ("uc_update: %s: ds[%zu] = %lf", name, i, ce->values_gauge[i]);
    } /* for (i) */

    /* Update the history if it exists. */
    if (ce->history != NULL)
    {
        assert (ce->history_index < ce->history_length);
        for (i = 0; i < ce->values_num; i++)
        {
            size_t hist_idx = (ce->values_num * ce->history_index) + i;
            ce->history[hist_idx] = ce->values_gauge[i];
        }

        assert (ce->history_length > 0);
        ce->history_index = (ce->history_index + 1) % ce->history_length;
    }

    /* Prune invalid gauge data */
    uc_check_range (ds, ce);

    ce->last_time = vl->time;
    ce->last_update = cdtime ();
    ce->interval = vl->interval;

    pthread_mutex_unlock (&cache_lock);

    return (0);
} /* int uc_update */
示例#26
0
static int wh_flush_nolock (cdtime_t timeout, wh_callback_t *cb) /* {{{ */
{
        int status;

        DEBUG ("write_http plugin: wh_flush_nolock: timeout = %.3f; "
                        "send_buffer_fill = %zu;",
                        CDTIME_T_TO_DOUBLE (timeout),
                        cb->send_buffer_fill);

        /* timeout == 0  => flush unconditionally */
        if (timeout > 0)
        {
                cdtime_t now;

                now = cdtime ();
                if ((cb->send_buffer_init_time + timeout) > now)
                        return (0);
        }

        if (cb->format == WH_FORMAT_COMMAND)
        {
                if (cb->send_buffer_fill == 0)
                {
                        cb->send_buffer_init_time = cdtime ();
                        return (0);
                }

                status = wh_send_buffer (cb);
                wh_reset_buffer (cb);
        }
        else if (cb->format == WH_FORMAT_JSON)
        {
                if (cb->send_buffer_fill <= 2)
                {
                        cb->send_buffer_init_time = cdtime ();
                        return (0);
                }

                status = format_json_finalize (cb->send_buffer,
                                &cb->send_buffer_fill,
                                &cb->send_buffer_free);
                if (status != 0)
                {
                        ERROR ("write_http: wh_flush_nolock: "
                                        "format_json_finalize failed.");
                        wh_reset_buffer (cb);
                        return (status);
                }

                status = wh_send_buffer (cb);
                wh_reset_buffer (cb);
        }
        else
        {
                ERROR ("write_http: wh_flush_nolock: "
                                "Unknown format: %i",
                                cb->format);
                return (-1);
        }

        return (status);
} /* }}} wh_flush_nolock */
示例#27
0
文件: statsd.c 项目: skolot/collectd
/* Must hold metrics_lock when calling this function. */
static int statsd_metric_submit_unsafe (statsd_config_t *conf, char const *name, /* {{{ */
    statsd_metric_t const *metric)
{
  value_t values[1];
  value_list_t vl = VALUE_LIST_INIT;
  char *global_prefix = NULL;
  char *type_prefix = NULL;
  char *global_postfix = NULL;
  char full_name[DATA_MAX_NAME_LEN] = {0};

  DEBUG("statsd plugin: submit metric");

  vl.values = values;
  vl.values_len = 1;
  sstrncpy (vl.host, hostname_g, sizeof (vl.host));
  sstrncpy (vl.plugin, "statsd", sizeof (vl.plugin));
  sstrncpy (vl.plugin_instance, conf->node_name, sizeof (vl.plugin_instance));

  global_prefix = (NULL == conf->global_prefix) ? "" : conf->global_prefix;
  global_postfix = (NULL == conf->global_postfix) ? "" : conf->global_postfix;

  switch (metric->type) {
  case STATSD_GAUGE:
    sstrncpy (vl.type, "gauge", sizeof (vl.type));
    type_prefix = (NULL == conf->gauge_prefix) ? "" : conf->gauge_prefix;
    break;
  case STATSD_TIMER:
    sstrncpy (vl.type, "latency", sizeof (vl.type));
    type_prefix = (NULL == conf->timer_prefix) ? "" : conf->timer_prefix;
    break;
  case STATSD_SET:
    sstrncpy (vl.type, "objects", sizeof (vl.type));
    type_prefix = (NULL == conf->set_prefix) ? "" : conf->set_prefix;
    break;
  case STATSD_COUNTER:
    sstrncpy (vl.type, "derive", sizeof (vl.type));
    type_prefix = (NULL == conf->counter_prefix) ? "" : conf->counter_prefix;
    break;
  default:
    ERROR("statsd plugin: unknow metrics type %d", metric->type);
  }

  ssnprintf(full_name, sizeof(full_name), "%s%s%s%s", global_prefix, type_prefix, name, global_postfix);
  DEBUG("statsd plugin: metric name %s", full_name);
  sstrncpy (vl.type_instance, full_name, sizeof (vl.type_instance));

  if (metric->type == STATSD_GAUGE)
    values[0].gauge = (gauge_t) metric->value;
  else if (metric->type == STATSD_TIMER)
  {
    size_t i;
    _Bool have_events = (metric->updates_num > 0);

    /* Make sure all timer metrics share the *same* timestamp. */
    vl.time = cdtime ();

    if (!conf->leave_metrics_name_asis)
      ssnprintf (vl.type_instance, sizeof (vl.type_instance),
                 "%s-average", full_name);
    values[0].gauge = have_events
      ? CDTIME_T_TO_DOUBLE (latency_counter_get_average (metric->latency))
      : NAN;
    plugin_dispatch_values (&vl);

    if (conf->timer_lower) {
      ssnprintf (vl.type_instance, sizeof (vl.type_instance),
          "%s-lower", full_name);
      values[0].gauge = have_events
        ? CDTIME_T_TO_DOUBLE (latency_counter_get_min (metric->latency))
        : NAN;
      plugin_dispatch_values (&vl);
    }

    if (conf->timer_upper) {
      ssnprintf (vl.type_instance, sizeof (vl.type_instance),
          "%s-upper", full_name);
      values[0].gauge = have_events
        ? CDTIME_T_TO_DOUBLE (latency_counter_get_max (metric->latency))
        : NAN;
      plugin_dispatch_values (&vl);
    }

    if (conf->timer_sum) {
      ssnprintf (vl.type_instance, sizeof (vl.type_instance),
          "%s-sum", full_name);
      values[0].gauge = have_events
        ? CDTIME_T_TO_DOUBLE (latency_counter_get_sum (metric->latency))
        : NAN;
      plugin_dispatch_values (&vl);
    }

    for (i = 0; i < conf->timer_percentile_num; i++)
    {
      ssnprintf (vl.type_instance, sizeof (vl.type_instance),
          "%s-percentile-%.0f", full_name, conf->timer_percentile[i]);
      values[0].gauge = have_events
        ? CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (metric->latency, conf->timer_percentile[i]))
        : NAN;
      plugin_dispatch_values (&vl);
    }

    /* Keep this at the end, since vl.type is set to "gauge" here. The
     * vl.type's above are implicitly set to "latency". */
    if (conf->timer_count) {
      sstrncpy (vl.type, "gauge", sizeof (vl.type));
      ssnprintf (vl.type_instance, sizeof (vl.type_instance),
          "%s-count", full_name);
      values[0].gauge = latency_counter_get_num (metric->latency);
      plugin_dispatch_values (&vl);
    }

    latency_counter_reset (metric->latency);
    return (0);
  }
  else if (metric->type == STATSD_SET)
  {
    if (metric->set == NULL)
      values[0].gauge = 0.0;
    else
      values[0].gauge = (gauge_t) c_avl_size (metric->set);
  }
  else { /* STATSD_COUNTER */
      /*
       * Expand a single value to two metrics:
       *
       * - The absolute counter, as a gauge
       * - A derived rate for this counter
       */
      values[0].derive = (derive_t) metric->value;
      plugin_dispatch_values(&vl);

      sstrncpy(vl.type, "gauge", sizeof (vl.type));
      values[0].gauge = (gauge_t) metric->value;
  }

  return (plugin_dispatch_values (&vl));
} /* }}} int statsd_metric_submit_unsafe */
示例#28
0
文件: statsd.c 项目: dacamp/collectd
/* Must hold metrics_lock when calling this function. */
static int statsd_metric_submit_unsafe (char const *name, /* {{{ */
    statsd_metric_t const *metric)
{
  value_t values[1];
  value_list_t vl = VALUE_LIST_INIT;

  vl.values = values;
  vl.values_len = 1;
  sstrncpy (vl.host, hostname_g, sizeof (vl.host));
  sstrncpy (vl.plugin, "statsd", sizeof (vl.plugin));

  if (metric->type == STATSD_GAUGE)
    sstrncpy (vl.type, "gauge", sizeof (vl.type));
  else if (metric->type == STATSD_TIMER)
    sstrncpy (vl.type, "latency", sizeof (vl.type));
  else if (metric->type == STATSD_SET)
    sstrncpy (vl.type, "objects", sizeof (vl.type));
  else /* if (metric->type == STATSD_COUNTER) */
    sstrncpy (vl.type, "derive", sizeof (vl.type));

  sstrncpy (vl.type_instance, name, sizeof (vl.type_instance));

  if (metric->type == STATSD_GAUGE)
    values[0].gauge = (gauge_t) metric->value;
  else if (metric->type == STATSD_TIMER)
  {
    size_t i;
    _Bool have_events = (metric->updates_num > 0);

    /* Make sure all timer metrics share the *same* timestamp. */
    vl.time = cdtime ();

    ssnprintf (vl.type_instance, sizeof (vl.type_instance),
        "%s-average", name);
    values[0].gauge = have_events
      ? CDTIME_T_TO_DOUBLE (latency_counter_get_average (metric->latency))
      : NAN;
    plugin_dispatch_values (&vl);

    if (conf_timer_lower) {
      ssnprintf (vl.type_instance, sizeof (vl.type_instance),
          "%s-lower", name);
      values[0].gauge = have_events
        ? CDTIME_T_TO_DOUBLE (latency_counter_get_min (metric->latency))
        : NAN;
      plugin_dispatch_values (&vl);
    }

    if (conf_timer_upper) {
      ssnprintf (vl.type_instance, sizeof (vl.type_instance),
          "%s-upper", name);
      values[0].gauge = have_events
        ? CDTIME_T_TO_DOUBLE (latency_counter_get_max (metric->latency))
        : NAN;
      plugin_dispatch_values (&vl);
    }

    if (conf_timer_sum) {
      ssnprintf (vl.type_instance, sizeof (vl.type_instance),
          "%s-sum", name);
      values[0].gauge = have_events
        ? CDTIME_T_TO_DOUBLE (latency_counter_get_sum (metric->latency))
        : NAN;
      plugin_dispatch_values (&vl);
    }

    for (i = 0; i < conf_timer_percentile_num; i++)
    {
      ssnprintf (vl.type_instance, sizeof (vl.type_instance),
          "%s-percentile-%.0f", name, conf_timer_percentile[i]);
      values[0].gauge = have_events
        ? CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (metric->latency, conf_timer_percentile[i]))
        : NAN;
      plugin_dispatch_values (&vl);
    }

    /* Keep this at the end, since vl.type is set to "gauge" here. The
     * vl.type's above are implicitly set to "latency". */
    if (conf_timer_count) {
      sstrncpy (vl.type, "gauge", sizeof (vl.type));
      ssnprintf (vl.type_instance, sizeof (vl.type_instance),
          "%s-count", name);
      values[0].gauge = latency_counter_get_num (metric->latency);
      plugin_dispatch_values (&vl);
    }

    latency_counter_reset (metric->latency);
    return (0);
  }
  else if (metric->type == STATSD_SET)
  {
    if (metric->set == NULL)
      values[0].gauge = 0.0;
    else
      values[0].gauge = (gauge_t) c_avl_size (metric->set);
  }
  else
    values[0].derive = (derive_t) metric->value;

  return (plugin_dispatch_values (&vl));
} /* }}} int statsd_metric_submit_unsafe */
示例#29
0
/*
 * Functions
 */
static int wr_write (const data_set_t *ds, /* {{{ */
    const value_list_t *vl,
    user_data_t *ud)
{
  wr_node_t *node = ud->data;
  char ident[512];
  char key[512];
  char value[512];
  char time[24];
  size_t value_size;
  char *value_ptr;
  int status;
  redisReply   *rr;

  status = FORMAT_VL (ident, sizeof (ident), vl);
  if (status != 0)
    return (status);
  ssnprintf (key, sizeof (key), "%s%s",
      (node->prefix != NULL) ? node->prefix : REDIS_DEFAULT_PREFIX,
      ident);
  ssnprintf (time, sizeof (time), "%.9f", CDTIME_T_TO_DOUBLE(vl->time));

  memset (value, 0, sizeof (value));
  value_size = sizeof (value);
  value_ptr = &value[0];
  status = format_values (value_ptr, value_size, ds, vl, node->store_rates);
  if (status != 0)
    return (status);

  pthread_mutex_lock (&node->lock);

  if (node->conn == NULL)
  {
    node->conn = redisConnectWithTimeout ((char *)node->host, node->port, node->timeout);
    if (node->conn == NULL)
    {
      ERROR ("write_redis plugin: Connecting to host \"%s\" (port %i) failed: Unkown reason",
          (node->host != NULL) ? node->host : "localhost",
          (node->port != 0) ? node->port : 6379);
      pthread_mutex_unlock (&node->lock);
      return (-1);
    }
    else if (node->conn->err)
    {
      ERROR ("write_redis plugin: Connecting to host \"%s\" (port %i) failed: %s",
          (node->host != NULL) ? node->host : "localhost",
          (node->port != 0) ? node->port : 6379,
          node->conn->errstr);
      pthread_mutex_unlock (&node->lock);
      return (-1);
    }

    rr = redisCommand(node->conn, "SELECT %d", node->database);
    if (rr == NULL)
      WARNING("SELECT command error. database:%d message:%s", node->database, node->conn->errstr);
    else
      freeReplyObject (rr);
  }

  rr = redisCommand (node->conn, "ZADD %s %s %s", key, time, value);
  if (rr == NULL)
    WARNING("ZADD command error. key:%s message:%s", key, node->conn->errstr);
  else
    freeReplyObject (rr);

  if (node->max_set_size >= 0)
  {
    rr = redisCommand (node->conn, "ZREMRANGEBYRANK %s %d %d", key, 0, (-1 * node->max_set_size) - 1);
    if (rr == NULL)
      WARNING("ZREMRANGEBYRANK command error. key:%s message:%s", key, node->conn->errstr);
    else
      freeReplyObject (rr);
  }

  /* TODO(octo): This is more overhead than necessary. Use the cache and
   * metadata to determine if it is a new metric and call SADD only once for
   * each metric. */
  rr = redisCommand (node->conn, "SADD %svalues %s",
      (node->prefix != NULL) ? node->prefix : REDIS_DEFAULT_PREFIX,
      ident);
  if (rr==NULL)
    WARNING("SADD command error. ident:%s message:%s", ident, node->conn->errstr);
  else
    freeReplyObject (rr);

  pthread_mutex_unlock (&node->lock);

  return (0);
} /* }}} int wr_write */
示例#30
0
static int uc_insert (const data_set_t *ds, const value_list_t *vl,
                      const char *key)
{
    char *key_copy;
    cache_entry_t *ce;
    size_t i;

    /* `cache_lock' has been locked by `uc_update' */

    key_copy = strdup (key);
    if (key_copy == NULL)
    {
        ERROR ("uc_insert: strdup failed.");
        return (-1);
    }

    ce = cache_alloc (ds->ds_num);
    if (ce == NULL)
    {
        sfree (key_copy);
        ERROR ("uc_insert: cache_alloc (%zu) failed.", ds->ds_num);
        return (-1);
    }

    sstrncpy (ce->name, key, sizeof (ce->name));

    for (i = 0; i < ds->ds_num; i++)
    {
        switch (ds->ds[i].type)
        {
        case DS_TYPE_COUNTER:
            ce->values_gauge[i] = NAN;
            ce->values_raw[i].counter = vl->values[i].counter;
            break;

        case DS_TYPE_GAUGE:
            ce->values_gauge[i] = vl->values[i].gauge;
            ce->values_raw[i].gauge = vl->values[i].gauge;
            break;

        case DS_TYPE_DERIVE:
            ce->values_gauge[i] = NAN;
            ce->values_raw[i].derive = vl->values[i].derive;
            break;

        case DS_TYPE_ABSOLUTE:
            ce->values_gauge[i] = NAN;
            if (vl->interval > 0)
                ce->values_gauge[i] = ((double) vl->values[i].absolute)
                                      / CDTIME_T_TO_DOUBLE (vl->interval);
            ce->values_raw[i].absolute = vl->values[i].absolute;
            break;

        default:
            /* This shouldn't happen. */
            ERROR ("uc_insert: Don't know how to handle data source type %i.",
                   ds->ds[i].type);
            sfree (key_copy);
            cache_free (ce);
            return (-1);
        } /* switch (ds->ds[i].type) */
    } /* for (i) */

    /* Prune invalid gauge data */
    uc_check_range (ds, ce);

    ce->last_time = vl->time;
    ce->last_update = cdtime ();
    ce->interval = vl->interval;
    ce->state = STATE_OKAY;

    if (c_avl_insert (cache_tree, key_copy, ce) != 0)
    {
        sfree (key_copy);
        ERROR ("uc_insert: c_avl_insert failed.");
        return (-1);
    }

    DEBUG ("uc_insert: Added %s to the cache.", key);
    return (0);
} /* int uc_insert */