1414 lines
48 KiB
Diff
1414 lines
48 KiB
Diff
|
|
diff --git a/contrib/removespikes.pl b/contrib/removespikes.pl
|
||
|
|
index e52908d3..7061cea8 100755
|
||
|
|
--- a/contrib/removespikes.pl
|
||
|
|
+++ b/contrib/removespikes.pl
|
||
|
|
@@ -97,10 +97,10 @@ while (<FICH>) {
|
||
|
|
$cdo=0;
|
||
|
|
if ($linea=~/^(.*)<row>/) { $tstamp=$1; }
|
||
|
|
if ($linea=~/(<row>.*)$/) { $tresto=$1; }
|
||
|
|
- if (/<v>\s\d\.\d+e.(\d+)\s<\/v>/) {
|
||
|
|
+ if (/<v>\s?\d\.\d+e.(\d+)\s?<\/v>/) {
|
||
|
|
@dump = split(/<\/v>/, $tresto);
|
||
|
|
for ($lino=0; $lino<=$#dump-1; $lino++) { # scans DS's within each row
|
||
|
|
- if ( $dump[$lino]=~/\d\.\d+e.(\d+)\s/ ) { # make sure it is a number (and not NaN)
|
||
|
|
+ if ( $dump[$lino]=~/\d\.\d+e.(\d+)\s?/ ) { # make sure it is a number (and not NaN)
|
||
|
|
$a=substr("0$lino",-2).":".$1;
|
||
|
|
$exp{$a}++; # store exponents
|
||
|
|
$tot{substr("0$lino",-2)}++; # and keep a per DS total
|
||
|
|
@@ -146,11 +146,11 @@ while (<FICH>) {
|
||
|
|
$cdo=0;
|
||
|
|
if ($linea=~/^(.*)<row>/) { $tstamp=$1; } # Grab timestamp
|
||
|
|
if ($linea=~/(<row>.*)$/) { $tresto=$1; } # grab rest-of-line :-)
|
||
|
|
- if (/<v>\s\d\.\d+e.(\d+)\s<\/v>/) { # are there DS's?
|
||
|
|
+ if (/<v>\s?\d\.\d+e.(\d+)\s?<\/v>/) { # are there DS's?
|
||
|
|
@dump=split(/<\/v>/, $tresto); # split them
|
||
|
|
if ($linbak ne '') {
|
||
|
|
for ($lino=0;$lino<=$#dump-1;$lino++) { # for each DS:
|
||
|
|
- if ($dump[$lino]=~/\d\.\d+e.(\d+)\s/) { # grab number (and not a NaN)
|
||
|
|
+ if ($dump[$lino]=~/\d\.\d+e.(\d+)\s?/) { # grab number (and not a NaN)
|
||
|
|
$c=$&;
|
||
|
|
$a=$1*1; # and exponent
|
||
|
|
$b=substr("0$lino",-2).":$1"; # calculate the max percentage of this DS
|
||
|
|
diff --git a/ganglia.inc b/ganglia.inc
|
||
|
|
index 733196a0..df8634a6 100644
|
||
|
|
--- a/ganglia.inc
|
||
|
|
+++ b/ganglia.inc
|
||
|
|
@@ -1,11 +1,11 @@
|
||
|
|
|
||
|
|
|
||
|
|
-FIXCONFIG = $(top_srcdir)/scripts/fixconfig
|
||
|
|
+FIXCONFIG = $(top_builddir)/scripts/fixconfig
|
||
|
|
|
||
|
|
# Unfortunately, we can't do this here with a pattern rule because
|
||
|
|
# that is a GNU make feature and is not fully portable
|
||
|
|
#%: %.in $(FIXCONFIG)
|
||
|
|
-# $(FIXCONFIG) $<
|
||
|
|
+# $(FIXCONFIG) $< $@
|
||
|
|
|
||
|
|
# For the moment, it is necessary to provide a rule for each file
|
||
|
|
# we want to generate - see the rule for ganglia-config in Makefile.am
|
||
|
|
diff --git a/ganglia.pod b/ganglia.pod
|
||
|
|
index 42c3a507..de709cbc 100644
|
||
|
|
--- a/ganglia.pod
|
||
|
|
+++ b/ganglia.pod
|
||
|
|
@@ -1,5 +1,7 @@
|
||
|
|
=pod
|
||
|
|
|
||
|
|
+=encoding UTF-8
|
||
|
|
+
|
||
|
|
=for comment The ganglia documentation is written in POD (Plain Old Documentation)
|
||
|
|
format. If you want to edit this file but don't know the POD format, it is very
|
||
|
|
easy to learn. Visit http://www.linuxgazette.com/issue73/spiel.html for a nice intro
|
||
|
|
@@ -605,10 +607,12 @@ is only partially complete).
|
||
|
|
machine_type
|
||
|
|
mem_buffers Amount of buffered memory l,f
|
||
|
|
mem_cached Amount of cached memory l,f
|
||
|
|
- mem_free Amount of available memory l,f
|
||
|
|
+ mem_free Amount of free memory available l,f
|
||
|
|
mem_shared Amount of shared memory l,f
|
||
|
|
+ mem_slab Amount of in-kernel data struct cache l
|
||
|
|
mem_sreclaimable Amount of slab reclaimable memory l (kernel >= 2.6.19)
|
||
|
|
- mem_total Amount of available memory l,f
|
||
|
|
+ mem_available Amount of application memory available l (kernel >= 3.14)
|
||
|
|
+ mem_total Amount of total memory available l,f
|
||
|
|
mtu Network maximum transmission unit l,f
|
||
|
|
os_name Operating system name l,f
|
||
|
|
os_release Operating system release (version) l,f
|
||
|
|
diff --git a/gmetad-python/gmetad-python.service.in b/gmetad-python/gmetad-python.service.in
|
||
|
|
index 16918db7..11243979 100644
|
||
|
|
--- a/gmetad-python/gmetad-python.service.in
|
||
|
|
+++ b/gmetad-python/gmetad-python.service.in
|
||
|
|
@@ -1,6 +1,6 @@
|
||
|
|
[Unit]
|
||
|
|
Description=Ganglia Meta Daemon in Python
|
||
|
|
-After=network.target
|
||
|
|
+After=network-online.target
|
||
|
|
|
||
|
|
[Service]
|
||
|
|
ExecStart=@bindir@/gmetad.py -f
|
||
|
|
diff --git a/gmetad/export_helpers.c b/gmetad/export_helpers.c
|
||
|
|
index 2c126e2e..8ee3b6c8 100644
|
||
|
|
--- a/gmetad/export_helpers.c
|
||
|
|
+++ b/gmetad/export_helpers.c
|
||
|
|
@@ -349,10 +349,11 @@ path_macro_replace(char *path, graphite_path_macro *patrn)
|
||
|
|
char *prefix;
|
||
|
|
char *suffix;
|
||
|
|
char *offset;
|
||
|
|
+ int i;
|
||
|
|
|
||
|
|
strncpy(final, path, PATHSIZE);
|
||
|
|
strncpy(path_cp, path, PATHSIZE);
|
||
|
|
- for(int i=0; patrn[i].torepl != 0; i++){
|
||
|
|
+ for(i=0; patrn[i].torepl != 0; i++){
|
||
|
|
while((offset = strstr(path_cp, patrn[i].torepl)))
|
||
|
|
{
|
||
|
|
prefix=path_cp; //pointer to the beginning of path_cp (for clarity)
|
||
|
|
diff --git a/gmetad/gmetad.c b/gmetad/gmetad.c
|
||
|
|
index 60ade92c..21d5b2f3 100644
|
||
|
|
--- a/gmetad/gmetad.c
|
||
|
|
+++ b/gmetad/gmetad.c
|
||
|
|
@@ -323,7 +323,7 @@ write_root_summary(datum_t *key, datum_t *val, void *arg)
|
||
|
|
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')
|
||
|
|
+ if (gmetad_config.unsummarized_sflow_vm_metrics && (p = strrchr(name, '.')) != NULL && *(p+1) == 'v')
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
ganglia_scoreboard_inc(METS_SUMRZ_ROOT);
|
||
|
|
@@ -341,7 +341,8 @@ write_root_summary(datum_t *key, datum_t *val, void *arg)
|
||
|
|
|
||
|
|
debug_msg("Writing Root Summary data for metric %s", name);
|
||
|
|
|
||
|
|
- rc = write_data_to_rrd( NULL, NULL, name, sum, num, 15, 0, metric->slope);
|
||
|
|
+ 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);
|
||
|
|
@@ -610,12 +611,12 @@ main ( int argc, char *argv[] )
|
||
|
|
/* Sum the new values */
|
||
|
|
hash_foreach(root.authority, do_root_summary, NULL );
|
||
|
|
|
||
|
|
- /* summary completed */
|
||
|
|
- pthread_mutex_unlock(root.sum_finished);
|
||
|
|
-
|
||
|
|
/* Save them to RRD */
|
||
|
|
hash_foreach(root.metric_summary, write_root_summary, NULL);
|
||
|
|
|
||
|
|
+ /* summary completed */
|
||
|
|
+ pthread_mutex_unlock(root.sum_finished);
|
||
|
|
+
|
||
|
|
/* Remember our last run */
|
||
|
|
now = apr_time_now();
|
||
|
|
last_metadata = now; //Updating global variable
|
||
|
|
diff --git a/gmetad/gmetad.service.in b/gmetad/gmetad.service.in
|
||
|
|
index 8234e90e..d7800655 100644
|
||
|
|
--- a/gmetad/gmetad.service.in
|
||
|
|
+++ b/gmetad/gmetad.service.in
|
||
|
|
@@ -1,6 +1,6 @@
|
||
|
|
[Unit]
|
||
|
|
Description=Ganglia Meta Daemon
|
||
|
|
-After=network.target
|
||
|
|
+After=network-online.target
|
||
|
|
|
||
|
|
[Service]
|
||
|
|
Type=forking
|
||
|
|
diff --git a/gmetad/process_xml.c b/gmetad/process_xml.c
|
||
|
|
index 15abc75c..fc28701e 100644
|
||
|
|
--- a/gmetad/process_xml.c
|
||
|
|
+++ b/gmetad/process_xml.c
|
||
|
|
@@ -1172,7 +1172,7 @@ finish_processing_source(datum_t *key, datum_t *val, void *arg)
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
/* Don't save to RRD if this metrics appears to be an sFlow VM metrics */
|
||
|
|
- if (gmetad_config.unsummarized_sflow_vm_metrics && (p = strchr(name, '.')) != NULL && *(p+1) == 'v')
|
||
|
|
+ if (gmetad_config.unsummarized_sflow_vm_metrics && (p = strrchr(name, '.')) != NULL && *(p+1) == 'v')
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
switch (tt->type)
|
||
|
|
diff --git a/gmetad/rrd_helpers.c b/gmetad/rrd_helpers.c
|
||
|
|
index 740799a5..e38c6514 100644
|
||
|
|
--- a/gmetad/rrd_helpers.c
|
||
|
|
+++ b/gmetad/rrd_helpers.c
|
||
|
|
@@ -276,8 +276,8 @@ RRD_create( char *rrd, int summary, unsigned int step,
|
||
|
|
heartbeat);
|
||
|
|
argv[argc++] = sum;
|
||
|
|
if (summary) {
|
||
|
|
- sprintf(num,"DS:num:%s:%d:U:U",
|
||
|
|
- data_source_type,
|
||
|
|
+ sprintf(num,"DS:num:%s:%d:U:U",
|
||
|
|
+ "GAUGE",
|
||
|
|
heartbeat);
|
||
|
|
argv[argc++] = num;
|
||
|
|
}
|
||
|
|
diff --git a/gmetad/server.c b/gmetad/server.c
|
||
|
|
index 28188e75..24083122 100644
|
||
|
|
--- a/gmetad/server.c
|
||
|
|
+++ b/gmetad/server.c
|
||
|
|
@@ -68,7 +68,11 @@ static const struct metricinfo
|
||
|
|
{
|
||
|
|
"cpu_sintr", cpu_sintr_func, g_float},
|
||
|
|
{
|
||
|
|
- "cpu_steal", cpu_steal_func, g_uint16},
|
||
|
|
+ "cpu_steal", cpu_steal_func, g_float},
|
||
|
|
+ {
|
||
|
|
+ "cpu_guest", cpu_guest_func, g_float},
|
||
|
|
+ {
|
||
|
|
+ "cpu_gnice", cpu_gnice_func, g_float},
|
||
|
|
{
|
||
|
|
"load_one", load_one_func, g_float},
|
||
|
|
{
|
||
|
|
@@ -115,6 +119,10 @@ static const struct metricinfo
|
||
|
|
#ifdef LINUX
|
||
|
|
"mem_sreclaimable", mem_sreclaimable_func, g_float},
|
||
|
|
{
|
||
|
|
+ "mem_slab", mem_slab_func, g_float},
|
||
|
|
+ {
|
||
|
|
+ "mem_available", mem_available_func, g_float},
|
||
|
|
+ {
|
||
|
|
#endif
|
||
|
|
#ifdef SOLARIS
|
||
|
|
"bread_sec", bread_sec_func, g_float},
|
||
|
|
diff --git a/gmetric/gmetric.c b/gmetric/gmetric.c
|
||
|
|
index 8e8da980..3328b08a 100644
|
||
|
|
--- a/gmetric/gmetric.c
|
||
|
|
+++ b/gmetric/gmetric.c
|
||
|
|
@@ -113,7 +113,8 @@ main( int argc, char *argv[] )
|
||
|
|
if(args_info.group_given)
|
||
|
|
{
|
||
|
|
char *last;
|
||
|
|
- for (char *group = apr_strtok(args_info.group_arg, ", ", &last); group != NULL; group = apr_strtok(NULL, ", ", &last)) {
|
||
|
|
+ char *group;
|
||
|
|
+ for (group = apr_strtok(args_info.group_arg, ", ", &last); group != NULL; group = apr_strtok(NULL, ", ", &last)) {
|
||
|
|
Ganglia_metadata_add(gmetric, "GROUP", group);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
diff --git a/gmond/conf.pod b/gmond/conf.pod
|
||
|
|
index 96531574..a4971631 100644
|
||
|
|
--- a/gmond/conf.pod
|
||
|
|
+++ b/gmond/conf.pod
|
||
|
|
@@ -166,6 +166,10 @@ For example, in a 32-bit Intel compatible Linux host that is usually:
|
||
|
|
|
||
|
|
/usr/lib/ganglia
|
||
|
|
|
||
|
|
+The B<tags> parameter is optional, and may be used to include arbitrary
|
||
|
|
+information in various output produced by Gmond, including the XML.
|
||
|
|
+It will be included as the I<TAGS> attribute of the <HOST> XML tab.
|
||
|
|
+
|
||
|
|
=head2 udp_send_channel
|
||
|
|
|
||
|
|
You can define as many B<udp_send_channel> sections as you like within
|
||
|
|
diff --git a/gmond/g25_config.c b/gmond/g25_config.c
|
||
|
|
index d295ab64..98721817 100644
|
||
|
|
--- a/gmond/g25_config.c
|
||
|
|
+++ b/gmond/g25_config.c
|
||
|
|
@@ -373,5 +373,6 @@ print_ganglia_25_config( char *path )
|
||
|
|
dotconf_cleanup(configfile);
|
||
|
|
|
||
|
|
print_config(path, &gmond_config);
|
||
|
|
+ fclose(fp);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
diff --git a/gmond/gmond.c b/gmond/gmond.c
|
||
|
|
index 7790e981..04a4b024 100644
|
||
|
|
--- a/gmond/gmond.c
|
||
|
|
+++ b/gmond/gmond.c
|
||
|
|
@@ -775,16 +775,15 @@ setup_listen_channels_pollset( void )
|
||
|
|
|
||
|
|
if(buffer)
|
||
|
|
{
|
||
|
|
- /* RB: getsockopt() returns double SO_RCVBUF since kernel reserves overhead space */
|
||
|
|
+ /* NOTE: getsockopt() returns double SO_RCVBUF on Linux for reserved overhead space */
|
||
|
|
if(rx_buf_sz!=(buffer*2))
|
||
|
|
{
|
||
|
|
- err_msg("Error setting UDP receive buffer for port %d bind=%s to size: %d.\n",
|
||
|
|
+ err_msg("WARNING When setting UDP receive buffer for port %d bind=%s to size: %d.\n",
|
||
|
|
port, bindaddr? bindaddr: "unspecified", (apr_int32_t) buffer);
|
||
|
|
- err_msg("Reported buffer size by OS: %d : does not match config setting %d.\n",
|
||
|
|
- (int) (rx_buf_sz/2), (int) buffer);
|
||
|
|
- err_msg("NOTE: only supported on systems that have Apache Portable Runtime library version 0.9.4 or higher.\n");
|
||
|
|
- err_msg("Check Operating System (kernel) limits, change or disable buffer size. Exiting.\n");
|
||
|
|
- exit(EXIT_FAILURE);
|
||
|
|
+ err_msg("Reported raw buffer size by OS: %d : config setting %d. Unable to verify\n",
|
||
|
|
+ (int) rx_buf_sz, (int) buffer);
|
||
|
|
+ err_msg("NOTE: Linux will report twice the configured value. See socket(7).\n");
|
||
|
|
+ err_msg("Check Operating System (kernel) limits, change or disable buffer size.\n");
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{ /* RB: Eureka */
|
||
|
|
@@ -1013,34 +1012,49 @@ Ganglia_host_get( char *remIP, apr_sockaddr_t *sa, Ganglia_metric_id *metric_id)
|
||
|
|
|
||
|
|
/* split out the spoofed host name and ip address so that it can
|
||
|
|
* be used to get the spoofed host. */
|
||
|
|
- if(metric_id && metric_id->spoof)
|
||
|
|
+ if(metric_id && metric_id->spoof && metric_id->host)
|
||
|
|
{
|
||
|
|
- char *spoofName;
|
||
|
|
- char *spoofIP;
|
||
|
|
int spoof_info_len;
|
||
|
|
|
||
|
|
spoof_info_len = strlen(metric_id->host);
|
||
|
|
- buff = malloc(spoof_info_len+1);
|
||
|
|
- strncpy(buff, metric_id->host, spoof_info_len + 1);
|
||
|
|
- spoofIP = buff;
|
||
|
|
- if( !(spoofName = strchr(buff+1,':')) ){
|
||
|
|
- err_msg("Incorrect format for spoof argument. exiting.\n");
|
||
|
|
- if (spoofIP) debug_msg("spoofIP: %s \n",spoofIP);
|
||
|
|
- if (buff) debug_msg("buff: %s \n",buff);
|
||
|
|
- if (buff) free(buff);
|
||
|
|
+ /* don't bother if the host string is empty */
|
||
|
|
+ if(spoof_info_len > 0)
|
||
|
|
+ {
|
||
|
|
+ char *spoofName;
|
||
|
|
+ char *spoofIP;
|
||
|
|
+
|
||
|
|
+ buff = malloc(spoof_info_len+1);
|
||
|
|
+ if(buff == NULL)
|
||
|
|
+ {
|
||
|
|
+ err_msg("Unable to allocate spoof argument parse buffer. exiting.\n");
|
||
|
|
+ return NULL;
|
||
|
|
+ }
|
||
|
|
+ strncpy(buff, metric_id->host, spoof_info_len + 1);
|
||
|
|
+ spoofIP = buff;
|
||
|
|
+ if( !(spoofName = strchr(buff+1,':')) ){
|
||
|
|
+ err_msg("Incorrect format for spoof argument (no colon delimiter). exiting.\n");
|
||
|
|
+ if (spoofIP) debug_msg("spoofIP: %s \n",spoofIP);
|
||
|
|
+ if (buff) debug_msg("buff: %s \n",buff);
|
||
|
|
+ if (buff) free(buff);
|
||
|
|
+ return NULL;
|
||
|
|
+ }
|
||
|
|
+ *spoofName = 0;
|
||
|
|
+ spoofName++;
|
||
|
|
+ if(!(*spoofName)){
|
||
|
|
+ err_msg("Incorrect format for spoof argument (empty hostname). exiting.\n");
|
||
|
|
+ if (buff) free(buff);
|
||
|
|
+ return NULL;
|
||
|
|
+ }
|
||
|
|
+ debug_msg(" spoofName: %s spoofIP: %s \n",spoofName,spoofIP);
|
||
|
|
+
|
||
|
|
+ hostname = spoofName;
|
||
|
|
+ remoteip = spoofIP;
|
||
|
|
+ }
|
||
|
|
+ else
|
||
|
|
+ {
|
||
|
|
+ err_msg("Incorrect format for spoof argument (host string empty). exiting.\n");
|
||
|
|
return NULL;
|
||
|
|
- }
|
||
|
|
- *spoofName = 0;
|
||
|
|
- spoofName++;
|
||
|
|
- if(!(*spoofName)){
|
||
|
|
- err_msg("Incorrect format for spoof argument. exiting.\n");
|
||
|
|
- if (buff) free(buff);
|
||
|
|
- return NULL;
|
||
|
|
- }
|
||
|
|
- debug_msg(" spoofName: %s spoofIP: %s \n",spoofName,spoofIP);
|
||
|
|
-
|
||
|
|
- hostname = spoofName;
|
||
|
|
- remoteip = spoofIP;
|
||
|
|
+ }
|
||
|
|
}
|
||
|
|
|
||
|
|
apr_thread_mutex_lock(hosts_mutex);
|
||
|
|
@@ -2030,13 +2044,20 @@ process_tcp_accept_channel(const apr_pollfd_t *desc, apr_time_t now)
|
||
|
|
channel = desc->client_data;
|
||
|
|
|
||
|
|
/* Create a context for the client connection */
|
||
|
|
- apr_pool_create(&client_context, global_context);
|
||
|
|
+ status = apr_pool_create(&client_context, global_context);
|
||
|
|
+ if(status != APR_SUCCESS)
|
||
|
|
+ {
|
||
|
|
+ return;
|
||
|
|
+ }
|
||
|
|
|
||
|
|
/* Accept the connection */
|
||
|
|
status = apr_socket_accept(&client, server, client_context);
|
||
|
|
if(status != APR_SUCCESS)
|
||
|
|
{
|
||
|
|
- goto close_accept_socket;
|
||
|
|
+ debug_msg("failed to accept");
|
||
|
|
+ /* Failed to accept, socket was not created
|
||
|
|
+ * Clear a prepared client context */
|
||
|
|
+ goto clear_client_context;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Set the timeout for writing to the client */
|
||
|
|
@@ -2144,6 +2165,7 @@ process_tcp_accept_channel(const apr_pollfd_t *desc, apr_time_t now)
|
||
|
|
close_accept_socket:
|
||
|
|
apr_socket_shutdown(client, APR_SHUTDOWN_READ);
|
||
|
|
apr_socket_close(client);
|
||
|
|
+clear_client_context:
|
||
|
|
apr_pool_destroy(client_context);
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -2298,6 +2320,7 @@ load_metric_modules( void )
|
||
|
|
{
|
||
|
|
cfg_t *tmp;
|
||
|
|
int j;
|
||
|
|
+ apr_hash_t *modules_loaded = apr_hash_make(global_context);
|
||
|
|
|
||
|
|
tmp = cfg_getsec( config_file, "modules");
|
||
|
|
for (j = 0; j < cfg_size(tmp, "module"); j++)
|
||
|
|
@@ -2309,6 +2332,7 @@ load_metric_modules( void )
|
||
|
|
apr_array_header_t *modParams_list = NULL;
|
||
|
|
int k, modEnabled;
|
||
|
|
apr_status_t merge_ret;
|
||
|
|
+ char *module_key = NULL;
|
||
|
|
|
||
|
|
cfg_t *module = cfg_getnsec(tmp, "module", j);
|
||
|
|
|
||
|
|
@@ -2345,6 +2369,17 @@ load_metric_modules( void )
|
||
|
|
}
|
||
|
|
modName = cfg_getstr(module, "name");
|
||
|
|
modparams = cfg_getstr(module, "params");
|
||
|
|
+
|
||
|
|
+
|
||
|
|
+ /* Check that we haven't loaded this module already, now
|
||
|
|
+ * that we've pulled the module name and path */
|
||
|
|
+ module_key = apr_pstrcat(global_context, modName, ":", modPath, NULL);
|
||
|
|
+ debug_msg("loading %s @ %s", modName, modPath);
|
||
|
|
+ if (NULL != apr_hash_get(modules_loaded, module_key, APR_HASH_KEY_STRING)) {
|
||
|
|
+ err_quit("Attempt to load module %s @ %s more than once.", modName, modPath);
|
||
|
|
+ continue;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
modParams_list = apr_array_make(global_context, 2, sizeof(mmparam));
|
||
|
|
|
||
|
|
for (k = 0; k < cfg_size(module, "param"); k++)
|
||
|
|
@@ -2372,6 +2407,7 @@ load_metric_modules( void )
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
debug_msg("loaded module: %s", modName);
|
||
|
|
+ apr_hash_set(modules_loaded, module_key, APR_HASH_KEY_STRING, apr_pstrdup(global_context, "true"));
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Retrieve the pointer to the module structure through the module name.
|
||
|
|
@@ -2976,7 +3012,13 @@ Ganglia_collection_group_send( Ganglia_collection_group *group, apr_time_t now)
|
||
|
|
name = cb->msg.Ganglia_value_msg_u.gstr.metric_id.name;
|
||
|
|
if (override_hostname != NULL)
|
||
|
|
{
|
||
|
|
- cb->msg.Ganglia_value_msg_u.gstr.metric_id.host = apr_pstrcat(gm_pool, (char *)( override_ip != NULL ? override_ip : override_hostname ), ":", (char *) override_hostname, NULL);
|
||
|
|
+ /* Since cb will live beyond this function call, we need to
|
||
|
|
+ * allocate the host field from the global pool and NOT the
|
||
|
|
+ * temporary gm_pool from the metric object. (Note that
|
||
|
|
+ * Ganglia_metric_callback objects are allocated from
|
||
|
|
+ * global_context elsewhere in this file.)
|
||
|
|
+ */
|
||
|
|
+ cb->msg.Ganglia_value_msg_u.gstr.metric_id.host = apr_pstrcat(global_context, (char *)( override_ip != NULL ? override_ip : override_hostname ), ":", (char *) override_hostname, NULL);
|
||
|
|
cb->msg.Ganglia_value_msg_u.gstr.metric_id.spoof = TRUE;
|
||
|
|
}
|
||
|
|
val = apr_pstrdup(gm_pool, host_metric_value(cb->info, &(cb->msg)));
|
||
|
|
@@ -3294,6 +3336,7 @@ main ( int argc, char *argv[] )
|
||
|
|
{
|
||
|
|
apr_time_t now, next_collection, last_cleanup;
|
||
|
|
apr_pool_t *cleanup_context;
|
||
|
|
+ apr_thread_t *tcp_listener_thread = NULL;
|
||
|
|
|
||
|
|
gmond_argv = argv;
|
||
|
|
|
||
|
|
@@ -3415,8 +3458,7 @@ main ( int argc, char *argv[] )
|
||
|
|
/* Create TCP listener thread */
|
||
|
|
if(!deaf)
|
||
|
|
{
|
||
|
|
- apr_thread_t *thread;
|
||
|
|
- if (apr_thread_create(&thread, NULL, tcp_listener, NULL, global_context) != APR_SUCCESS)
|
||
|
|
+ if (apr_thread_create(&tcp_listener_thread, NULL, tcp_listener, NULL, global_context) != APR_SUCCESS)
|
||
|
|
{
|
||
|
|
err_msg("Failed to create TCP listener thread. Exiting.\n");
|
||
|
|
exit(EXIT_FAILURE);
|
||
|
|
@@ -3477,6 +3519,16 @@ main ( int argc, char *argv[] )
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
+ if(tcp_listener_thread)
|
||
|
|
+ {
|
||
|
|
+ apr_status_t status = SUCCESS;
|
||
|
|
+ if((status = apr_thread_join(&status, tcp_listener_thread)) != APR_SUCCESS)
|
||
|
|
+ {
|
||
|
|
+ char buff[512];
|
||
|
|
+ debug_msg("apr_thread_join returned unexpected status %d = %s\n", status, apr_strerror(status, buff, 511));
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
apr_pool_destroy(global_context);
|
||
|
|
|
||
|
|
if(reload_required == 1)
|
||
|
|
diff --git a/gmond/gmond.service.in b/gmond/gmond.service.in
|
||
|
|
index 3fd136b4..13774e80 100644
|
||
|
|
--- a/gmond/gmond.service.in
|
||
|
|
+++ b/gmond/gmond.service.in
|
||
|
|
@@ -1,6 +1,6 @@
|
||
|
|
[Unit]
|
||
|
|
Description=Ganglia Monitor Daemon
|
||
|
|
-After=network.target
|
||
|
|
+After=network-online.target
|
||
|
|
|
||
|
|
[Service]
|
||
|
|
Type=forking
|
||
|
|
diff --git a/gmond/modules/cpu/mod_cpu.c b/gmond/modules/cpu/mod_cpu.c
|
||
|
|
index c5323a7b..f510dabb 100644
|
||
|
|
--- a/gmond/modules/cpu/mod_cpu.c
|
||
|
|
+++ b/gmond/modules/cpu/mod_cpu.c
|
||
|
|
@@ -58,6 +58,10 @@ static g_val_t cpu_metric_handler ( int metric_index )
|
||
|
|
return cpu_sintr_func();
|
||
|
|
case 10:
|
||
|
|
return cpu_steal_func();
|
||
|
|
+ case 11:
|
||
|
|
+ return cpu_guest_func();
|
||
|
|
+ case 12:
|
||
|
|
+ return cpu_gnice_func();
|
||
|
|
}
|
||
|
|
|
||
|
|
/* default case */
|
||
|
|
@@ -78,6 +82,8 @@ static Ganglia_25metric cpu_metric_info[] =
|
||
|
|
{0, "cpu_intr", 90, GANGLIA_VALUE_FLOAT, "%", "both", "%.1f", UDP_HEADER_SIZE+8, "cpu_intr"},
|
||
|
|
{0, "cpu_sintr", 90, GANGLIA_VALUE_FLOAT, "%", "both", "%.1f", UDP_HEADER_SIZE+8, "cpu_sintr"},
|
||
|
|
{0, "cpu_steal", 90, GANGLIA_VALUE_FLOAT, "%", "both", "%.1f", UDP_HEADER_SIZE+8, "cpu_steal"},
|
||
|
|
+ {0, "cpu_guest", 90, GANGLIA_VALUE_FLOAT, "%", "both", "%.1f", UDP_HEADER_SIZE+8, "cpu_guest"},
|
||
|
|
+ {0, "cpu_gnice", 90, GANGLIA_VALUE_FLOAT, "%", "both", "%.1f", UDP_HEADER_SIZE+8, "cpu_gnice"},
|
||
|
|
{0, NULL}
|
||
|
|
|
||
|
|
};
|
||
|
|
diff --git a/gmond/modules/cpu/mod_multicpu.c b/gmond/modules/cpu/mod_multicpu.c
|
||
|
|
index 253e0969..f57bad76 100644
|
||
|
|
--- a/gmond/modules/cpu/mod_multicpu.c
|
||
|
|
+++ b/gmond/modules/cpu/mod_multicpu.c
|
||
|
|
@@ -76,6 +76,8 @@ static cpu_util *cpu_wio = NULL;
|
||
|
|
static cpu_util *cpu_intr = NULL;
|
||
|
|
static cpu_util *cpu_sintr = NULL;
|
||
|
|
static cpu_util *cpu_steal = NULL;
|
||
|
|
+static cpu_util *cpu_guest = NULL;
|
||
|
|
+static cpu_util *cpu_gnice = NULL;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* A helper function to determine the number of cpustates in /proc/stat (MKN)
|
||
|
|
@@ -102,6 +104,10 @@ static void init_cpu_info (void)
|
||
|
|
** Loop over file until next "cpu" token is found.
|
||
|
|
** i=4 : Linux 2.4.x
|
||
|
|
** i=7 : Linux 2.6.x
|
||
|
|
+ **
|
||
|
|
+ ** i=8 : Linux 2.6.11+
|
||
|
|
+ ** i=9 : Linux 2.6.24+
|
||
|
|
+ ** i=10: Linux 2.6.33+
|
||
|
|
*/
|
||
|
|
while (strncmp(p,"cpu",3)) {
|
||
|
|
p = skip_token(p);
|
||
|
|
@@ -190,7 +196,8 @@ static char *find_cpu (char *p, int cpu_index, double *total_jiffies)
|
||
|
|
static double total_jiffies_func (char *p)
|
||
|
|
{
|
||
|
|
unsigned long user_jiffies, nice_jiffies, system_jiffies, idle_jiffies,
|
||
|
|
- wio_jiffies, irq_jiffies, sirq_jiffies, steal_jiffies;
|
||
|
|
+ wio_jiffies, irq_jiffies, sirq_jiffies, steal_jiffies,
|
||
|
|
+ guest_jiffies, gnice_jiffies;
|
||
|
|
|
||
|
|
user_jiffies = strtod( p, &p );
|
||
|
|
p = skip_whitespace(p);
|
||
|
|
@@ -216,6 +223,10 @@ static double total_jiffies_func (char *p)
|
||
|
|
|
||
|
|
p = skip_whitespace(p);
|
||
|
|
steal_jiffies = strtod( p , &p );
|
||
|
|
+ p = skip_whitespace(p);
|
||
|
|
+ guest_jiffies = strtod( p , &p ); /* "guest" included in user already */
|
||
|
|
+ p = skip_whitespace(p);
|
||
|
|
+ gnice_jiffies = strtod( p , &p ); /* "gnice" included in nice already */
|
||
|
|
return user_jiffies + nice_jiffies + system_jiffies + idle_jiffies +
|
||
|
|
wio_jiffies + irq_jiffies + sirq_jiffies + steal_jiffies;
|
||
|
|
}
|
||
|
|
@@ -457,7 +468,7 @@ static cpu_util *init_metric (apr_pool_t *p, apr_array_header_t *ar, int cpu_cou
|
||
|
|
static g_val_t multi_cpu_steal_func (int cpu_index)
|
||
|
|
{
|
||
|
|
char *p;
|
||
|
|
- cpu_util *cpu = &(cpu_user[cpu_index]);
|
||
|
|
+ cpu_util *cpu = &(cpu_steal[cpu_index]);
|
||
|
|
|
||
|
|
p = update_file(&proc_stat);
|
||
|
|
if((proc_stat.last_read.tv_sec != cpu->stamp.tv_sec) &&
|
||
|
|
@@ -479,6 +490,59 @@ static g_val_t multi_cpu_steal_func (int cpu_index)
|
||
|
|
return cpu->val;
|
||
|
|
}
|
||
|
|
|
||
|
|
+static g_val_t multi_cpu_guest_func (int cpu_index)
|
||
|
|
+{
|
||
|
|
+ char *p;
|
||
|
|
+ cpu_util *cpu = &(cpu_guest[cpu_index]);
|
||
|
|
+
|
||
|
|
+ p = update_file(&proc_stat);
|
||
|
|
+ if((proc_stat.last_read.tv_sec != cpu->stamp.tv_sec) &&
|
||
|
|
+ (proc_stat.last_read.tv_usec != cpu->stamp.tv_usec)) {
|
||
|
|
+ cpu->stamp = proc_stat.last_read;
|
||
|
|
+
|
||
|
|
+ p = find_cpu (p, cpu_index, &cpu->curr_total_jiffies);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_whitespace(p);
|
||
|
|
+ calculate_utilization (p, cpu);
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return cpu->val;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+static g_val_t multi_cpu_gnice_func (int cpu_index)
|
||
|
|
+{
|
||
|
|
+ char *p;
|
||
|
|
+ cpu_util *cpu = &(cpu_gnice[cpu_index]);
|
||
|
|
+
|
||
|
|
+ p = update_file(&proc_stat);
|
||
|
|
+ if((proc_stat.last_read.tv_sec != cpu->stamp.tv_sec) &&
|
||
|
|
+ (proc_stat.last_read.tv_usec != cpu->stamp.tv_usec)) {
|
||
|
|
+ cpu->stamp = proc_stat.last_read;
|
||
|
|
+
|
||
|
|
+ p = find_cpu (p, cpu_index, &cpu->curr_total_jiffies);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_whitespace(p);
|
||
|
|
+ calculate_utilization (p, cpu);
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return cpu->val;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
static int ex_metric_init (apr_pool_t *p)
|
||
|
|
{
|
||
|
|
int i;
|
||
|
|
@@ -515,6 +579,10 @@ static int ex_metric_init (apr_pool_t *p)
|
||
|
|
"executing at the sintr level");
|
||
|
|
cpu_steal = init_metric (pool, metric_info, cpu_count, "multicpu_steal",
|
||
|
|
"Percentage of CPU preempted by the hypervisor");
|
||
|
|
+ cpu_guest = init_metric (pool, metric_info, cpu_count, "multicpu_guest",
|
||
|
|
+ "Percentage of CPU running a virtual CPU");
|
||
|
|
+ cpu_gnice = init_metric (pool, metric_info, cpu_count, "multicpu_gnice",
|
||
|
|
+ "Percentage of CPU running a niced guest");
|
||
|
|
|
||
|
|
/* Add a terminator to the array and replace the empty static metric definition
|
||
|
|
array with the dynamic array that we just created
|
||
|
|
@@ -574,6 +642,12 @@ static g_val_t ex_metric_handler ( int metric_index )
|
||
|
|
if (strcmp(name, "multicpu_steal") == 0)
|
||
|
|
return multi_cpu_steal_func(index);
|
||
|
|
|
||
|
|
+ if (strcmp(name, "multicpu_guest") == 0)
|
||
|
|
+ return multi_cpu_guest_func(index);
|
||
|
|
+
|
||
|
|
+ if (strcmp(name, "multicpu_gnice") == 0)
|
||
|
|
+ return multi_cpu_gnice_func(index);
|
||
|
|
+
|
||
|
|
/* default case */
|
||
|
|
val.f = 0;
|
||
|
|
return val;
|
||
|
|
diff --git a/gmond/modules/memory/mod_mem.c b/gmond/modules/memory/mod_mem.c
|
||
|
|
index feb8d99c..98c0812c 100644
|
||
|
|
--- a/gmond/modules/memory/mod_mem.c
|
||
|
|
+++ b/gmond/modules/memory/mod_mem.c
|
||
|
|
@@ -50,6 +50,10 @@ static g_val_t mem_metric_handler ( int metric_index )
|
||
|
|
#ifdef LINUX
|
||
|
|
case 7:
|
||
|
|
return mem_sreclaimable_func();
|
||
|
|
+ case 8:
|
||
|
|
+ return mem_slab_func();
|
||
|
|
+ case 9:
|
||
|
|
+ return mem_available_func();
|
||
|
|
#endif
|
||
|
|
#if HPUX
|
||
|
|
case 7:
|
||
|
|
@@ -79,6 +83,8 @@ static Ganglia_25metric mem_metric_info[] =
|
||
|
|
{0, "swap_total", 1200, GANGLIA_VALUE_FLOAT, "KB", "zero", "%.0f", UDP_HEADER_SIZE+8, "Total amount of swap space displayed in KBs"},
|
||
|
|
#ifdef LINUX
|
||
|
|
{0, "mem_sreclaimable", 180, GANGLIA_VALUE_FLOAT, "KB", "both", "%.0f", UDP_HEADER_SIZE+8, "Amount of reclaimable slab memory"},
|
||
|
|
+ {0, "mem_slab", 180, GANGLIA_VALUE_FLOAT, "KB", "both", "%.0f", UDP_HEADER_SIZE+8, "Amount of in-kernel data structures cache"},
|
||
|
|
+ {0, "mem_available", 180, GANGLIA_VALUE_FLOAT, "KB", "both", "%.0f", UDP_HEADER_SIZE+8, "Estimate of how much memory is available"},
|
||
|
|
#endif
|
||
|
|
#if HPUX
|
||
|
|
{0, "mem_arm", 180, GANGLIA_VALUE_FLOAT, "KB", "both", "%.0f", UDP_HEADER_SIZE+8, "mem_arm"},
|
||
|
|
diff --git a/gmond/python_modules/apache_status/apache_status.py b/gmond/python_modules/apache_status/apache_status.py
|
||
|
|
index e33e5ea9..580e8931 100755
|
||
|
|
--- a/gmond/python_modules/apache_status/apache_status.py
|
||
|
|
+++ b/gmond/python_modules/apache_status/apache_status.py
|
||
|
|
@@ -86,6 +86,10 @@ def get_metrics():
|
||
|
|
for sck in split_line[1]:
|
||
|
|
metrics[ Scoreboard_bykey[sck] ] += 1
|
||
|
|
else:
|
||
|
|
+ # Apache > 2.4.16 inserts the hostname as the first line, so ignore
|
||
|
|
+ if len(split_line) == 1:
|
||
|
|
+ continue
|
||
|
|
+
|
||
|
|
if long_metric_name in Metric_Map:
|
||
|
|
metric_name = Metric_Map[long_metric_name]
|
||
|
|
else:
|
||
|
|
diff --git a/gmond/python_modules/network/multi_interface.py b/gmond/python_modules/network/multi_interface.py
|
||
|
|
index 3f9b45d0..456704b8 100644
|
||
|
|
--- a/gmond/python_modules/network/multi_interface.py
|
||
|
|
+++ b/gmond/python_modules/network/multi_interface.py
|
||
|
|
@@ -247,7 +247,7 @@ def get_aggregates(name):
|
||
|
|
except KeyError:
|
||
|
|
delta = 0.0
|
||
|
|
|
||
|
|
- sum += delta
|
||
|
|
+ sum += delta
|
||
|
|
|
||
|
|
return sum
|
||
|
|
|
||
|
|
diff --git a/gmond/python_modules/network/netstats.py b/gmond/python_modules/network/netstats.py
|
||
|
|
index f9c6795f..66c378d2 100644
|
||
|
|
--- a/gmond/python_modules/network/netstats.py
|
||
|
|
+++ b/gmond/python_modules/network/netstats.py
|
||
|
|
@@ -19,6 +19,8 @@ stats_files = ["/proc/net/netstat", "/proc/net/snmp"]
|
||
|
|
|
||
|
|
LAST_METRICS = copy.deepcopy(METRICS)
|
||
|
|
METRICS_CACHE_MAX = 5
|
||
|
|
+# Metrics that are not counters but absolute values
|
||
|
|
+ABSOLUTE_VALUES = ["currestab"]
|
||
|
|
|
||
|
|
stats_pos = {}
|
||
|
|
|
||
|
|
@@ -46,6 +48,8 @@ def get_metrics():
|
||
|
|
count = 0
|
||
|
|
metrics = re.split("\s+", line)
|
||
|
|
metric_group = metrics[0].replace(":", "").lower()
|
||
|
|
+ if metric_group not in stats_pos:
|
||
|
|
+ continue
|
||
|
|
new_metrics[metric_group] = dict()
|
||
|
|
for value in metrics:
|
||
|
|
# Skip first
|
||
|
|
@@ -69,12 +73,15 @@ def get_metrics():
|
||
|
|
def get_value(name):
|
||
|
|
"""Return a value for the requested metric"""
|
||
|
|
|
||
|
|
- metrics = get_metrics()[0]
|
||
|
|
+ # get metrics
|
||
|
|
+ [curr_metrics, last_metrics] = get_metrics()
|
||
|
|
|
||
|
|
- name = name[len(NAME_PREFIX):] # remove prefix from name
|
||
|
|
+ parts = name.split("_")
|
||
|
|
+ group = parts[0]
|
||
|
|
+ metric = "_".join(parts[1:])
|
||
|
|
|
||
|
|
try:
|
||
|
|
- result = metrics['data'][name]
|
||
|
|
+ result = float(curr_metrics['data'][group][metric])
|
||
|
|
except StandardError:
|
||
|
|
result = 0
|
||
|
|
|
||
|
|
@@ -209,11 +216,17 @@ def metric_init(params):
|
||
|
|
|
||
|
|
for group in stats_pos:
|
||
|
|
for item in stats_pos[group]:
|
||
|
|
- descriptors.append(create_desc(Desc_Skel, {
|
||
|
|
+ if stats_pos[group][item] in ABSOLUTE_VALUES:
|
||
|
|
+ descriptors.append(create_desc(Desc_Skel, {
|
||
|
|
"name" : group + "_" + stats_pos[group][item],
|
||
|
|
- "description": stats_pos[group][item],
|
||
|
|
- 'groups' : group
|
||
|
|
- }))
|
||
|
|
+ "call_back" : get_value,
|
||
|
|
+ "groups" : group
|
||
|
|
+ }))
|
||
|
|
+ else:
|
||
|
|
+ descriptors.append(create_desc(Desc_Skel, {
|
||
|
|
+ "name" : group + "_" + stats_pos[group][item],
|
||
|
|
+ "groups" : group
|
||
|
|
+ }))
|
||
|
|
|
||
|
|
descriptors.append(create_desc(Desc_Skel, {
|
||
|
|
"name" : "tcpext_tcploss_percentage",
|
||
|
|
@@ -221,7 +234,7 @@ def metric_init(params):
|
||
|
|
"description": "TCP percentage loss, tcploss / insegs + outsegs",
|
||
|
|
"units" : "pct",
|
||
|
|
'groups' : 'tcpext'
|
||
|
|
- }))
|
||
|
|
+ }))
|
||
|
|
|
||
|
|
descriptors.append(create_desc(Desc_Skel, {
|
||
|
|
"name" : "tcp_attemptfails_percentage",
|
||
|
|
@@ -229,7 +242,7 @@ def metric_init(params):
|
||
|
|
"description": "TCP attemptfail percentage, tcpattemptfail / insegs + outsegs",
|
||
|
|
"units" : "pct",
|
||
|
|
'groups' : 'tcp'
|
||
|
|
- }))
|
||
|
|
+ }))
|
||
|
|
|
||
|
|
descriptors.append(create_desc(Desc_Skel, {
|
||
|
|
"name" : "tcp_retrans_percentage",
|
||
|
|
@@ -237,7 +250,7 @@ def metric_init(params):
|
||
|
|
"description": "TCP retrans percentage, retranssegs / insegs + outsegs",
|
||
|
|
"units" : "pct",
|
||
|
|
'groups' : 'tcp'
|
||
|
|
- }))
|
||
|
|
+ }))
|
||
|
|
|
||
|
|
return descriptors
|
||
|
|
|
||
|
|
@@ -247,12 +260,12 @@ def metric_cleanup():
|
||
|
|
pass
|
||
|
|
|
||
|
|
|
||
|
|
-#This code is for debugging and unit testing
|
||
|
|
+# This code is for debugging and unit testing
|
||
|
|
if __name__ == '__main__':
|
||
|
|
descriptors = metric_init(PARAMS)
|
||
|
|
while True:
|
||
|
|
for d in descriptors:
|
||
|
|
v = d['call_back'](d['name'])
|
||
|
|
- print '%s = %s' % (d['name'], v)
|
||
|
|
+ print '%s = %s' % (d['name'], v)
|
||
|
|
print 'Sleeping 15 seconds'
|
||
|
|
time.sleep(15)
|
||
|
|
diff --git a/gmond/python_modules/process/procstat.py b/gmond/python_modules/process/procstat.py
|
||
|
|
index b26849b2..93ff9a9c 100644
|
||
|
|
--- a/gmond/python_modules/process/procstat.py
|
||
|
|
+++ b/gmond/python_modules/process/procstat.py
|
||
|
|
@@ -383,6 +383,8 @@ def metric_init(params):
|
||
|
|
|
||
|
|
mem = {
|
||
|
|
'units': 'B',
|
||
|
|
+ 'value_type': 'float',
|
||
|
|
+ 'format': '%.0f',
|
||
|
|
'description': 'The total memory utilization'}
|
||
|
|
)
|
||
|
|
|
||
|
|
diff --git a/gmond/sflow.c b/gmond/sflow.c
|
||
|
|
index 80154ed7..5e633634 100644
|
||
|
|
--- a/gmond/sflow.c
|
||
|
|
+++ b/gmond/sflow.c
|
||
|
|
@@ -303,7 +303,8 @@ submit_sflow_string(Ganglia_host *hostdata, char *metric_prefix, EnumSFLOWGMetri
|
||
|
|
char mtitle_buf[SFLOW_MAX_METRIC_NAME_LEN];
|
||
|
|
if(ok || sflowCFG.submit_null_str) {
|
||
|
|
set_metric_name_and_title(&mname, &mtitle, mname_buf, mtitle_buf, metric_prefix, tag);
|
||
|
|
- fmsg.id = vmsg.id = gmetric_uint;
|
||
|
|
+ //fmsg.id = vmsg.id = gmetric_uint;
|
||
|
|
+ fmsg.id = vmsg.id = gmetric_string;
|
||
|
|
fmsg.Ganglia_metadata_msg_u.gfull.metric.type = "string";
|
||
|
|
vmsg.Ganglia_value_msg_u.gstr.metric_id.name = mname;
|
||
|
|
vmsg.Ganglia_value_msg_u.gstr.str = (ok ? (char *)val : sflowCFG.null_str);
|
||
|
|
@@ -400,7 +401,7 @@ process_struct_CPU(SFlowXDR *x, SFlowDataSource *dataSource, Ganglia_host *hostd
|
||
|
|
|
||
|
|
if(steal_and_guest) {
|
||
|
|
cpu_total += delta_cpu_steal;
|
||
|
|
- /* Note: cpu_guest is included in cpu_idle
|
||
|
|
+ /* Note: cpu_guest is included in cpu_user
|
||
|
|
* and cpu_guest_nice is included in cpu_nice
|
||
|
|
* so they do not contribute to cpu_total.
|
||
|
|
*/
|
||
|
|
@@ -1188,6 +1189,7 @@ processCounterSample(SFlowXDR *x, char **errorMsg)
|
||
|
|
SFLOWXDR_skip(x,4);
|
||
|
|
|
||
|
|
machine_type = SFLOWXDR_next(x);
|
||
|
|
+
|
||
|
|
os_name = SFLOWXDR_next(x);
|
||
|
|
osrelease_len = SFLOWXDR_next(x);
|
||
|
|
if(osrelease_len > 0 && osrelease_len <= SFLOW_MAX_OSRELEASE_LEN) {
|
||
|
|
diff --git a/gmond/sflow_gmetric.h b/gmond/sflow_gmetric.h
|
||
|
|
index d85c36e7..f8811da2 100644
|
||
|
|
--- a/gmond/sflow_gmetric.h
|
||
|
|
+++ b/gmond/sflow_gmetric.h
|
||
|
|
@@ -20,7 +20,7 @@ SFLOW_GMETRIC(SFLOW_M_cpu_intr, "cpu_intr", "", GANGLIA_SLOPE_BOTH, "%.2f", "cpu
|
||
|
|
SFLOW_GMETRIC(SFLOW_M_cpu_sintr, "cpu_sintr", "", GANGLIA_SLOPE_BOTH, "%.2f", "cpu", NULL, "CPU Soft Interrupts" )
|
||
|
|
SFLOW_GMETRIC(SFLOW_M_cpu_steal, "cpu_steal", "%", GANGLIA_SLOPE_BOTH, "%.2f", "cpu", NULL, "CPU Steal" )
|
||
|
|
SFLOW_GMETRIC(SFLOW_M_cpu_guest, "cpu_guest", "%", GANGLIA_SLOPE_BOTH, "%.2f", "cpu", NULL, "CPU Guest" )
|
||
|
|
-SFLOW_GMETRIC(SFLOW_M_cpu_guest_nice, "cpu_guest_nice", "%", GANGLIA_SLOPE_BOTH, "%.2f", "cpu", NULL, "CPU Guest Nice" )
|
||
|
|
+SFLOW_GMETRIC(SFLOW_M_cpu_guest_nice, "cpu_gnice", "%", GANGLIA_SLOPE_BOTH, "%.2f", "cpu", NULL, "CPU Guest Nice" )
|
||
|
|
SFLOW_GMETRIC(SFLOW_M_interrupts, "interrupts", "", GANGLIA_SLOPE_BOTH, "%.0f", "cpu", NULL, "Interrupts" )
|
||
|
|
SFLOW_GMETRIC(SFLOW_M_contexts, "contexts", "", GANGLIA_SLOPE_BOTH, "%.0f", "cpu", NULL, "Context Switches" )
|
||
|
|
SFLOW_GMETRIC(SFLOW_M_mem_total, "mem_total", "KB", GANGLIA_SLOPE_ZERO, "%.0f", "memory", NULL, "Memory Total" )
|
||
|
|
diff --git a/lib/default_conf.h.in b/lib/default_conf.h.in
|
||
|
|
index 142115f6..3f9e5b9f 100644
|
||
|
|
--- a/lib/default_conf.h.in
|
||
|
|
+++ b/lib/default_conf.h.in
|
||
|
|
@@ -71,7 +71,7 @@ udp_recv_channel {\n\
|
||
|
|
bind = 239.2.11.71\n\
|
||
|
|
retry_bind = true\n\
|
||
|
|
# Size of the UDP buffer. If you are handling lots of metrics you really\n\
|
||
|
|
- # should bump it up to e.g. 10MB or even higher.\n\
|
||
|
|
+ # should bump it up to e.g. 10MB or even higher.\n\
|
||
|
|
# buffer = 10485760\n\
|
||
|
|
}\n\
|
||
|
|
\n\
|
||
|
|
@@ -270,6 +270,19 @@ collection_group {\n\
|
||
|
|
title = \"CPU sintr\"\n\
|
||
|
|
}\n\
|
||
|
|
*/\n\
|
||
|
|
+ /* The next two metrics are optional if you want more detail...\n\
|
||
|
|
+ ... since they are accounted for in cpu_user and cpu_nice.\n\
|
||
|
|
+ metric {\n\
|
||
|
|
+ name = \"cpu_guest\"\n\
|
||
|
|
+ value_threshold = \"1.0\"\n\
|
||
|
|
+ title = \"CPU guest\"\n\
|
||
|
|
+ }\n\
|
||
|
|
+ metric {\n\
|
||
|
|
+ name = \"cpu_gnice\"\n\
|
||
|
|
+ value_threshold = \"1.0\"\n\
|
||
|
|
+ title = \"CPU gnice\"\n\
|
||
|
|
+ }\n\
|
||
|
|
+ */\n\
|
||
|
|
}\n\
|
||
|
|
\n\
|
||
|
|
collection_group {\n\
|
||
|
|
@@ -397,6 +410,24 @@ include (\"" SYSCONFDIR "/conf.d/*.conf\")\n\
|
||
|
|
\n\
|
||
|
|
"
|
||
|
|
|
||
|
|
+#define LINUX_SPECIFIC_CONFIGURATION "\
|
||
|
|
+collection_group {\n\
|
||
|
|
+ collect_every = 40\n\
|
||
|
|
+ time_threshold = 180\n\
|
||
|
|
+ metric {\n\
|
||
|
|
+ name = \"mem_available\"\n\
|
||
|
|
+ value_threshold = \"1024.0\"\n\
|
||
|
|
+ title = \"Available Memory\"\n\
|
||
|
|
+ }\n\
|
||
|
|
+ metric {\n\
|
||
|
|
+ name = \"mem_sreclaimable\"\n\
|
||
|
|
+ value_threshold = \"1024.0\"\n\
|
||
|
|
+ title = \"Slab Memory Reclaimable\"\n\
|
||
|
|
+ }\n\
|
||
|
|
+}\n\
|
||
|
|
+\n\
|
||
|
|
+"
|
||
|
|
+
|
||
|
|
#define SOLARIS_SPECIFIC_CONFIGURATION "\
|
||
|
|
/* solaris specific metrics begin */\n\
|
||
|
|
collection_group {\n\
|
||
|
|
diff --git a/lib/hash.c b/lib/hash.c
|
||
|
|
index a1d41e76..de922533 100644
|
||
|
|
--- a/lib/hash.c
|
||
|
|
+++ b/lib/hash.c
|
||
|
|
@@ -346,6 +346,10 @@ hash_delete (datum_t *key, hash_t * hash)
|
||
|
|
for (; bucket != NULL; last = bucket, bucket = bucket->next)
|
||
|
|
{
|
||
|
|
node_t tmp;
|
||
|
|
+ if (bucket->key && !hash_keycmp(hash, key, bucket->key))
|
||
|
|
+ {
|
||
|
|
+ continue;
|
||
|
|
+ }
|
||
|
|
if (bucket == &hash->node[i])
|
||
|
|
{
|
||
|
|
tmp.key = bucket->key;
|
||
|
|
diff --git a/lib/libgmond.c b/lib/libgmond.c
|
||
|
|
index f5eb32f1..d378d8e9 100644
|
||
|
|
--- a/lib/libgmond.c
|
||
|
|
+++ b/lib/libgmond.c
|
||
|
|
@@ -26,7 +26,11 @@
|
||
|
|
#include <dirent.h>
|
||
|
|
#include <fnmatch.h>
|
||
|
|
|
||
|
|
-static char myhost[APRMAXHOSTLEN+1];
|
||
|
|
+/* functions throughout this file will initialize this
|
||
|
|
+ * variable if myhost[0] == '\0', so ensure the compiler
|
||
|
|
+ * initializes it as an empty string:
|
||
|
|
+ */
|
||
|
|
+static char myhost[APRMAXHOSTLEN+1] = "";
|
||
|
|
|
||
|
|
/***** IMPORTANT ************
|
||
|
|
Any changes that you make to this file need to be reconciled in ./conf.pod
|
||
|
|
@@ -210,6 +214,9 @@ build_default_gmond_configuration(Ganglia_pool p)
|
||
|
|
default_gmond_configuration = apr_pstrcat(context, default_gmond_configuration, SFLOW_CONFIGURATION, NULL);
|
||
|
|
#endif
|
||
|
|
default_gmond_configuration = apr_pstrcat(context, default_gmond_configuration, COLLECTION_GROUP_LIST, NULL);
|
||
|
|
+#if LINUX
|
||
|
|
+ default_gmond_configuration = apr_pstrcat(context, default_gmond_configuration, LINUX_SPECIFIC_CONFIGURATION, NULL);
|
||
|
|
+#endif
|
||
|
|
#if SOLARIS
|
||
|
|
default_gmond_configuration = apr_pstrcat(context, default_gmond_configuration, SOLARIS_SPECIFIC_CONFIGURATION, NULL);
|
||
|
|
#endif
|
||
|
|
diff --git a/libmetrics/darwin/metrics.c b/libmetrics/darwin/metrics.c
|
||
|
|
index 690e88ed..c9940eba 100644
|
||
|
|
--- a/libmetrics/darwin/metrics.c
|
||
|
|
+++ b/libmetrics/darwin/metrics.c
|
||
|
|
@@ -37,7 +37,7 @@
|
||
|
|
#include <sys/socket.h>
|
||
|
|
#include <stdio.h>
|
||
|
|
|
||
|
|
-/* Added for disk statstics */
|
||
|
|
+/* Added for disk statistics */
|
||
|
|
#include <sys/param.h>
|
||
|
|
#include <sys/ucred.h>
|
||
|
|
#include <sys/mount.h>
|
||
|
|
@@ -467,6 +467,28 @@ cpu_sintr_func ( void )
|
||
|
|
return val;
|
||
|
|
}
|
||
|
|
|
||
|
|
+/*
|
||
|
|
+** FIXME
|
||
|
|
+*/
|
||
|
|
+g_val_t
|
||
|
|
+cpu_guest_func ( void )
|
||
|
|
+{
|
||
|
|
+ g_val_t val;
|
||
|
|
+ val.f = 0.0;
|
||
|
|
+ return val;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+/*
|
||
|
|
+** FIXME
|
||
|
|
+*/
|
||
|
|
+g_val_t
|
||
|
|
+cpu_gnice_func ( void )
|
||
|
|
+{
|
||
|
|
+ g_val_t val;
|
||
|
|
+ val.f = 0.0;
|
||
|
|
+ return val;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
|
||
|
|
g_val_t
|
||
|
|
bytes_in_func ( void )
|
||
|
|
diff --git a/libmetrics/libmetrics.h b/libmetrics/libmetrics.h
|
||
|
|
index fab9a092..947a387f 100644
|
||
|
|
--- a/libmetrics/libmetrics.h
|
||
|
|
+++ b/libmetrics/libmetrics.h
|
||
|
|
@@ -55,6 +55,8 @@ void libmetrics_init( void );
|
||
|
|
g_val_t cpu_intr_func(void);
|
||
|
|
g_val_t cpu_sintr_func(void);
|
||
|
|
g_val_t cpu_steal_func(void);
|
||
|
|
+ g_val_t cpu_guest_func(void);
|
||
|
|
+ g_val_t cpu_gnice_func(void);
|
||
|
|
g_val_t bytes_in_func(void);
|
||
|
|
g_val_t bytes_out_func(void);
|
||
|
|
g_val_t pkts_in_func(void);
|
||
|
|
@@ -77,7 +79,10 @@ void libmetrics_init( void );
|
||
|
|
g_val_t location_func(void);
|
||
|
|
|
||
|
|
#ifdef LINUX
|
||
|
|
+ g_val_t mem_available_func (void);
|
||
|
|
+ g_val_t mem_slab_func (void);
|
||
|
|
g_val_t mem_sreclaimable_func (void);
|
||
|
|
+ g_val_t mem_sunreclaim_func (void);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/* the following are additional internal metrics added by swagner
|
||
|
|
diff --git a/libmetrics/linux/metrics.c b/libmetrics/linux/metrics.c
|
||
|
|
index 62e7314b..456abe33 100644
|
||
|
|
--- a/libmetrics/linux/metrics.c
|
||
|
|
+++ b/libmetrics/linux/metrics.c
|
||
|
|
@@ -104,6 +104,8 @@ num_cpustates_func ( void )
|
||
|
|
** i=4 : Linux 2.4.x
|
||
|
|
** i=7 : Linux 2.6.x
|
||
|
|
** i=8 : Linux 2.6.11
|
||
|
|
+** i=9 : Linux 2.6.24
|
||
|
|
+** i=10 : Linux 2.6.33
|
||
|
|
*/
|
||
|
|
while (strncmp(p, "cpu", 3)) {
|
||
|
|
p = skip_token(p);
|
||
|
|
@@ -262,7 +264,11 @@ void update_ifdata ( char *caller )
|
||
|
|
l_bytes_in += rbi - ns->rbi;
|
||
|
|
} else {
|
||
|
|
debug_msg("update_ifdata(%s) - Overflow in rbi: %"PRI_STAT" -> %"PRI_STAT,caller,ns->rbi,rbi);
|
||
|
|
- l_bytes_in += STAT_MAX - ns->rbi + rbi;
|
||
|
|
+ if ( ns->rbi <= ULONG_MAX ) { /* assume it's more reasonable that the counter rolled over at ULONG_MAX than ULLONG_MAX */
|
||
|
|
+ l_bytes_in += ULONG_MAX - ns->rbi + rbi;
|
||
|
|
+ } else {
|
||
|
|
+ l_bytes_in += STAT_MAX - ns->rbi + rbi;
|
||
|
|
+ }
|
||
|
|
}
|
||
|
|
ns->rbi = rbi;
|
||
|
|
|
||
|
|
@@ -271,7 +277,11 @@ void update_ifdata ( char *caller )
|
||
|
|
l_pkts_in += rpi - ns->rpi;
|
||
|
|
} else {
|
||
|
|
debug_msg("updata_ifdata(%s) - Overflow in rpi: %"PRI_STAT" -> %"PRI_STAT,caller,ns->rpi,rpi);
|
||
|
|
- l_pkts_in += STAT_MAX - ns->rpi + rpi;
|
||
|
|
+ if ( ns->rpi <= ULONG_MAX ) {
|
||
|
|
+ l_pkts_in += ULONG_MAX - ns->rpi + rpi;
|
||
|
|
+ } else {
|
||
|
|
+ l_pkts_in += STAT_MAX - ns->rpi + rpi;
|
||
|
|
+ }
|
||
|
|
}
|
||
|
|
ns->rpi = rpi;
|
||
|
|
|
||
|
|
@@ -284,7 +294,11 @@ void update_ifdata ( char *caller )
|
||
|
|
l_bytes_out += rbo - ns->rbo;
|
||
|
|
} else {
|
||
|
|
debug_msg("update_ifdata(%s) - Overflow in rbo: %"PRI_STAT" -> %"PRI_STAT,caller,ns->rbo,rbo);
|
||
|
|
- l_bytes_out += STAT_MAX - ns->rbo + rbo;
|
||
|
|
+ if ( ns->rbo <= ULONG_MAX ) {
|
||
|
|
+ l_bytes_out += ULONG_MAX - ns->rbo + rbo;
|
||
|
|
+ } else {
|
||
|
|
+ l_bytes_out += STAT_MAX - ns->rbo + rbo;
|
||
|
|
+ }
|
||
|
|
}
|
||
|
|
ns->rbo = rbo;
|
||
|
|
|
||
|
|
@@ -293,7 +307,11 @@ void update_ifdata ( char *caller )
|
||
|
|
l_pkts_out += rpo - ns->rpo;
|
||
|
|
} else {
|
||
|
|
debug_msg("update_ifdata(%s) - Overflow in rpo: %"PRI_STAT" -> %"PRI_STAT,caller,ns->rpo,rpo);
|
||
|
|
- l_pkts_out += STAT_MAX - ns->rpo + rpo;
|
||
|
|
+ if ( ns->rpo <= ULONG_MAX ) {
|
||
|
|
+ l_pkts_out += ULONG_MAX - ns->rpo + rpo;
|
||
|
|
+ } else {
|
||
|
|
+ l_pkts_out += STAT_MAX - ns->rpo + rpo;
|
||
|
|
+ }
|
||
|
|
}
|
||
|
|
ns->rpo = rpo;
|
||
|
|
}
|
||
|
|
@@ -593,36 +611,30 @@ machine_type_func ( void )
|
||
|
|
|
||
|
|
#ifdef __i386__
|
||
|
|
snprintf(val.str, MAX_G_STRING_SIZE, "x86");
|
||
|
|
-#endif
|
||
|
|
-#ifdef __x86_64__
|
||
|
|
+#elif __x86_64__
|
||
|
|
snprintf(val.str, MAX_G_STRING_SIZE, "x86_64");
|
||
|
|
-#endif
|
||
|
|
-#ifdef __ia64__
|
||
|
|
+#elif __ia64__
|
||
|
|
snprintf(val.str, MAX_G_STRING_SIZE, "ia64");
|
||
|
|
-#endif
|
||
|
|
-#ifdef __sparc__
|
||
|
|
+#elif __sparc__
|
||
|
|
snprintf(val.str, MAX_G_STRING_SIZE, "sparc");
|
||
|
|
-#endif
|
||
|
|
-#ifdef __alpha__
|
||
|
|
+#elif __alpha__
|
||
|
|
snprintf(val.str, MAX_G_STRING_SIZE, "alpha");
|
||
|
|
-#endif
|
||
|
|
-#ifdef __powerpc__
|
||
|
|
+#elif __powerpc__
|
||
|
|
snprintf(val.str, MAX_G_STRING_SIZE, "powerpc");
|
||
|
|
-#endif
|
||
|
|
-#ifdef __m68k__
|
||
|
|
+#elif __m68k__
|
||
|
|
snprintf(val.str, MAX_G_STRING_SIZE, "m68k");
|
||
|
|
-#endif
|
||
|
|
-#ifdef __mips__
|
||
|
|
+#elif __mips__
|
||
|
|
snprintf(val.str, MAX_G_STRING_SIZE, "mips");
|
||
|
|
-#endif
|
||
|
|
-#ifdef __arm__
|
||
|
|
+#elif __arm__
|
||
|
|
snprintf(val.str, MAX_G_STRING_SIZE, "arm");
|
||
|
|
-#endif
|
||
|
|
-#ifdef __hppa__
|
||
|
|
+#elif __aarch64__
|
||
|
|
+ snprintf(val.str, MAX_G_STRING_SIZE, "aarch64");
|
||
|
|
+#elif __hppa__
|
||
|
|
snprintf(val.str, MAX_G_STRING_SIZE, "hppa");
|
||
|
|
-#endif
|
||
|
|
-#ifdef __s390__
|
||
|
|
+#elif __s390__
|
||
|
|
snprintf(val.str, MAX_G_STRING_SIZE, "s390");
|
||
|
|
+#else
|
||
|
|
+ snprintf(val.str, MAX_G_STRING_SIZE, "unknown");
|
||
|
|
#endif
|
||
|
|
|
||
|
|
return val;
|
||
|
|
@@ -691,6 +703,8 @@ total_jiffies_func ( void )
|
||
|
|
p = skip_whitespace(p);
|
||
|
|
steal_jiffies = strtod( p, &p );
|
||
|
|
|
||
|
|
+ /* guest is included in user already, and gnice is included in nice */
|
||
|
|
+
|
||
|
|
return user_jiffies + nice_jiffies + system_jiffies + idle_jiffies +
|
||
|
|
wio_jiffies + irq_jiffies + sirq_jiffies + steal_jiffies;
|
||
|
|
}
|
||
|
|
@@ -1056,6 +1070,89 @@ cpu_steal_func ( void )
|
||
|
|
return val;
|
||
|
|
}
|
||
|
|
|
||
|
|
+g_val_t
|
||
|
|
+cpu_guest_func ( void )
|
||
|
|
+{
|
||
|
|
+ char *p;
|
||
|
|
+ static g_val_t val;
|
||
|
|
+ static struct timeval stamp={0,0};
|
||
|
|
+ static double last_guest_jiffies, guest_jiffies,
|
||
|
|
+ last_total_jiffies, total_jiffies, diff;
|
||
|
|
+
|
||
|
|
+ p = update_file(&proc_stat);
|
||
|
|
+ if((proc_stat.last_read.tv_sec != stamp.tv_sec) &&
|
||
|
|
+ (proc_stat.last_read.tv_usec != stamp.tv_usec)) {
|
||
|
|
+ stamp = proc_stat.last_read;
|
||
|
|
+
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ guest_jiffies = strtod( p , (char **)NULL );
|
||
|
|
+ total_jiffies = total_jiffies_func();
|
||
|
|
+
|
||
|
|
+ diff = guest_jiffies - last_guest_jiffies;
|
||
|
|
+
|
||
|
|
+ if ( diff )
|
||
|
|
+ val.f = (diff/(total_jiffies - last_total_jiffies))*100;
|
||
|
|
+ else
|
||
|
|
+ val.f = 0.0;
|
||
|
|
+
|
||
|
|
+ last_guest_jiffies = guest_jiffies;
|
||
|
|
+ last_total_jiffies = total_jiffies;
|
||
|
|
+
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return val;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+g_val_t
|
||
|
|
+cpu_gnice_func ( void )
|
||
|
|
+{
|
||
|
|
+ char *p;
|
||
|
|
+ static g_val_t val;
|
||
|
|
+ static struct timeval stamp={0,0};
|
||
|
|
+ static double last_gnice_jiffies, gnice_jiffies,
|
||
|
|
+ last_total_jiffies, total_jiffies, diff;
|
||
|
|
+
|
||
|
|
+ p = update_file(&proc_stat);
|
||
|
|
+ if((proc_stat.last_read.tv_sec != stamp.tv_sec) &&
|
||
|
|
+ (proc_stat.last_read.tv_usec != stamp.tv_usec)) {
|
||
|
|
+ stamp = proc_stat.last_read;
|
||
|
|
+
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ gnice_jiffies = strtod( p , (char **)NULL );
|
||
|
|
+ total_jiffies = total_jiffies_func();
|
||
|
|
+
|
||
|
|
+ diff = gnice_jiffies - last_gnice_jiffies;
|
||
|
|
+
|
||
|
|
+ if ( diff )
|
||
|
|
+ val.f = (diff/(total_jiffies - last_total_jiffies))*100;
|
||
|
|
+ else
|
||
|
|
+ val.f = 0.0;
|
||
|
|
+
|
||
|
|
+ last_gnice_jiffies = gnice_jiffies;
|
||
|
|
+ last_total_jiffies = total_jiffies;
|
||
|
|
+
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return val;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
g_val_t
|
||
|
|
load_one_func ( void )
|
||
|
|
{
|
||
|
|
@@ -1150,6 +1247,23 @@ mem_free_func ( void )
|
||
|
|
return val;
|
||
|
|
}
|
||
|
|
|
||
|
|
+g_val_t
|
||
|
|
+mem_available_func ( void )
|
||
|
|
+{
|
||
|
|
+ char *p;
|
||
|
|
+ g_val_t val;
|
||
|
|
+
|
||
|
|
+ p = strstr( update_file(&proc_meminfo), "MemAvailable:" );
|
||
|
|
+ if (p) {
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ val.f = atof( p );
|
||
|
|
+ } else {
|
||
|
|
+ val.f = 0.0;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return val;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
g_val_t
|
||
|
|
mem_shared_func ( void )
|
||
|
|
{
|
||
|
|
@@ -1187,6 +1301,23 @@ mem_buffers_func ( void )
|
||
|
|
return val;
|
||
|
|
}
|
||
|
|
|
||
|
|
+g_val_t
|
||
|
|
+mem_slab_func ( void )
|
||
|
|
+{
|
||
|
|
+ char *p;
|
||
|
|
+ g_val_t val;
|
||
|
|
+
|
||
|
|
+ p = strstr( update_file(&proc_meminfo), "Slab:" );
|
||
|
|
+ if(p) {
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ val.f = atof( p );
|
||
|
|
+ } else {
|
||
|
|
+ val.f = 0;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return val;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
g_val_t
|
||
|
|
mem_sreclaimable_func ( void )
|
||
|
|
{
|
||
|
|
@@ -1204,6 +1335,23 @@ mem_sreclaimable_func ( void )
|
||
|
|
return val;
|
||
|
|
}
|
||
|
|
|
||
|
|
+g_val_t
|
||
|
|
+mem_sunreclaim_func ( void )
|
||
|
|
+{
|
||
|
|
+ char *p;
|
||
|
|
+ g_val_t val;
|
||
|
|
+
|
||
|
|
+ p = strstr( update_file(&proc_meminfo), "SUnreclaim:" );
|
||
|
|
+ if(p) {
|
||
|
|
+ p = skip_token(p);
|
||
|
|
+ val.f = atof( p );
|
||
|
|
+ } else {
|
||
|
|
+ val.f = 0;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return val;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
g_val_t
|
||
|
|
mem_cached_func ( void )
|
||
|
|
{
|
||
|
|
@@ -1388,7 +1536,8 @@ float find_disk_space(double *total_size, double *total_free)
|
||
|
|
if (!strncmp(mode, "ro", 2)) continue;
|
||
|
|
if (remote_mount(device, type)) continue;
|
||
|
|
if (strncmp(device, "/dev/", 5) != 0 &&
|
||
|
|
- strncmp(device, "/dev2/", 6) != 0) continue;
|
||
|
|
+ strncmp(device, "/dev2/", 6) != 0 &&
|
||
|
|
+ strncmp(type, "zfs", 3) != 0) continue;
|
||
|
|
thispct = device_space(mount, device, total_size, total_free);
|
||
|
|
debug_msg("Counting device %s (%.2f %%)", device, thispct);
|
||
|
|
if (!max || max<thispct)
|
||
|
|
diff --git a/libmetrics/openbsd/metrics.c b/libmetrics/openbsd/metrics.c
|
||
|
|
index c148deb9..5ea5f3c7 100644
|
||
|
|
--- a/libmetrics/openbsd/metrics.c
|
||
|
|
+++ b/libmetrics/openbsd/metrics.c
|
||
|
|
@@ -21,6 +21,7 @@
|
||
|
|
#include <sys/swap.h>
|
||
|
|
#include <uvm/uvm_param.h>
|
||
|
|
#include <sys/proc.h>
|
||
|
|
+#include <sys/vmmeter.h>
|
||
|
|
|
||
|
|
#include <sys/socket.h>
|
||
|
|
#include <net/if.h>
|
||
|
|
@@ -485,6 +486,28 @@ cpu_steal_func ( void )
|
||
|
|
return val;
|
||
|
|
}
|
||
|
|
|
||
|
|
+/*
|
||
|
|
+** FIXME
|
||
|
|
+*/
|
||
|
|
+g_val_t
|
||
|
|
+cpu_guest_func ( void )
|
||
|
|
+{
|
||
|
|
+ g_val_t val;
|
||
|
|
+ val.f = 0.0;
|
||
|
|
+ return val;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+/*
|
||
|
|
+** FIXME
|
||
|
|
+*/
|
||
|
|
+g_val_t
|
||
|
|
+cpu_gnice_func ( void )
|
||
|
|
+{
|
||
|
|
+ g_val_t val;
|
||
|
|
+ val.f = 0.0;
|
||
|
|
+ return val;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
g_val_t
|
||
|
|
mem_free_func ( void )
|
||
|
|
{
|
||
|
|
diff --git a/libmetrics/solaris/metrics.c b/libmetrics/solaris/metrics.c
|
||
|
|
index 93ca213b..b7000171 100644
|
||
|
|
--- a/libmetrics/solaris/metrics.c
|
||
|
|
+++ b/libmetrics/solaris/metrics.c
|
||
|
|
@@ -1366,3 +1366,26 @@ cpu_steal_func ( void )
|
||
|
|
return val;
|
||
|
|
}
|
||
|
|
|
||
|
|
+
|
||
|
|
+/*
|
||
|
|
+** FIXME
|
||
|
|
+*/
|
||
|
|
+g_val_t
|
||
|
|
+cpu_guest_func ( void )
|
||
|
|
+{
|
||
|
|
+ g_val_t val;
|
||
|
|
+ val.f = 0.0;
|
||
|
|
+ return val;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+/*
|
||
|
|
+** FIXME
|
||
|
|
+*/
|
||
|
|
+g_val_t
|
||
|
|
+cpu_gnice_func ( void )
|
||
|
|
+{
|
||
|
|
+ g_val_t val;
|
||
|
|
+ val.f = 0.0;
|
||
|
|
+ return val;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
diff --git a/libmetrics/tests/test-metrics.c b/libmetrics/tests/test-metrics.c
|
||
|
|
index e87717f4..b3ae3bac 100644
|
||
|
|
--- a/libmetrics/tests/test-metrics.c
|
||
|
|
+++ b/libmetrics/tests/test-metrics.c
|
||
|
|
@@ -41,6 +41,10 @@ static const struct metricinfo
|
||
|
|
{
|
||
|
|
"cpu_nice", cpu_nice_func, g_float},
|
||
|
|
{
|
||
|
|
+ "cpu_guest", cpu_guest_func, g_float},
|
||
|
|
+ {
|
||
|
|
+ "cpu_gnice", cpu_gnice_func, g_float},
|
||
|
|
+ {
|
||
|
|
"cpu_system", cpu_system_func, g_float},
|
||
|
|
{
|
||
|
|
"cpu_idle", cpu_idle_func, g_float},
|