示例#1
0
static int dsnames_to_json(char *buffer, size_t buffer_size, /* {{{ */
                           const data_set_t *ds) {
  size_t offset = 0;

  memset(buffer, 0, buffer_size);

#define BUFFER_ADD(...)                                                        \
  do {                                                                         \
    int status;                                                                \
    status = ssnprintf(buffer + offset, buffer_size - offset, __VA_ARGS__);    \
    if (status < 1)                                                            \
      return (-1);                                                             \
    else if (((size_t)status) >= (buffer_size - offset))                       \
      return (-ENOMEM);                                                        \
    else                                                                       \
      offset += ((size_t)status);                                              \
  } while (0)

  BUFFER_ADD("[");
  for (size_t i = 0; i < ds->ds_num; i++) {
    if (i > 0)
      BUFFER_ADD(",");

    BUFFER_ADD("\"%s\"", ds->ds[i].name);
  } /* for ds->ds_num */
  BUFFER_ADD("]");

#undef BUFFER_ADD

  DEBUG("format_json: dsnames_to_json: buffer = %s;", buffer);

  return (0);
} /* }}} int dsnames_to_json */
示例#2
0
static int gr_format_values (char *ret, size_t ret_len,
        int ds_num, const data_set_t *ds, const value_list_t *vl,
        gauge_t const *rates)
{
    size_t offset = 0;
    int status;

    assert (0 == strcmp (ds->type, vl->type));

    memset (ret, 0, ret_len);

#define BUFFER_ADD(...) do { \
    status = ssnprintf (ret + offset, ret_len - offset, \
            __VA_ARGS__); \
    if (status < 1) \
    { \
        return (-1); \
    } \
    else if (((size_t) status) >= (ret_len - offset)) \
    { \
        return (-1); \
    } \
    else \
    offset += ((size_t) status); \
} while (0)

    if (ds->ds[ds_num].type == DS_TYPE_GAUGE)
        BUFFER_ADD (GAUGE_FORMAT, vl->values[ds_num].gauge);
    else if (rates != NULL)
        BUFFER_ADD ("%f", rates[ds_num]);
    else if (ds->ds[ds_num].type == DS_TYPE_COUNTER)
        BUFFER_ADD ("%llu", vl->values[ds_num].counter);
    else if (ds->ds[ds_num].type == DS_TYPE_DERIVE)
        BUFFER_ADD ("%"PRIi64, vl->values[ds_num].derive);
    else if (ds->ds[ds_num].type == DS_TYPE_ABSOLUTE)
        BUFFER_ADD ("%"PRIu64, vl->values[ds_num].absolute);
    else
    {
        ERROR ("gr_format_values plugin: Unknown data source type: %i",
                ds->ds[ds_num].type);
        return (-1);
    }

