コード例 #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
ファイル: utils_cmd_putval.c プロジェクト: KIvosak/collectd
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 */
コード例 #3
0
ファイル: utils_cache.c プロジェクト: tabletcorry/collectd
/* XXX: This function will acquire `cache_lock' but will not free it! */
static meta_data_t *uc_get_meta (const value_list_t *vl) /* {{{ */
{
  char name[6 * DATA_MAX_NAME_LEN];
  cache_entry_t *ce = NULL;
  int status;

  status = FORMAT_VL (name, sizeof (name), vl);
  if (status != 0)
  {
    ERROR ("utils_cache: uc_get_meta: FORMAT_VL failed.");
    return (NULL);
  }

  pthread_mutex_lock (&cache_lock);

  status = c_avl_get (cache_tree, name, (void *) &ce);
  if (status != 0)
  {
    pthread_mutex_unlock (&cache_lock);
    return (NULL);
  }
  assert (ce != NULL);

  if (ce->meta == NULL)
    ce->meta = meta_data_create ();

  if (ce->meta == NULL)
    pthread_mutex_unlock (&cache_lock);

  return (ce->meta);
} /* }}} meta_data_t *uc_get_meta */
コード例 #4
0
ファイル: utils_cache.c プロジェクト: tabletcorry/collectd
gauge_t *uc_get_rate (const data_set_t *ds, const value_list_t *vl)
{
  char name[6 * DATA_MAX_NAME_LEN];
  gauge_t *ret = NULL;
  size_t ret_num = 0;
  int status;

  if (FORMAT_VL (name, sizeof (name), vl) != 0)
  {
    ERROR ("utils_cache: uc_get_rate: FORMAT_VL failed.");
    return (NULL);
  }

  status = uc_get_rate_by_name (name, &ret, &ret_num);
  if (status != 0)
    return (NULL);

  /* This is important - the caller has no other way of knowing how many
   * values are returned. */
  if (ret_num != (size_t) ds->ds_num)
  {
    ERROR ("utils_cache: uc_get_rate: ds[%s] has %i values, "
	"but uc_get_rate_by_name returned %zu.",
	ds->type, ds->ds_num, ret_num);
    sfree (ret);
    return (NULL);
  }

  return (ret);
} /* gauge_t *uc_get_rate */
コード例 #5
0
ファイル: utils_cache.c プロジェクト: tabletcorry/collectd
int uc_inc_hits (const data_set_t *ds, const value_list_t *vl, int step)
{
  char name[6 * DATA_MAX_NAME_LEN];
  cache_entry_t *ce = NULL;
  int ret = -1;

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

  pthread_mutex_lock (&cache_lock);

  if (c_avl_get (cache_tree, name, (void *) &ce) == 0)
  {
    assert (ce != NULL);
    ret = ce->hits;
    ce->hits = ret + step;
  }

  pthread_mutex_unlock (&cache_lock);

  return (ret);
} /* int uc_inc_hits */
コード例 #6
0
ファイル: rrdcached.c プロジェクト: EMSL-MSC/collectd
static int value_list_to_filename(char *buffer, size_t buffer_size,
                                  value_list_t const *vl) {
  char const suffix[] = ".rrd";
  int status;
  size_t len;

  if (datadir != NULL) {
    size_t datadir_len = strlen(datadir) + 1;

    if (datadir_len >= buffer_size)
      return ENOMEM;

    sstrncpy(buffer, datadir, buffer_size);
    buffer[datadir_len - 1] = '/';
    buffer[datadir_len] = 0;

    buffer += datadir_len;
    buffer_size -= datadir_len;
  }

  status = FORMAT_VL(buffer, buffer_size, vl);
  if (status != 0)
    return status;

  len = strlen(buffer);
  assert(len < buffer_size);
  buffer += len;
  buffer_size -= len;

  if (buffer_size <= sizeof(suffix))
    return ENOMEM;

  memcpy(buffer, suffix, sizeof(suffix));
  return 0;
} /* int value_list_to_filename */
コード例 #7
0
ファイル: utils_cache.c プロジェクト: tabletcorry/collectd
int uc_get_history (const data_set_t *ds, const value_list_t *vl,
    gauge_t *ret_history, size_t num_steps, size_t num_ds)
{
  char name[6 * DATA_MAX_NAME_LEN];

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

  return (uc_get_history_by_name (name, ret_history, num_steps, num_ds));
} /* int uc_get_history */
コード例 #8
0
/* Update the num, sum, min, max, ... fields of the aggregation instance, if
 * the rate of the value list is available. Value lists with more than one data
 * source are not supported and will return an error. Returns zero on success
 * and non-zero otherwise. */
