Esempio n. 1
0
latency_counter_t *latency_counter_create (void) /* {{{ */
{
  latency_counter_t *lc;

  lc = calloc (1, sizeof (*lc));
  if (lc == NULL)
    return (NULL);

  latency_counter_reset (lc);
  lc->bin_width = HISTOGRAM_DEFAULT_BIN_WIDTH;
  return (lc);
} /* }}} latency_counter_t *latency_counter_create */
Esempio n. 2
0
/* 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 */
Esempio n. 3
0
/* Must hold metrics_lock when calling this function. */
static int statsd_metric_submit_unsafe (char const *name, statsd_metric_t *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 { /* STATSD_COUNTER */
    gauge_t delta = nearbyint (metric->value);

    /* Etsy's statsd writes counters as two metrics: a rate and the change since
     * the last write. Since collectd does not reset its DERIVE metrics to zero,
     * this makes little sense, but we're dispatching a "count" metric here
     * anyway - if requested by the user - for compatibility reasons. */
    if (conf_counter_sum)
    {
      sstrncpy (vl.type, "count", sizeof (vl.type));
      values[0].gauge = delta;
      plugin_dispatch_values (&vl);

      /* restore vl.type */
      sstrncpy (vl.type, "derive", sizeof (vl.type));
    }

    /* Rather than resetting value to zero, subtract delta so we correctly keep
     * track of residuals. */
    metric->value   -= delta;
    metric->counter += (derive_t) delta;

    values[0].derive = metric->counter;
  }

  return (plugin_dispatch_values (&vl));
} /* }}} int statsd_metric_submit_unsafe */
Esempio n. 4
0
/* 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 */
Esempio n. 5
0
static int latency_submit_match(cu_match_t *match, void *user_data) {
  cu_tail_match_simple_t *data = (cu_tail_match_simple_t *)user_data;
  cu_match_value_t *match_value;
  value_list_t vl = VALUE_LIST_INIT;

  match_value = (cu_match_value_t *)match_get_user_data(match);
  if (match_value == NULL)
    return (-1);

  sstrncpy(vl.host, hostname_g, sizeof(vl.host));
  sstrncpy(vl.plugin, data->plugin, sizeof(vl.plugin));
  sstrncpy(vl.plugin_instance, data->plugin_instance,
           sizeof(vl.plugin_instance));
  vl.interval = data->interval;
  vl.time = cdtime();

  /* Submit percentiles */
  sstrncpy(vl.type, data->type, sizeof(vl.type));
  for (size_t i = 0; i < data->latency_config.percentile_num; i++) {
    if (strlen(data->type_instance) != 0)
      ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%s-%.0f",
                data->type_instance, data->latency_config.percentile[i]);
    else
      ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%.0f",
                data->latency_config.percentile[i]);

    vl.values = &(value_t){
        .gauge =
            (match_value->values_num != 0)
                ? CDTIME_T_TO_DOUBLE(latency_counter_get_percentile(
                      match_value->latency, data->latency_config.percentile[i]))
                : NAN,
    };
    vl.values_len = 1;

    plugin_dispatch_values(&vl);
  }

  /* Submit buckets */
  sstrncpy(vl.type, "bucket", sizeof(vl.type));
  for (size_t i = 0; i < data->latency_config.buckets_num; i++) {
    latency_bucket_t bucket = data->latency_config.buckets[i];

    double lower_bound = CDTIME_T_TO_DOUBLE(bucket.lower_bound);
    double upper_bound =
        bucket.upper_bound ? CDTIME_T_TO_DOUBLE(bucket.upper_bound) : INFINITY;

    if (strlen(data->type_instance) != 0)
      ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%s-%s-%g_%g",
                data->type, data->type_instance, lower_bound, upper_bound);
    else
      ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%s-%g_%g",
                data->type, lower_bound, upper_bound);

    vl.values = &(value_t){
        .gauge =
            latency_counter_get_rate(match_value->latency, bucket.lower_bound,
                                     bucket.upper_bound, vl.time),
    };
    vl.values_len = 1;

    plugin_dispatch_values(&vl);
  }

  match_value->value.gauge = NAN;
  match_value->values_num = 0;
  latency_counter_reset(match_value->latency);

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

static int tail_callback(void *data, char *buf,
                         int __attribute__((unused)) buflen) {
  cu_tail_match_t *obj = (cu_tail_match_t *)data;

  for (size_t i = 0; i < obj->matches_num; i++)
    match_apply(obj->matches[i].match, buf);

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

static void tail_match_simple_free(void *data) {
  cu_tail_match_simple_t *user_data = (cu_tail_match_simple_t *)data;
  latency_config_free(user_data->latency_config);
  sfree(user_data);
} /* void tail_match_simple_free */

/*
 * Public functions
 */
cu_tail_match_t *tail_match_create(const char *filename) {
  cu_tail_match_t *obj;

  obj = calloc(1, sizeof(*obj));
  if (obj == NULL)
    return (NULL);

  obj->tail = cu_tail_create(filename);
  if (obj->tail == NULL) {
    sfree(obj);
    return (NULL);
  }

  return (obj);
} /* cu_tail_match_t *tail_match_create */