Ejemplo n.º 1
0
/* Write a metric summary value to the RRD database. */
static int
finish_processing_source(datum_t *key, datum_t *val, void *arg)
{
   xmldata_t *xmldata = (xmldata_t *) arg;
   char *name, *type;
   char sum[512];
   char num[256];
   Metric_t *metric;
   struct type_tag *tt;
   llist_entry *le;

   name = (char*) key->data;
   metric = (Metric_t*) val->data;
   type = getfield(metric->strings, metric->type);

   /* Don't save to RRD if the datasource is dead or write_rrds is off */
   if( xmldata->ds->dead || gmetad_config.write_rrds != 1)
      return 1;

   tt = in_type_list(type, strlen(type));
   if (!tt) return 0;

   /* Don't save to RRD if this is a metric not to be summarized */
   if (llist_search(&(gmetad_config.unsummarized_metrics), (void *)name, llist_strncmp, &le) == 0)
      return 0;

   switch (tt->type)
      {
         case INT:
         case UINT:
            sprintf(sum, "%.f", metric->val.d);
            break;
         case FLOAT:
            sprintf(sum, "%.*f", (int) metric->precision, metric->val.d);
            break;
         default:
            break;
      }
   sprintf(num, "%u", metric->num);

   /* Save the data to a round robin database if this data source is 
    * alive. */
   if (!xmldata->ds->dead && !xmldata->rval)
     {

       debug_msg("Writing Summary data for source %s, metric %s",
                 xmldata->sourcename, name);

       xmldata->rval = write_data_to_rrd(xmldata->sourcename, NULL, name,
                                         sum, num, xmldata->ds->step,
                                         xmldata->source.localtime,
                                         cstr_to_slope(getfield(metric->strings, metric->slope)));
     }

   return xmldata->rval;
}
Ejemplo n.º 2
0
static int
write_root_summary(datum_t *key, datum_t *val, void *arg)
{
   char *name, *type;
   char sum[256];
   char num[256];
   Metric_t *metric;
   int rc;
   struct type_tag *tt;
   llist_entry *le;
   char *p;

   name = (char*) key->data;
   metric = (Metric_t*) val->data;
   type = getfield(metric->strings, metric->type);

   /* Summarize all numeric metrics */
   tt = in_type_list(type, strlen(type));
   /* Don't write a summary for an unknown or STRING type */
   if (!tt || (tt->type == STRING))
       return 0;

   /* Don't write a summary for metrics not to be summarized */
   if (llist_search(&(gmetad_config.unsummarized_metrics), (void *)key->data, llist_strncmp, &le) == 0)
       return 0;

   /* Don't write a summary for metris that appears to be sFlow VM metrics */
   if (gmetad_config.unsummarized_sflow_vm_metrics && (p = strchr(name, '.')) != NULL && *(p+1) == 'v')
     return 0;

   ganglia_scoreboard_inc(METS_SUMRZ_ROOT);
   /* We log all our sums in double which does not suffer from
      wraparound errors: for example memory KB exceeding 4TB. -twitham */
   sprintf(sum, "%.5f", metric->val.d);

   sprintf(num, "%u", metric->num);

   /* err_msg("Writing Overall Summary for metric %s (%s)", name, sum); */

   /* Save the data to a rrd file unless write_rrds == off */
	 if (gmetad_config.write_rrds == 0)
	     return 0;

   debug_msg("Writing Root Summary data for metric %s", name);

   rc = write_data_to_rrd( NULL, NULL, name, sum, num, 15, 0,
      cstr_to_slope(getfield(metric->strings, metric->slope)));
   if (rc)
      {
         err_msg("Unable to write meta data for metric %s to RRD", name);
      }
   return 0;
}
Ejemplo n.º 3
0
static int
startElement_METRIC(void *data, const char *el, const char **attr)
{
    xmldata_t *xmldata = (xmldata_t *)data;
    ganglia_slope_t slope = GANGLIA_SLOPE_UNSPECIFIED;
    struct xml_tag *xt;
    struct type_tag *tt;
    datum_t *hash_datum = NULL;
    datum_t *rdatum;
    datum_t hashkey, hashval;
    const char *name = NULL;
    const char *metricval = NULL;
    const char *type = NULL;
    int do_summary;
    int i, edge, carbon_ret;
    hash_t *summary;
    Metric_t *metric;

    if (!xmldata->host_alive ) return 0;

    /* Get name for hash key, and val/type for summaries. */
    for(i = 0; attr[i]; i+=2)
    {
        xt = in_xml_list(attr[i], strlen(attr[i]));
        if (!xt) continue;

        switch (xt->tag)
        {
        case NAME_TAG:
            name = attr[i+1];
            hashkey.data = (void*) name;
            hashkey.size =  strlen(name) + 1;
            break;
        case VAL_TAG:
            metricval = attr[i+1];
            break;
        case TYPE_TAG:
            type = attr[i+1];
            break;
        case SLOPE_TAG:
            slope = cstr_to_slope(attr[i+1]);
        default:
            break;
        }
    }

    metric = &(xmldata->metric);
    memset((void*) metric, 0, sizeof(*metric));

    /* Summarize all numeric metrics */
    do_summary = 0;
    tt = in_type_list(type, strlen(type));
    if (!tt) return 0;

    if (tt->type==INT || tt->type==UINT || tt->type==FLOAT)
        do_summary = 1;

    /* Only keep metric details if we are the authority on this cluster. */
    if (authority_mode(xmldata))
    {
        /* Save the data to a round robin database if the data source is alive
         */
        fillmetric(attr, metric, type);
        if (metric->dmax && metric->tn > metric->dmax)
            return 0;

        if (do_summary && !xmldata->ds->dead && !xmldata->rval)
        {
            debug_msg("Updating host %s, metric %s",
                      xmldata->hostname, name);
            if ( gmetad_config.write_rrds == 1 )
                xmldata->rval = write_data_to_rrd(xmldata->sourcename,
                                                  xmldata->hostname, name, metricval, NULL,
                                                  xmldata->ds->step, xmldata->source.localtime, slope);
            if (gmetad_config.carbon_server) // if the user has specified a carbon server, send the metric to carbon as well
                carbon_ret=write_data_to_carbon(xmldata->sourcename, xmldata->hostname, name, metricval,xmldata->source.localtime);
        }
        metric->id = METRIC_NODE;
        metric->report_start = metric_report_start;
        metric->report_end = metric_report_end;


        edge = metric->stringslen;
        metric->name = addstring(metric->strings, &edge, name);
        metric->stringslen = edge;

        /* Set local idea of T0. */
        metric->t0 = xmldata->now;
        metric->t0.tv_sec -= metric->tn;

        /* Trim metric structure to the correct length. */
        hashval.size = sizeof(*metric) - GMETAD_FRAMESIZE + metric->stringslen;
        hashval.data = (void*) metric;

        /* Update full metric in cluster host table. */
        rdatum = hash_insert(&hashkey, &hashval, xmldata->host.metrics);
        if (!rdatum)
        {
            err_msg("Could not insert %s metric", name);
        }
    }

    /* Always update summary for numeric metrics. */
    if (do_summary)
    {
        summary = xmldata->source.metric_summary;
        hash_datum = hash_lookup(&hashkey, summary);
        if (!hash_datum)
        {
            if (!authority_mode(xmldata))
            {
                metric = &(xmldata->metric);
                memset((void*) metric, 0, sizeof(*metric));
                fillmetric(attr, metric, type);
            }
            /* else we have already filled in the metric above. */
        }
        else
        {
            memcpy(&xmldata->metric, hash_datum->data, hash_datum->size);
            datum_free(hash_datum);
            metric = &(xmldata->metric);

            switch (tt->type)
            {
            case INT:
            case UINT:
            case FLOAT:
                metric->val.d += (double)
                                 strtod(metricval, (char**) NULL);
                break;
            default:
                break;
            }
        }

        metric->num++;
        metric->t0 = xmldata->now; /* tell cleanup thread we are using this */

        /* Trim metric structure to the correct length. Tricky. */
        hashval.size = sizeof(*metric) - GMETAD_FRAMESIZE + metric->stringslen;
        hashval.data = (void*) metric;

        /* Update metric in summary table. */
        rdatum = hash_insert(&hashkey, &hashval, summary);
        if (!rdatum) err_msg("Could not insert %s metric", name);
    }
    return 0;
}
Ejemplo n.º 4
0
int
main( int argc, char *argv[] )
{
  int rval;

  /* process the commandline options */
  if (cmdline_parser (argc, argv, &args_info) != 0)
        exit(1);

  /* create the global context */
  global_context = Ganglia_pool_create(NULL);
  if(!global_context)
    {
      fprintf(stderr,"Unable to create global context. Exiting.\n");
      exit(1);
    }
  
  /* parse the configuration file */
  gmond_config = Ganglia_gmond_config_create( args_info.conf_arg, !args_info.conf_given);

  /* deal with spoof overrides */
  cfg_t *globals = (cfg_t*) cfg_getsec( gmond_config, "globals" );
  char *override_hostname = cfg_getstr( globals, "override_hostname" );
  char *override_ip = cfg_getstr( globals, "override_ip" );

  /* build the udp send channels */
  send_channels = Ganglia_udp_send_channels_create(global_context, gmond_config);
  if(!send_channels)
    {
      fprintf(stderr,"Unable to create ganglia send channels. Exiting.\n");
      exit(1);
    }

  /* create the message */
  gmetric = Ganglia_metric_create(global_context);
  if(!gmetric)
    {
      fprintf(stderr,"Unable to allocate gmetric structure. Exiting.\n");
      exit(1);
    }
  apr_pool_t *gm_pool = (apr_pool_t*)gmetric->pool;

  if(args_info.spoof_given && args_info.heartbeat_given){
    rval = Ganglia_metric_set(gmetric, "heartbeat", "0", "uint32", "", 0, 0, 0);
  }else{
    if( ! (args_info.name_given && args_info.value_given && args_info.type_given))
      {
        fprintf(stderr,"Incorrect options supplied, exiting.\n");
        exit(1);
      }
    rval = Ganglia_metric_set( gmetric, args_info.name_arg, args_info.value_arg,
             args_info.type_arg, args_info.units_arg, cstr_to_slope(args_info.slope_arg),
             args_info.tmax_arg, args_info.dmax_arg);
  }

  /* TODO: make this less ugly later */
  switch(rval)
    {
    case 1:
      fprintf(stderr,"gmetric parameters invalid. exiting.\n");
      exit(1); 
    case 2:
      fprintf(stderr,"one of your parameters has an invalid character '\"'. exiting.\n");
      exit(1);
    case 3:
      fprintf(stderr,"the type parameter \"%s\" is not a valid type. exiting.\n", args_info.type_arg);
      exit(1);
    case 4:
      fprintf(stderr,"the value parameter \"%s\" does not represent a number. exiting.\n", args_info.value_arg);
      exit(1);
    }

  /* TODO: Try to validate the spoof arg format.  A better validation could 
   *  be done here. This is just checking for a colon. */
  if(args_info.spoof_given && !strchr(args_info.spoof_arg,':'))
    {
      fprintf(stderr,"Incorrect format for spoof argument. exiting.\n");
      exit(1);
    }

  if(args_info.spoof_given)
      Ganglia_metadata_add(gmetric, SPOOF_HOST, args_info.spoof_arg);
  if(!args_info.spoof_given && override_hostname != NULL)
    {
      char *spoof_string = apr_pstrcat(gm_pool, override_ip != NULL ? override_ip : override_hostname, ":", override_hostname, NULL);
      Ganglia_metadata_add(gmetric, SPOOF_HOST, spoof_string);
    }
  if(args_info.heartbeat_given)
      Ganglia_metadata_add(gmetric, SPOOF_HEARTBEAT, "yes");
  if(args_info.cluster_given)
      Ganglia_metadata_add(gmetric, "CLUSTER", args_info.cluster_arg);
  if(args_info.group_given)
      Ganglia_metadata_add(gmetric, "GROUP", args_info.group_arg);
  if(args_info.desc_given)
      Ganglia_metadata_add(gmetric, "DESC", args_info.desc_arg);
  if(args_info.title_given)
      Ganglia_metadata_add(gmetric, "TITLE", args_info.title_arg);

  /* send the message */
  rval = Ganglia_metric_send(gmetric, send_channels);
  if(rval)
    {
      fprintf(stderr,"There was an error sending to %d of the send channels.\n", rval);
    }

  /* cleanup */
  Ganglia_metric_destroy(gmetric); /* not really necessary but for symmetry */
  Ganglia_pool_destroy(global_context);

  return 0;
}