static int agg_instance_update (agg_instance_t *inst, /* {{{ */
    data_set_t const *ds, value_list_t const *vl)
{
  gauge_t *rate;

  if (ds->ds_num != 1)
  {
    ERROR ("aggregation plugin: The \"%s\" type (data set) has more than one "
        "data source. This is currently not supported by this plugin. "
        "Sorry.", ds->type);
    return (EINVAL);
  }

  rate = uc_get_rate (ds, vl);
  if (rate == NULL)
  {
    char ident[6 * DATA_MAX_NAME_LEN];
    FORMAT_VL (ident, sizeof (ident), vl);
    ERROR ("aggregation plugin: Unable to read the current rate of \"%s\".",
        ident);
    return (ENOENT);
  }

  if (isnan (rate[0]))
  {
    sfree (rate);
    return (0);
  }

  pthread_mutex_lock (&inst->lock);

  inst->num++;
  inst->sum += rate[0];
  inst->squares_sum += (rate[0] * rate[0]);

  if (isnan (inst->min) || (inst->min > rate[0]))
    inst->min = rate[0];
  if (isnan (inst->max) || (inst->max < rate[0]))
    inst->max = rate[0];

  pthread_mutex_unlock (&inst->lock);

  sfree (rate);
  return (0);
} /* }}} int agg_instance_update */
コード例 #9
0
ファイル: write_redis.c プロジェクト: 01BTC10/collectd
/*
 * 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 */
コード例 #10
0
ファイル: utils_cache.c プロジェクト: tabletcorry/collectd
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 send_okay_notification = 0;
  time_t update_delay = 0;
  notification_t n;
  int status;
  int 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 = %u; "
	"last cache update = %u;",
	name, (unsigned int) vl->time, (unsigned int) ce->last_time);
    return (-1);
  }

  /* Send a notification (after the lock has been released) if we switch the
   * state from something else to `okay'. */
  if (ce->state == STATE_MISSING)
  {
    send_okay_notification = 1;
    ce->state = STATE_OKAY;
    update_delay = time (NULL) - ce->last_update;
  }

  for (i = 0; i < ds->ds_num; i++)
  {
    switch (ds->ds[i].type)
    {
      case DS_TYPE_COUNTER:
	{
	  counter_t diff;

	  /* check if the counter has wrapped around */
	  if (vl->values[i].counter < ce->values_raw[i].counter)
	  {
	    if (ce->values_raw[i].counter <= 4294967295U)
	      diff = (4294967295U - ce->values_raw[i].counter)
		+ vl->values[i].counter;
	    else
	      diff = (18446744073709551615ULL - ce->values_raw[i].counter)
		+ vl->values[i].counter;
	  }
	  else /* counter has NOT wrapped around */
	  {
	    diff = vl->values[i].counter - ce->values_raw[i].counter;
	  }

	  ce->values_gauge[i] = ((double) diff)
	    / ((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;

	  diff = vl->values[i].derive - ce->values_raw[i].derive;

	  ce->values_gauge[i] = ((double) diff)
	    / ((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)
	  / ((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[%i] = %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 = time (NULL);
  ce->interval = vl->interval;

  pthread_mutex_unlock (&cache_lock);

  if (send_okay_notification == 0)
    return (0);

  /* Do not send okay notifications for uninteresting values, i. e. values for
   * which no threshold is configured. */
  status = ut_check_interesting (name);
  if (status <= 0)
    return (0);

  /* Initialize the notification */
  memset (&n, '\0', sizeof (n));
  NOTIFICATION_INIT_VL (&n, vl, ds);

  n.severity = NOTIF_OKAY;
  n.time = vl->time;

  ssnprintf (n.message, sizeof (n.message),
      "Received a value for %s. It was missing for %u seconds.",
      name, (unsigned int) update_delay);

  plugin_dispatch_notification (&n);

  return (0);
} /* int uc_update */
コード例 #11
0
ファイル: utils_cache.c プロジェクト: beorn-/collectd
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 */
コード例 #12
0
static int network_dispatch_values (value_list_t *vl, /* {{{ */
    const char *username)
{
  int status;
  
  // DEBUG("host: %s", vl->host);
  // DEBUG("plugin: %s", vl->plugin);
  // DEBUG("plugin_instance: %s", vl->plugin_instance);
  // DEBUG("type: %s", vl->type);
  // DEBUG("type_instance: %s", vl->type_instance);

  if ((vl->time <= 0)
      || (strlen (vl->host) <= 0)
      || (strlen (vl->plugin) <= 0)
      || (strlen (vl->type) <= 0))
    return (-EINVAL);
  
  if (!check_receive_okay (vl))
  {
#if COLLECT_DEBUG
    char name[6*DATA_MAX_NAME_LEN];
    FORMAT_VL (name, sizeof (name), vl);
    name[sizeof (name) - 1] = 0;
    DEBUG ("network plugin: network_dispatch_values: "
	"NOT dispatching %s.", name);
#endif
    stats_values_not_dispatched++;
    return (0);
  }

  assert (vl->meta == NULL);

  vl->meta = meta_data_create ();
  if (vl->meta == NULL)
  {
    ERROR ("network plugin: meta_data_create failed.");
    return (-ENOMEM);
  }

  status = meta_data_add_boolean (vl->meta, "zeromq:received", 1);
  if (status != 0)
  {
    ERROR ("network plugin: meta_data_add_boolean failed.");
    meta_data_destroy (vl->meta);
    vl->meta = NULL;
    return (status);
  }

  if (username != NULL)
  {
    status = meta_data_add_string (vl->meta, "zeromq:username", username);
    if (status != 0)
    {
      ERROR ("network plugin: meta_data_add_string failed.");
      meta_data_destroy (vl->meta);
      vl->meta = NULL;
      return (status);
    }
  }
  
  // DEBUG("dispatching %d values", vl->values_len);
  plugin_dispatch_values (vl);
  stats_values_dispatched++;

  meta_data_destroy (vl->meta);
  vl->meta = NULL;

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