<GANGLIA_XML VERSION="2.5.0" SOURCE="gmond">
<CLUSTER NAME="unspecified" OWNER="unspecified" LATLONG="unspecified"
LOCALTIME="1029973784">
<HOST NAME="mauna" IP="10.10.77.125" LOCATION="unspecified"
REPORTED="1029973780" TN="4" TMAX="20" DMAX="0" GMOND_STARTED="1029973763">
<METRIC NAME="cpu_num" VAL="4" TYPE="uint16" UNITS="" TN="20" TMAX="1200"
DMAX="0" SLOPE="zero" SOURCE="gmond"/>
<METRIC NAME="machine_type" VAL="alpha" TYPE="string" UNITS="" TN="20"
TMAX="1200" DMAX="0" SLOPE="zero" SOURCE="gmond"/>
<METRIC NAME="gexec" VAL="OFF" TYPE="string" UNITS="" TN="20" TMAX="300"
DMAX="0" SLOPE="zero" SOURCE="gmond"/>
<METRIC NAME="sys_clock" VAL="1029973763" TYPE="timestamp" UNITS="s"
TN="20" TMAX="1200" DMAX="0" SLOPE="zero" SOURCE="gmond"/>
<METRIC NAME="mtu" VAL="1500" TYPE="uint32" UNITS="B" TN="20" TMAX="1200"
DMAX="0" SLOPE="zero" SOURCE="gmond"/>
<METRIC NAME="os_name" VAL="OSF1" TYPE="string" UNITS="" TN="20"
TMAX="1200" DMAX="0" SLOPE="zero" SOURCE="gmond"/>
<METRIC NAME="os_release" VAL="V5.1" TYPE="string" UNITS="" TN="20"
TMAX="1200" DMAX="0" SLOPE="zero" SOURCE="gmond"/>
</HOST>
</CLUSTER>
</GANGLIA_XML>
Not too many metrics to start with, but they all work. Ran gmond with very
low expectations, and *bam.* It auto-detects the multicast interface and
starts sending out packets (and receiving them). And as you can see the
XML dump bit works too.
Attached is a working osf.c with mostly dummy values (but it's enough to
get it compiled so you can start coding metrics with it). Note that the
metrics above are all determined algorithmically (although I'm going to
change the os_name/release ones to use utsname instead of sysinfo calls).
Found ways to get a pretty large subset of the Solaris data in Tru64 just
now, too.
Compiled using:
Monday afternoon CVS checkout.
GNU m4 1.4
GNU autoconf 2.53
GNU automake 1.6.3
GNU libtool 1.4.2
GNU gcc 2.95.3
P.S. gstat doesn't work. :)
#include "ganglia.h"
#include "metric_typedefs.h"
#include <sys/systeminfo.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/swap.h>
#include <sys/types.h>
#include <sys/sysinfo.h>
#include <unistd.h>
int multiplier;
/*
* This function is called only once by the gmond. Use to
* initialize data structures, etc or just return SYNAPSE_SUCCESS;
*/
g_val_t
metric_init(void)
{
g_val_t val;
multiplier = getpagesize() / 1024;
val.int32 = SYNAPSE_SUCCESS;
return val;
}
/*
*
*/
g_val_t
cpu_num_func ( void )
{
g_val_t val;
val.uint16 = sysconf(_SC_NPROCESSORS_ONLN);
return val;
}
g_val_t
cpu_speed_func ( void )
{
g_val_t val;
val.uint16 = 0;
return val;
}
g_val_t
mem_total_func ( void )
{
g_val_t val;
val.uint32 = ( 1 * multiplier);
return val;
}
g_val_t
swap_total_func ( void )
{
g_val_t val;
off_t swaptotal;
// swapctl(SC_GETSWAPTOT, &swaptotal);
// val.uint32 = swaptotal / 2;
val.uint32 = 0;
return val;
}
g_val_t
boottime_func ( void )
{
g_val_t val;
val.uint32 = 0;
return val;
}
g_val_t
sys_clock_func ( void )
{
g_val_t val;
val.uint32 = time(NULL);
return val;
}
g_val_t
machine_type_func ( void )
{
g_val_t val;
long size;
size = sysinfo(SI_MACHINE, val.str, MAX_G_STRING_SIZE);
/* strncpy( val.str, "x86", MAX_G_STRING_SIZE ); */
return val;
}
g_val_t
os_name_func ( void )
{
g_val_t val;
long size;
size = sysinfo(SI_SYSNAME, val.str, MAX_G_STRING_SIZE);
/* strncpy( val.str, "FreeBSD", MAX_G_STRING_SIZE ); */
return val;
}
g_val_t
os_release_func ( void )
{
g_val_t val;
long size;
size = sysinfo(SI_RELEASE, val.str, MAX_G_STRING_SIZE);
/* strncpy( val.str, "unknown", MAX_G_STRING_SIZE ); */
return val;
}
g_val_t
cpu_user_func ( void )
{
g_val_t val;
val.f = 0;
return val;
}
g_val_t
cpu_nice_func ( void )
{
g_val_t val;
val.f = 0.0;
return val;
}
g_val_t
cpu_system_func ( void )
{
g_val_t val;
val.f = 0;
return val;
}
g_val_t
cpu_idle_func ( void )
{
g_val_t val;
val.f = 0;
return val;
}
g_val_t
cpu_aidle_func ( void )
{
g_val_t val;
val.f = 0.0;
return val;
}
g_val_t
load_one_func ( void )
{
g_val_t val;
val.f = 1;
return val;
}
g_val_t
load_five_func ( void )
{
g_val_t val;
val.f = 1;
return val;
}
g_val_t
load_fifteen_func ( void )
{
g_val_t val;
val.f = 1;
return val;
}
g_val_t
proc_run_func( void )
{
g_val_t val;
val.uint32 = 0;
return val;
}
g_val_t
proc_total_func ( void )
{
g_val_t val;
val.uint32 = 0;
return val;
}
g_val_t
mem_free_func ( void )
{
g_val_t val;
val.uint32 = ( 5 * multiplier);
return val;
}
g_val_t
mem_shared_func ( void )
{
g_val_t val;
val.uint32 = 0;
return val;
}
g_val_t
mem_buffers_func ( void )
{
g_val_t val;
val.uint32 = ( 10 * multiplier);
return val;
}
g_val_t
mem_cached_func ( void )
{
g_val_t val;
val.uint32 = 0;
return val;
}
g_val_t
swap_free_func ( void )
{
g_val_t val;
off_t swapfree;
/* swapctl(SC_GETFREESWAP, &swapfree);
val.uint32 = swapfree / 2;
*/
val.uint32 = 0;
return val;
}
#include "dnet.h"
static int
find_mtu(const struct intf_entry *entry, void *arg)
{
unsigned int mtu;
unsigned int *min = (unsigned int *) arg;
/* Only consider interfaces that are up. */
if (! entry->intf_flags & INTF_FLAG_UP)
return 0;
mtu=entry->intf_mtu;
if ( !*min || *min>mtu)
*min=mtu;
return 0;
}
g_val_t
mtu_func ( void )
{
/* We want to find the minimum MTU (Max packet size) over all UP interfaces.
*/
unsigned int min=0;
g_val_t val;
intf_t *intf;
intf = intf_open();
intf_loop(intf, find_mtu, &min);
intf_close(intf);
val.uint32 = min;
/* A val of 0 means there are no UP interfaces. Shouldn't happen. */
return val;
}