I did a hack to allow a single config file to work across all of my
hosts, even though I needed mod_multicpu and had different numbers of
processors on different machines.

The hack I did was as follows:

When gmond found a metric name which contained one or more (#) pound
signs, I converted the metric name to a sprintf string, as follows:


cpu_###_idle => cpu_%03d_idle
cpu_#_idle => cpu_%d_idle.

I then iteratively applied the config in question, stopping the first
time I got an error.

This would, of course, work only when the variants were numbered, zero
based, and consecutive, but it is very useful to me.

What I added to gmond.c was:
> +const char *make_fmt(const char * const src_in) {
> +     char *pos=strchr(src_in,'#');
> +     if(!pos)
> +             return 0;
> +
> +  {
> +    const char *src = src_in;
> +    static char fmt[1024];
> +    static char * const end = fmt+sizeof(fmt)-1;
> +    char *dst=fmt;
> +    while(src!=pos && dst!=end) {
> +      if((*dst++ = *src++)=='%' && dst!=end)
> +        *dst++='%';
> +    }
> +    if(dst!=end)
> +      *dst++='%';
> +    if(dst!=end)
> +      *dst++='0';
> +    {
> +      int pad=1;
> +      while(*++src == '#')
> +        ++pad;
> +      dst+=snprintf(dst,end-dst,"%d",pad);
> +    }
> +    if(dst!=end)
> +      *dst++='d';
> +    while(dst!=end) {
> +      switch(*dst++ = *src++) {
> +        case 0:
> +          return fmt;
> +        case '#':
> +          err_quit(">1 series of '#' in \"%s\"",src_in);
> +        case '%':
> +          if(dst!=end)
> +            *dst++='%';
> +          break;
> +        default:
> +          break;
> +      }
> +    }
> +    err_quit("fmt string for \"%s\" too long",src_in);
> +  }
> +     /* not reached */
> +     return 0;
> +}
> +double add_metric_series( 
> +     Ganglia_collection_group *group, 
> +     const char *name,
> +     const char *title,
> +     float value_threshold
> +)
> +{
> +     const char *fmt=make_fmt(name);
> +     if(!fmt)
> +             return add_metric(group,name,title,value_threshold);
> +  {
> +    char dname[strlen(fmt)+16];
> +    size_t idx;
> +    double res=0.0;
> +    for(idx=0;idx<64;idx++) {
> +      snprintf(dname,sizeof(dname),fmt,idx);
> +      // the first time through, we do not precheck the metric, so that
> +      // if a series does not yield ANY valid metrics, we get an error.
> +      if(idx && !apr_hash_get( metric_callbacks, dname, APR_HASH_KEY_STRING 
> ))
> +        break;
> +      res+=add_metric(group,dname,title,value_threshold);
> +    }
> +    return res;
> +  }
> +}

and I changed the call to add_metric to call add_metric_series instead.

Sorry for no more reasonable patch, but I made other changes, so can't
do a CVS diff.

This might, however, be useful to somebody else, so I thought I'd pass
the idea around.

Regards,
Rich

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Ganglia-developers mailing list
Ganglia-developers@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ganglia-developers

Reply via email to