#undef BUFFER_ADD

    return (0);
}
static int kairosdb_escape_string(char *buffer, size_t buffer_size, /* {{{ */
                                  const char *string) {
  size_t dst_pos;

  if ((buffer == NULL) || (string == NULL))
    return -EINVAL;

  if (buffer_size < 3)
    return -ENOMEM;

  dst_pos = 0;

#define BUFFER_ADD(c)                                                          \
  do {                                                                         \
    if (dst_pos >= (buffer_size - 1)) {                                        \
      buffer[buffer_size - 1] = '\0';                                          \
      return -ENOMEM;                                                          \
    }                                                                          \
    buffer[dst_pos] = (c);                                                     \
    dst_pos++;                                                                 \
  } while (0)

  /* Escape special characters */
  /* authorize -_. and alpha num but also escapes " */
  BUFFER_ADD('"');
  for (size_t src_pos = 0; string[src_pos] != 0; src_pos++) {
    if (isalnum(string[src_pos]) || 0x2d == string[src_pos] ||
        0x2e == string[src_pos] || 0x5f == string[src_pos])
      BUFFER_ADD(tolower(string[src_pos]));
  } /* for */
  BUFFER_ADD('"');
  buffer[dst_pos] = 0;

#undef BUFFER_ADD

  return 0;
} /* }}} int kairosdb_escape_string */
static int escape_string (char *buffer, size_t buffer_size, /* {{{ */
    const char *string)
{
  size_t src_pos;
  size_t dst_pos;

  if ((buffer == NULL) || (string == NULL))
    return (-EINVAL);

  if (buffer_size < 3)
    return (-ENOMEM);

  dst_pos = 0;

#define BUFFER_ADD(c) do { \
  if (dst_pos >= (buffer_size - 1)) { \
    buffer[buffer_size - 1] = 0; \
    return (-ENOMEM); \
  } \
  buffer[dst_pos] = (c); \
  dst_pos++; \
} while (0)

  /* Escape special characters */
  BUFFER_ADD ('"');
  for (src_pos = 0; string[src_pos] != 0; src_pos++)
  {
    if ((string[src_pos] == '"')
        || (string[src_pos] == '\\'))
    {
      BUFFER_ADD ('\\');
      BUFFER_ADD (string[src_pos]);
    }
    else if (string[src_pos] <= 0x001F)
      BUFFER_ADD ('?');
    else
      BUFFER_ADD (string[src_pos]);
  } /* for */
  BUFFER_ADD ('"');
  buffer[dst_pos] = 0;

#undef BUFFER_ADD

  return (0);
} /* }}} int buffer_add_string */
示例#5
0
文件: ceph.c 项目: Zanop/collectd
static int
ceph_cb_number(void *ctx, const char *number_val, yajl_len_t number_len)
{
    yajl_struct *state = (yajl_struct*) ctx;
    char buffer[number_len+1];
    char key[2 * DATA_MAX_NAME_LEN];
    _Bool latency_type = 0;
    size_t i;
    int status;

    memcpy(buffer, number_val, number_len);
    buffer[sizeof(buffer) - 1] = 0;

    memset (key, 0, sizeof (key));
    for (i = 0; i < state->depth; i++)
    {
        if (state->stack[i] == NULL)
            continue;

        if (strlen (key) != 0)
            BUFFER_ADD (key, ".");
        BUFFER_ADD (key, state->stack[i]);
    }

    /* Special case for latency metrics. */
    if ((strcmp ("avgcount", state->key) == 0)
        || (strcmp ("sum", state->key) == 0))
    {
        latency_type = 1;

        /* Super-special case for filestore.journal_wr_bytes.avgcount: For
         * some reason, Ceph schema encodes this as a count/sum pair while all
         * other "Bytes" data (excluding used/capacity bytes for OSD space) uses
         * a single "Derive" type. To spare further confusion, keep this KPI as
         * the same type of other "Bytes". Instead of keeping an "average" or
         * "rate", use the "sum" in the pair and assign that to the derive
         * value. */
        if (convert_special_metrics && (state->depth >= 2)
            && (strcmp("filestore", state->stack[state->depth - 2]) == 0)
            && (strcmp("journal_wr_bytes", state->stack[state->depth - 1]) == 0)
            && (strcmp("avgcount", state->key) == 0))
        {
            DEBUG("ceph plugin: Skipping avgcount for filestore.JournalWrBytes");
            return CEPH_CB_CONTINUE;
        }
    }
    else /* not a latency type */
    {
        BUFFER_ADD (key, ".");
        BUFFER_ADD (key, state->key);
    }

    status = state->handler(state->handler_arg, buffer, key);
    if((status == RETRY_AVGCOUNT) && latency_type)
    {
        /* Add previously skipped part of the key, either "avgcount" or "sum",
         * and try again. */
        BUFFER_ADD (key, ".");
        BUFFER_ADD (key, state->key);

        status = state->handler(state->handler_arg, buffer, key);
    }

    if (status != 0)
    {
        ERROR("ceph plugin: JSON handler failed with status %d.", status);
        return CEPH_CB_ABORT;
    }

    return CEPH_CB_CONTINUE;
}
static int values_to_json (char *buffer, size_t buffer_size, /* {{{ */
                const data_set_t *ds, const value_list_t *vl, int store_rates)
{
  size_t offset = 0;
  int i;
  gauge_t *rates = NULL;

  memset (buffer, 0, buffer_size);

#define BUFFER_ADD(...) do { \
  int status; \
  status = ssnprintf (buffer + offset, buffer_size - offset, \
      __VA_ARGS__); \
  if (status < 1) \
  { \
    sfree(rates); \
    return (-1); \
  } \
  else if (((size_t) status) >= (buffer_size - offset)) \
  { \
    sfree(rates); \
    return (-ENOMEM); \
  } \
  else \
    offset += ((size_t) status); \
} while (0)

  BUFFER_ADD ("[");
  for (i = 0; i < ds->ds_num; i++)
  {
    if (i > 0)
      BUFFER_ADD (",");

    if (ds->ds[i].type == DS_TYPE_GAUGE)
    {
      if(isfinite (vl->values[i].gauge))
        BUFFER_ADD ("%g", vl->values[i].gauge);
      else
        BUFFER_ADD ("null");
    }
    else if (store_rates)
    {
      if (rates == NULL)
        rates = uc_get_rate (ds, vl);
      if (rates == NULL)
      {
        WARNING ("utils_format_json: uc_get_rate failed.");
        sfree(rates);
        return (-1);
      }

      if(isfinite (rates[i]))
        BUFFER_ADD ("%g", rates[i]);
      else
        BUFFER_ADD ("null");
    }
    else if (ds->ds[i].type == DS_TYPE_COUNTER)
      BUFFER_ADD ("%llu", vl->values[i].counter);
    else if (ds->ds[i].type == DS_TYPE_DERIVE)
      BUFFER_ADD ("%"PRIi64, vl->values[i].derive);
    else if (ds->ds[i].type == DS_TYPE_ABSOLUTE)
      BUFFER_ADD ("%"PRIu64, vl->values[i].absolute);
    else
    {
      ERROR ("format_json: Unknown data source type: %i",
          ds->ds[i].type);
      sfree (rates);
      return (-1);
    }
  } /* for ds->ds_num */
  BUFFER_ADD ("]");

#undef BUFFER_ADD

  DEBUG ("format_json: values_to_json: buffer = %s;", buffer);
  sfree(rates);
  return (0);
} /* }}} int values_to_json */
int value_list_to_json (char *buffer, size_t buffer_size, /* {{{ */
                const data_set_t *ds, const value_list_t *vl, int store_rates)
{
  char temp[512];
  size_t offset = 0;
  int status;

  memset (buffer, 0, buffer_size);

#define BUFFER_ADD(...) do { \
  status = ssnprintf (buffer + offset, buffer_size - offset, \
      __VA_ARGS__); \
  if (status < 1) \
    return (-1); \
  else if (((size_t) status) >= (buffer_size - offset)) \
    return (-ENOMEM); \
  else \
    offset += ((size_t) status); \
} while (0)

  BUFFER_ADD ("{");

  status = values_to_json (temp, sizeof (temp), ds, vl, store_rates);
  if (status != 0)
    return (status);
  BUFFER_ADD ("\"values\":%s", temp);

  status = dstypes_to_json (temp, sizeof (temp), ds, vl);
  if (status != 0)
    return (status);
  BUFFER_ADD (",\"dstypes\":%s", temp);

  status = dsnames_to_json (temp, sizeof (temp), ds, vl);
  if (status != 0)
    return (status);
  BUFFER_ADD (",\"dsnames\":%s", temp);

  BUFFER_ADD (",\"time\":%lu", (unsigned long) vl->time);
  BUFFER_ADD (",\"interval\":%i", vl->interval);

#define BUFFER_ADD_KEYVAL(key, value) do { \
  status = escape_string (temp, sizeof (temp), (value)); \
  if (status != 0) \
    return (status); \
  BUFFER_ADD (",\"%s\":%s", (key), temp); \
} while (0)

  BUFFER_ADD_KEYVAL ("host", vl->host);
  BUFFER_ADD_KEYVAL ("plugin", vl->plugin);
  BUFFER_ADD_KEYVAL ("plugin_instance", vl->plugin_instance);
  BUFFER_ADD_KEYVAL ("type", vl->type);
  BUFFER_ADD_KEYVAL ("type_instance", vl->type_instance);

  BUFFER_ADD ("}");

#undef BUFFER_ADD_KEYVAL
#undef BUFFER_ADD

  DEBUG ("format_json: value_list_to_json: buffer = %s;", buffer);

  return (0);
} /* }}} int value_list_to_json */
示例#8
0
static int value_list_to_json(char *buffer, size_t buffer_size, /* {{{ */
                              const data_set_t *ds, const value_list_t *vl,
                              int store_rates) {
  char temp[512];
  size_t offset = 0;
  int status;

  memset(buffer, 0, buffer_size);

#define BUFFER_ADD(...)                                                        \
  do {                                                                         \
    status = ssnprintf(buffer + offset, buffer_size - offset, __VA_ARGS__);    \
    if (status < 1)                                                            \
      return (-1);                                                             \
    else if (((size_t)status) >= (buffer_size - offset))                       \
      return (-ENOMEM);                                                        \
    else                                                                       \
      offset += ((size_t)status);                                              \
  } while (0)

  /* All value lists have a leading comma. The first one will be replaced with
   * a square bracket in `format_json_finalize'. */
  BUFFER_ADD(",{");

  status = values_to_json(temp, sizeof(temp), ds, vl, store_rates);
  if (status != 0)
    return (status);
  BUFFER_ADD("\"values\":%s", temp);

  status = dstypes_to_json(temp, sizeof(temp), ds);
  if (status != 0)
    return (status);
  BUFFER_ADD(",\"dstypes\":%s", temp);

  status = dsnames_to_json(temp, sizeof(temp), ds);
  if (status != 0)
    return (status);
  BUFFER_ADD(",\"dsnames\":%s", temp);

  BUFFER_ADD(",\"time\":%.3f", CDTIME_T_TO_DOUBLE(vl->time));
  BUFFER_ADD(",\"interval\":%.3f", CDTIME_T_TO_DOUBLE(vl->interval));

#define BUFFER_ADD_KEYVAL(key, value)                                          \
  do {                                                                         \
    status = json_escape_string(temp, sizeof(temp), (value));                  \
    if (status != 0)                                                           \
      return (status);                                                         \
    BUFFER_ADD(",\"%s\":%s", (key), temp);                                     \
  } while (0)

  BUFFER_ADD_KEYVAL("host", vl->host);
  BUFFER_ADD_KEYVAL("plugin", vl->plugin);
  BUFFER_ADD_KEYVAL("plugin_instance", vl->plugin_instance);
  BUFFER_ADD_KEYVAL("type", vl->type);
  BUFFER_ADD_KEYVAL("type_instance", vl->type_instance);

  if (vl->meta != NULL) {
    char meta_buffer[buffer_size];
    memset(meta_buffer, 0, sizeof(meta_buffer));
    status = meta_data_to_json(meta_buffer, sizeof(meta_buffer), vl->meta);
    if (status != 0)
      return (status);

    BUFFER_ADD(",\"meta\":%s", meta_buffer);
  } /* if (vl->meta != NULL) */

  BUFFER_ADD("}");

#undef BUFFER_ADD_KEYVAL
#undef BUFFER_ADD

  DEBUG("format_json: value_list_to_json: buffer = %s;", buffer);

  return (0);
} /* }}} int value_list_to_json */
示例#9
0
static int meta_data_keys_to_json(char *buffer, size_t buffer_size, /* {{{ */
                                  meta_data_t *meta, char **keys,
                                  size_t keys_num) {
  size_t offset = 0;
  int status;

  buffer[0] = 0;

#define BUFFER_ADD(...)                                                        \
  do {                                                                         \
    status = ssnprintf(buffer + offset, buffer_size - offset, __VA_ARGS__);    \
    if (status < 1)                                                            \
      return (-1);                                                             \
    else if (((size_t)status) >= (buffer_size - offset))                       \
      return (-ENOMEM);                                                        \
    else                                                                       \
      offset += ((size_t)status);                                              \
  } while (0)

  for (size_t i = 0; i < keys_num; ++i) {
    int type;
    char *key = keys[i];

    type = meta_data_type(meta, key);
    if (type == MD_TYPE_STRING) {
      char *value = NULL;
      if (meta_data_get_string(meta, key, &value) == 0) {
        char temp[512] = "";

        status = json_escape_string(temp, sizeof(temp), value);
        sfree(value);
        if (status != 0)
          return status;

        BUFFER_ADD(",\"%s\":%s", key, temp);
      }
    } else if (type == MD_TYPE_SIGNED_INT) {
      int64_t value = 0;
      if (meta_data_get_signed_int(meta, key, &value) == 0)
        BUFFER_ADD(",\"%s\":%" PRIi64, key, value);
    } else if (type == MD_TYPE_UNSIGNED_INT) {
      uint64_t value = 0;
      if (meta_data_get_unsigned_int(meta, key, &value) == 0)
        BUFFER_ADD(",\"%s\":%" PRIu64, key, value);
    } else if (type == MD_TYPE_DOUBLE) {
      double value = 0.0;
      if (meta_data_get_double(meta, key, &value) == 0)
        BUFFER_ADD(",\"%s\":%f", key, value);
    } else if (type == MD_TYPE_BOOLEAN) {
      _Bool value = 0;
      if (meta_data_get_boolean(meta, key, &value) == 0)
        BUFFER_ADD(",\"%s\":%s", key, value ? "true" : "false");
    }
  } /* for (keys) */

  if (offset == 0)
    return (ENOENT);

  buffer[0] = '{'; /* replace leading ',' */
  BUFFER_ADD("}");

#undef BUFFER_ADD

  return (0);
} /* }}} int meta_data_keys_to_json */
static int values_to_kairosdb(char *buffer, size_t buffer_size, /* {{{ */
                              const data_set_t *ds, const value_list_t *vl,
                              int store_rates, size_t ds_idx) {
  size_t offset = 0;
  gauge_t *rates = NULL;

  memset(buffer, 0, buffer_size);

#define BUFFER_ADD(...)                                                        \
  do {                                                                         \
    int status;                                                                \
    status = snprintf(buffer + offset, buffer_size - offset, __VA_ARGS__);     \
    if (status < 1) {                                                          \
      sfree(rates);                                                            \
      return -1;                                                               \
    } else if (((size_t)status) >= (buffer_size - offset)) {                   \
      sfree(rates);                                                            \
      return -ENOMEM;                                                          \
    } else                                                                     \
      offset += ((size_t)status);                                              \
  } while (0)

  if (ds->ds[ds_idx].type == DS_TYPE_GAUGE) {
    if (isfinite(vl->values[ds_idx].gauge)) {
      BUFFER_ADD("[[");
      BUFFER_ADD("%" PRIu64, CDTIME_T_TO_MS(vl->time));
      BUFFER_ADD(",");
      BUFFER_ADD(JSON_GAUGE_FORMAT, vl->values[ds_idx].gauge);
    } else {
      DEBUG("utils_format_kairosdb: invalid vl->values[ds_idx].gauge for "
            "%s|%s|%s|%s|%s",
            vl->plugin, vl->plugin_instance, vl->type, vl->type_instance,
            ds->ds[ds_idx].name);
      return -1;
    }
  } else if (store_rates) {
    if (rates == NULL)
      rates = uc_get_rate(ds, vl);
    if (rates == NULL) {
      WARNING("utils_format_kairosdb: uc_get_rate failed for %s|%s|%s|%s|%s",
              vl->plugin, vl->plugin_instance, vl->type, vl->type_instance,
              ds->ds[ds_idx].name);

      return -1;
    }

    if (isfinite(rates[ds_idx])) {
      BUFFER_ADD("[[");
      BUFFER_ADD("%" PRIu64, CDTIME_T_TO_MS(vl->time));
      BUFFER_ADD(",");
      BUFFER_ADD(JSON_GAUGE_FORMAT, rates[ds_idx]);
    } else {
      WARNING("utils_format_kairosdb: invalid rates[ds_idx] for %s|%s|%s|%s|%s",
              vl->plugin, vl->plugin_instance, vl->type, vl->type_instance,
              ds->ds[ds_idx].name);
      sfree(rates);
      return -1;
    }
  } else if (ds->ds[ds_idx].type == DS_TYPE_COUNTER) {
    BUFFER_ADD("[[");
    BUFFER_ADD("%" PRIu64, CDTIME_T_TO_MS(vl->time));
    BUFFER_ADD(",");
    BUFFER_ADD("%" PRIu64, (uint64_t)vl->values[ds_idx].counter);
  } else if (ds->ds[ds_idx].type == DS_TYPE_DERIVE) {
    BUFFER_ADD("[[");
    BUFFER_ADD("%" PRIu64, CDTIME_T_TO_MS(vl->time));
    BUFFER_ADD(",");
    BUFFER_ADD("%" PRIi64, vl->values[ds_idx].derive);
  } else if (ds->ds[ds_idx].type == DS_TYPE_ABSOLUTE) {
    BUFFER_ADD("[[");
    BUFFER_ADD("%" PRIu64, CDTIME_T_TO_MS(vl->time));
    BUFFER_ADD(",");
    BUFFER_ADD("%" PRIu64, vl->values[ds_idx].absolute);
  } else {
    ERROR("format_kairosdb: Unknown data source type: %i", ds->ds[ds_idx].type);
    sfree(rates);
    return -1;
  }
  BUFFER_ADD("]]");

#undef BUFFER_ADD

  DEBUG("format_kairosdb: values_to_kairosdb: buffer = %s;", buffer);
  sfree(rates);
  return 0;
} /* }}} int values_to_kairosdb */
static int value_list_to_kairosdb(char *buffer, size_t buffer_size, /* {{{ */
                                  const data_set_t *ds, const value_list_t *vl,
                                  int store_rates,
                                  char const *const *http_attrs,
                                  size_t http_attrs_num, int data_ttl,
                                  char const *metrics_prefix) {
  char temp[512];
  size_t offset = 0;
  int status;

  memset(buffer, 0, buffer_size);

#define BUFFER_ADD(...)                                                        \
  do {                                                                         \
    status = snprintf(buffer + offset, buffer_size - offset, __VA_ARGS__);     \
    if (status < 1)                                                            \
      return -1;                                                               \
    else if (((size_t)status) >= (buffer_size - offset))                       \
      return -ENOMEM;                                                          \
    else                                                                       \
      offset += ((size_t)status);                                              \
  } while (0)

#define BUFFER_ADD_KEYVAL(key, value)                                          \
  do {                                                                         \
    status = kairosdb_escape_string(temp, sizeof(temp), (value));              \
    if (status != 0)                                                           \
      return status;                                                           \
    BUFFER_ADD(",\"%s\": %s", (key), temp);                                    \
  } while (0)

  for (size_t i = 0; i < ds->ds_num; i++) {
    /* All value lists have a leading comma. The first one will be replaced with
     * a square bracket in `format_kairosdb_finalize'. */
    BUFFER_ADD(",{\"name\":\"");

    if (metrics_prefix != NULL) {
      BUFFER_ADD("%s.", metrics_prefix);
    }

    BUFFER_ADD("%s", vl->plugin);

    status = values_to_kairosdb(temp, sizeof(temp), ds, vl, store_rates, i);
    if (status != 0)
      return status;

    BUFFER_ADD("\", \"datapoints\": %s", temp);

    /*
     * Now adds meta data to metric as tags
     */

    memset(temp, 0, sizeof(temp));

    if (data_ttl != 0)
      BUFFER_ADD(", \"ttl\": %i", data_ttl);

    BUFFER_ADD(", \"tags\":\{");

    BUFFER_ADD("\"host\": \"%s\"", vl->host);
    for (size_t j = 0; j < http_attrs_num; j += 2) {
      BUFFER_ADD(", \"%s\":", http_attrs[j]);
      BUFFER_ADD(" \"%s\"", http_attrs[j + 1]);
    }

    if (strlen(vl->plugin_instance))
      BUFFER_ADD_KEYVAL("plugin_instance", vl->plugin_instance);
    BUFFER_ADD_KEYVAL("type", vl->type);
    if (strlen(vl->type_instance))
      BUFFER_ADD_KEYVAL("type_instance", vl->type_instance);
    if (ds->ds_num != 1)
      BUFFER_ADD_KEYVAL("ds", ds->ds[i].name);
    BUFFER_ADD("}}");
  } /* for ds->ds_num */

#undef BUFFER_ADD_KEYVAL
#undef BUFFER_ADD

  DEBUG("format_kairosdb: value_list_to_kairosdb: buffer = %s;", buffer);

  return 0;
} /* }}} int value_list_to_kairosdb */
示例#12
0
int format_values_extremon (char *ret, size_t ret_len, 
                            const data_set_t *ds, const value_list_t *vl,
                            _Bool store_rates)
{
  size_t    offset = 0;
  int       status=0;
  int       i;
  gauge_t*  rates = NULL;

  assert (0 == strcmp (ds->type, vl->type));
  assert (vl->plugin != NULL);
  assert (vl->type != NULL);
  memset (ret, 0, ret_len);

#define BUFFER_ADD(...) do { \
        status = ssnprintf (ret + offset, ret_len - offset, \
                        __VA_ARGS__); \
        if (status < 1) \
        { \
                sfree (rates); \
                return (-1); \
        } \
        else if (((size_t) status) >= (ret_len - offset)) \
        { \
                sfree (rates); \
                return (-1); \
        } \
        else \
                offset += ((size_t) status); \
} while (0)

  for(i=0;i<ds->ds_num;i++)
  {
    if((vl->plugin_instance==NULL) || (strlen (vl->plugin_instance)= 0))
    {
      if ((vl->type_instance==NULL) || (strlen(vl->type_instance)==0))
        BUFFER_ADD("%s.%s.%s.",vl->host,vl->plugin,vl->type);
      else
        BUFFER_ADD("%s.%s.%s.%s.",vl->host,vl->plugin,vl->type,
                                  vl->type_instance);
    }
    else
    {
      if((vl->type_instance == NULL) || (strlen(vl->type_instance) == 0))
        BUFFER_ADD("%s.%s.%s.%s.", vl->host,vl->plugin,
                                   vl->plugin_instance, vl->type);
      else
        BUFFER_ADD("%s.%s.%s.%s.%s.", vl->host,vl->plugin,
                                      vl->plugin_instance,vl->type,
                                      vl->type_instance);
    }

    if(ds->ds[i].type==DS_TYPE_GAUGE)
      BUFFER_ADD ("%s=%f\n", ds->ds[i].name,vl->values[i].gauge);
    else if(store_rates)
    {
      if(rates==NULL)
        rates=uc_get_rate (ds, vl);

      if(rates==NULL)
      {
        WARNING ("format_values_extremon : uc_get_rate failed.");
        return (-1);
      }

      BUFFER_ADD ("%s=%g\n", ds->ds[i].name,rates[i]);
    }
    else if(ds->ds[i].type==DS_TYPE_COUNTER)
      BUFFER_ADD ("%s=%llu\n", ds->ds[i].name,vl->values[i].counter);
  }


#undef BUFFER_ADD

  sfree (rates);
  return (0);
}