Skip to content
Browse files

*** empty log message ***

  • Loading branch information...
1 parent eea06c0 commit 9069c9cd40da6cb44874ed282adb5e00d4f2ec40 massie committed Jan 14, 2005
View
2 monitor-core/configure.in
@@ -392,7 +392,7 @@ echo " / /_/ / /_/ / / / / /_/ / / / /_/ /"
echo " \____/\__,_/_/ /_/\__, /_/_/\__,_/"
echo " /____/"
echo ""
-echo "Copyright (c) 2004 University of California, Berkeley"
+echo "Copyright (c) 2005 University of California, Berkeley"
echo ""
echo "Version: $GANGLIA_VERSION ($GANGLIA_RELEASE_NAME)"
echo "Library: Release $LT_RELEASE $LT_CURRENT:$LT_REVISION:$LT_AGE"
View
2 monitor-core/gmond/conf.c
@@ -1,6 +1,7 @@
#include <stdio.h>
#include "conf.h"
+#if 0
extern cfg_t *config_file;
/* This function is necessary only because I need
@@ -34,3 +35,4 @@ value_callback(cfg_t *cfg, cfg_opt_t *opt, const char *value, void *result)
fprintf(stderr,"CALLED\n");
return 0;
}
+#endif
View
59 monitor-core/gmond/conf.h
@@ -8,15 +8,13 @@ in order for the documentation to be in order with the code
#include "confuse.h"
-void init_validate_funcs(void);
-
#define DEFAULT_CONFIGURATION "\
behavior { \n\
setuid = no \n\
user = nobody \n\
} \n\
udp_send_channel { \n\
- ip = 127.0.0.1 \n\
+ mcast_join = 239.2.11.71 \n\
port = 8649 \n\
} \n\
udp_recv_channel { \n\
@@ -28,26 +26,18 @@ tcp_accept_channel { \n\
port = 8666 \n\
} \n\
collection_group { \n\
- name = \"cpu_stat\" \n\
+ collect_every = 60 \n\
metric { \n\
name = \"cpu_user\" \n\
- absolute_minimum = 0 \n\
- absolute_maximum = 100 \n\
} \n\
metric { \n\
- name = \"cpu_sys\" \n\
- absolute_minimum = 0 \n\
- absolute_maximum = 100 \n\
+ name = \"cpu_system\" \n\
} \n\
metric { \n\
name = \"cpu_idle\" \n\
- absolute_minimum = 0 \n\
- absolute_maximum = 100 \n\
} \n\
metric { \n\
name = \"cpu_nice\" \n\
- absolute_minimum = 0 \n\
- absolute_maximum = 100 \n\
} \n\
} \n\
"
@@ -77,7 +67,6 @@ static cfg_opt_t udp_send_channel_opts[] = {
CFG_STR("mcast_if", NULL, CFGF_NONE),
CFG_STR("ip", NULL, CFGF_NONE ),
CFG_INT("port", -1, CFGF_NONE ),
- CFG_STR("protocol", "xdr", CFGF_NONE),
CFG_END()
};
@@ -86,7 +75,6 @@ static cfg_opt_t udp_recv_channel_opts[] = {
CFG_STR("bind", NULL, CFGF_NONE ),
CFG_INT("port", -1, CFGF_NONE ),
CFG_STR("mcast_if", NULL, CFGF_NONE),
- CFG_STR("protocol", "xdr", CFGF_NONE),
CFG_STR("allow_ip", NULL, CFGF_NONE),
CFG_STR("allow_mask", NULL, CFGF_NONE),
CFG_END()
@@ -96,64 +84,33 @@ static cfg_opt_t tcp_accept_channel_opts[] = {
CFG_STR("bind", NULL, CFGF_NONE ),
CFG_INT("port", -1, CFGF_NONE ),
CFG_STR("interface", NULL, CFGF_NONE),
- CFG_STR("protocol", "xml", CFGF_NONE),
CFG_STR("allow_ip", NULL, CFGF_NONE),
CFG_STR("allow_mask", NULL, CFGF_NONE),
CFG_END()
};
-int metric_validate_func(cfg_t *cfg, cfg_opt_t *opt);
-cfg_callback_t value_cb;
-
static cfg_opt_t metric_opts[] = {
- CFG_BOOL( "absolute_minimum_given", 0, CFGF_NONE ),
- CFG_FLOAT("absolute_minimum", 0, CFGF_NONE ),
- CFG_BOOL( "absolute_minimum_alert_given", 0, CFGF_NONE ),
- CFG_FLOAT("absolute_minimum_alert", 0, CFGF_NONE ),
- CFG_BOOL( "absolute_minimum_warning_given", 0, CFGF_NONE ),
- CFG_FLOAT("absolute_minimum_warning", 0, CFGF_NONE ),
- CFG_BOOL( "absolute_maximum_warning_given", 0, CFGF_NONE ),
- CFG_FLOAT("absolute_maximum_warning", 0, CFGF_NONE ),
- CFG_BOOL( "absolute_maximum_alert_given", 0, CFGF_NONE ),
- CFG_FLOAT("absolute_maximum_alert", 0, CFGF_NONE ),
- CFG_BOOL( "absolute_maximum_given", 0, CFGF_NONE ),
- CFG_FLOAT("absolute_maximum", 0, CFGF_NONE ),
- CFG_BOOL( "relative_change_normal_given", 0, CFGF_NONE),
- CFG_FLOAT("relative_change_normal", 0, CFGF_NONE),
- CFG_BOOL( "relative_change_warning_given", 0, CFGF_NONE),
- CFG_FLOAT("relative_change_warning", 0, CFGF_NONE),
- CFG_BOOL( "relative_change_alert_given", 0, CFGF_NONE),
- CFG_FLOAT("relative_change_alert", 0, CFGF_NONE),
- CFG_STR("units", NULL, CFGF_NONE ),
CFG_STR("name", NULL, CFGF_NONE ),
- CFG_INT("current_state", 0, CFGF_NONE), /* high_alert, high_warning, normal, low_warning, low_alert */
- CFG_END()
-};
-
-static cfg_opt_t static_collection_group_opts[] = {
- CFG_STR("name", NULL, CFGF_NONE),
- CFG_INT("collection_interval", 60, CFGF_NONE),
+ CFG_FLOAT("value_threshold", -1, CFGF_NONE),
CFG_END()
};
-/* Group with metrics that change... */
static cfg_opt_t collection_group_opts[] = {
CFG_STR("name", NULL, CFGF_NONE),
CFG_SEC("metric", metric_opts, CFGF_MULTI),
- CFG_INT("collection_interval", 60, CFGF_NONE),
- CFG_INT("announce_interval", 3600, CFGF_NONE), /* tmax */
- CFG_INT("lifetime", 0, CFGF_NONE), /* dmax */
+ CFG_BOOL("collect_once", 0, CFGF_NONE),
+ CFG_INT("collect_every", 60, CFGF_NONE),
+ CFG_INT("time_threshold", 3600, CFGF_NONE), /* tmax */
+ CFG_INT("lifetime", 0, CFGF_NONE), /* dmax */
CFG_END()
};
-
static cfg_opt_t gmond_opts[] = {
CFG_SEC("cluster", cluster_opts, CFGF_NONE),
CFG_SEC("behavior", behavior_opts, CFGF_NONE),
CFG_SEC("udp_send_channel", udp_send_channel_opts, CFGF_MULTI),
CFG_SEC("udp_recv_channel", udp_recv_channel_opts, CFGF_MULTI),
CFG_SEC("tcp_accept_channel", tcp_accept_channel_opts, CFGF_MULTI),
- CFG_SEC("static_collection_group", static_collection_group_opts, CFGF_MULTI),
CFG_SEC("collection_group", collection_group_opts, CFGF_MULTI),
CFG_END()
};
View
942 monitor-core/gmond/gmond.c
@@ -41,18 +41,40 @@ int deaf;
int mute;
/* Maximum UDP message size.. TODO: allow tweakability */
int max_udp_message_len = 1472; /* mtu 1500 - 28 bytes for IP/UDP headers */
+
+#if 0
/* The pollset for incoming UDP messages */
apr_pollset_t *udp_recv_pollset = NULL;
/* The access control list for each of the UDP channels */
apr_array_header_t *udp_recv_acl_array = NULL;
+#endif
/* The array for outgoing UDP message channels */
apr_array_header_t *udp_send_array = NULL;
+/* The array for outgoing TCP message channels (later) */
+apr_array_header_t *tcp_send_array = NULL;
+enum Ganglia_channel_types {
+ TCP_ACCEPT_CHANNEL,
+ UDP_RECV_CHANNEL
+};
+typedef enum Ganglia_channel_types Ganglia_channel_types;
+
+struct Ganglia_channel {
+ Ganglia_channel_types type;
+ apr_ipsubnet_t *acl;
+};
+typedef struct Ganglia_channel Ganglia_channel;
+
+/* This pollset holds the tcp_accept and udp_recv channels */
+apr_pollset_t *listen_channels = NULL;
+
+#if 0
/* The pollset for incoming TCP requests */
apr_pollset_t *tcp_accept_pollset = NULL;
/* The access control list for each of the TCP accept channels */
apr_array_header_t *tcp_accept_acl_array = NULL;
+#endif
/* The hash to hold the hosts (key = host IP) */
apr_hash_t *hosts = NULL;
@@ -78,6 +100,7 @@ struct Ganglia_host_data {
};
typedef struct Ganglia_host_data Ganglia_host_data;
+/* This is the structure of the data save to each host->metric hash */
struct Ganglia_metric_data {
/* The ganglia message */
Ganglia_message message;
@@ -92,11 +115,30 @@ apr_hash_t *metric_callbacks = NULL;
/* The "metrics" hash contains values of type "Ganglia_metric_callback" */
/* This is where libmetrics meets gmond */
struct Ganglia_metric_callback {
- char *name; /* metric name */
+ char *name; /* metric name */
+ float value_threshold;/* the value threshold */
+ Ganglia_25metric *info;/* the information about this metric */
g_val_t (*cb)(void); /* callback function */
+ g_val_t now; /* the current value */
+ g_val_t last; /* the last value */
+ Ganglia_message msg; /* the message to send */
};
typedef struct Ganglia_metric_callback Ganglia_metric_callback;
+/* This is the structure of a collection group */
+struct Ganglia_collection_group {
+ apr_time_t next_collect; /* When to collect next */
+ apr_time_t next_send; /* When to send next (tmax) */
+ int once;
+ int collect_every;
+ int time_threshold;
+ apr_array_header_t *metric_array;
+};
+typedef struct Ganglia_collection_group Ganglia_collection_group;
+
+/* This is the array of collection groups that we are processing... */
+apr_array_header_t *collection_groups = NULL;
+
static void
cleanup_configuration_file(void)
{
@@ -108,8 +150,6 @@ process_configuration_file(void)
{
config_file = cfg_init( gmond_opts, CFGF_NOCASE );
- init_validate_funcs(); /* in config.c */
-
switch( cfg_parse( config_file, args_info.conf_arg ) )
{
case CFG_FILE_ERROR:
@@ -227,23 +267,23 @@ process_deaf_mute_mode( void )
}
static void
-setup_udp_recv_pollset( void )
+setup_listen_channels_pollset( void )
{
apr_status_t status;
- /* We will open sockets to listen for messages */
- int i, num_udp_recv_channels = cfg_size( config_file, "udp_recv_channel");
-
- /* Create my UDP recv pollset */
- apr_pollset_create(&udp_recv_pollset, num_udp_recv_channels, global_context, 0);
+ int i;
+ int num_udp_recv_channels = cfg_size( config_file, "udp_recv_channel");
+ int num_tcp_accept_channels = cfg_size( config_file, "tcp_accept_channel");
+ int total_listen_channels = num_udp_recv_channels + num_tcp_accept_channels;
+ Ganglia_channel *channel;
- /* Create my UDP recv access control array */
- udp_recv_acl_array = apr_array_make( global_context, num_udp_recv_channels,
- sizeof(apr_ipsubnet_t *));
+ /* Create my incoming pollset */
+ apr_pollset_create(&listen_channels, total_listen_channels, global_context, 0);
+ /* Process all the udp_recv_channels */
for(i = 0; i< num_udp_recv_channels; i++)
{
cfg_t *udp_recv_channel;
- char *mcast_join, *mcast_if, *bindaddr, *protocol, *allow_ip, *allow_mask;
+ char *mcast_join, *mcast_if, *bindaddr, *allow_ip, *allow_mask;
int port;
apr_socket_t *socket = NULL;
apr_ipsubnet_t *ipsub = NULL;
@@ -255,15 +295,13 @@ setup_udp_recv_pollset( void )
mcast_if = cfg_getstr( udp_recv_channel, "mcast_if" );
port = cfg_getint( udp_recv_channel, "port");
bindaddr = cfg_getstr( udp_recv_channel, "bind");
- protocol = cfg_getstr( udp_recv_channel, "protocol");
allow_ip = cfg_getstr( udp_recv_channel, "allow_ip");
allow_mask = cfg_getstr( udp_recv_channel, "allow_mask");
- debug_msg("udp_recv_channel mcast_join=%s mcast_if=%s port=%d bind=%s protocol=%s\n",
+ debug_msg("udp_recv_channel mcast_join=%s mcast_if=%s port=%d bind=%s\n",
mcast_join? mcast_join:"NULL",
mcast_if? mcast_if:"NULL", port,
- bindaddr? bindaddr: "NULL",
- protocol? protocol:"NULL");
+ bindaddr? bindaddr: "NULL");
/* Create a sub-pool for this channel */
apr_pool_create(&pool, global_context);
@@ -296,29 +334,108 @@ setup_udp_recv_pollset( void )
socket_pollfd.desc_type = APR_POLL_SOCKET;
socket_pollfd.reqevents = APR_POLLIN;
socket_pollfd.desc.s = socket;
- socket_pollfd.client_data = protocol;
+
+ channel = apr_pcalloc( pool, sizeof(Ganglia_channel));
+ if(!channel)
+ {
+ fprintf(stderr,"Unable to malloc memory for channel. Exiting. \n");
+ exit(1);
+ }
+
+ /* Mark this channel as a udp_recv_channel */
+ channel->type = UDP_RECV_CHANNEL;
+
+ /* Save the ACL information */
+ if(allow_ip)
+ {
+ status = apr_ipsubnet_create(&ipsub, allow_ip, allow_mask, pool);
+ if(status != APR_SUCCESS)
+ {
+ fprintf(stderr,"Unable to build ACL for ip=%s mask=%s. Exiting.\n",
+ allow_ip, allow_mask);
+ exit(1);
+ }
+ }
+ channel->acl = ipsub;
+
+ /* Save the pointer to this socket specific data */
+ socket_pollfd.client_data = channel;
/* Add the socket to the pollset */
- status = apr_pollset_add(udp_recv_pollset, &socket_pollfd);
+ status = apr_pollset_add(listen_channels, &socket_pollfd);
if(status != APR_SUCCESS)
{
fprintf(stderr,"Failed to add socket to pollset. Exiting.\n");
exit(1);
}
+ }
+
+ /* Process all the tcp_accept_channels */
+ for(i=0; i< num_tcp_accept_channels; i++)
+ {
+ cfg_t *tcp_accept_channel = cfg_getnsec( config_file, "tcp_accept_channel", i);
+ char *bindaddr, *allow_ip, *allow_mask, *interface;
+ int port;
+ apr_socket_t *socket = NULL;
+ apr_ipsubnet_t *ipsub = NULL;
+ apr_pollfd_t socket_pollfd;
+ apr_pool_t *pool = NULL;
+
+ port = cfg_getint( tcp_accept_channel, "port");
+ bindaddr = cfg_getstr( tcp_accept_channel, "bind");
+ allow_ip = cfg_getstr( tcp_accept_channel, "allow_ip");
+ allow_mask = cfg_getstr( tcp_accept_channel, "allow_mask");
+ interface = cfg_getstr( tcp_accept_channel, "interface");
+
+ debug_msg("tcp_accept_channel bind=%s port=%d\n",
+ bindaddr? bindaddr: "NULL", port);
+
+ /* Create a subpool context */
+ apr_pool_create(&pool, global_context);
+
+ /* Create the socket for the channel */
+ socket = create_tcp_server(pool, port, bindaddr, interface);
+ if(!socket)
+ {
+ fprintf(stderr,"Unable to create tcp_accept_channel. Exiting.\n");
+ exit(1);
+ }
+
+ /* Build the socket poll file descriptor structure */
+ socket_pollfd.desc_type = APR_POLL_SOCKET;
+ socket_pollfd.reqevents = APR_POLLIN;
+ socket_pollfd.desc.s = socket;
+
+ channel = apr_pcalloc( pool, sizeof(Ganglia_channel));
+ if(!channel)
+ {
+ fprintf(stderr,"Unable to malloc data for channel. Exiting.\n");
+ exit(1);
+ }
+
+ channel->type = TCP_ACCEPT_CHANNEL;
/* Save the ACL information */
if(allow_ip)
{
- status = apr_ipsubnet_create(&ipsub, allow_ip, allow_mask, global_context);
+ status = apr_ipsubnet_create(&ipsub, allow_ip, allow_mask, pool);
if(status != APR_SUCCESS)
{
fprintf(stderr,"Unable to build ACL for ip=%s mask=%s. Exiting.\n",
allow_ip, allow_mask);
exit(1);
}
}
- /* ipsub of NULL means no acl in effect */
- *(apr_ipsubnet_t **)apr_array_push(udp_recv_acl_array) = ipsub;
+ channel->acl = ipsub;
+ socket_pollfd.client_data = channel;
+
+ /* Add the socket to the pollset */
+ status = apr_pollset_add(listen_channels, &socket_pollfd);
+ if(status != APR_SUCCESS)
+ {
+ fprintf(stderr,"Failed to add socket to pollset. Exiting.\n");
+ exit(1);
+ }
}
}
@@ -466,114 +583,70 @@ Ganglia_message_save( Ganglia_host_data *host, Ganglia_message *message )
}
static void
-poll_udp_recv_channels(apr_interval_time_t timeout)
+process_udp_recv_channel(const apr_pollfd_t *desc)
{
apr_status_t status;
- const apr_pollfd_t *descs = NULL;
- apr_int32_t num = 0;
-
- /* Poll for data with given timeout */
- status = apr_pollset_poll(udp_recv_pollset, timeout, &num, &descs);
+ apr_socket_t *socket;
+ apr_sockaddr_t *remotesa = NULL;
+ char remoteip[256];
+ char buf[max_udp_message_len];
+ apr_size_t len = max_udp_message_len;
+ Ganglia_channel *channel;
+ XDR x;
+ Ganglia_message msg;
+ Ganglia_host_data *hostdata = NULL;
+
+ socket = desc->desc.s;
+ /* We could also use the apr_socket_data_get/set() functions
+ * to have per socket user data .. see APR docs */
+ channel = desc->client_data;
+
+ apr_socket_addr_get(&remotesa, APR_REMOTE, socket);
+
+ /* Grab the data */
+ status = apr_socket_recvfrom(remotesa, socket, 0, buf, &len);
if(status != APR_SUCCESS)
- return;
-
- if(num>0)
{
- int i;
-
- /* We have data to read */
- for(i=0; i< num; i++)
- {
- apr_socket_t *socket;
- apr_sockaddr_t *remotesa = NULL;
- char *protocol, remoteip[256];
- apr_ipsubnet_t *ipsub;
- char buf[max_udp_message_len];
- apr_size_t len = max_udp_message_len;
-
- socket = descs[i].desc.s;
- /* We could also use the apr_socket_data_get/set() functions
- * to have per socket user data .. see APR docs */
- protocol = descs[i].client_data;
-
- apr_socket_addr_get(&remotesa, APR_REMOTE, socket);
-
- /* Grab the data */
- status = apr_socket_recvfrom(remotesa, socket, 0, buf, &len);
- if(status != APR_SUCCESS)
- {
- continue;
- }
+ return;
+ }
- /* This function is in ./lib/apr_net.c and not APR. The
- * APR counterpart is apr_sockaddr_ip_get() but we don't
- * want to malloc memory evertime we call this */
- apr_sockaddr_ip_buffer_get(remoteip, 256, remotesa);
+ /* This function is in ./lib/apr_net.c and not APR. The
+ * APR counterpart is apr_sockaddr_ip_get() but we don't
+ * want to malloc memory evertime we call this */
+ apr_sockaddr_ip_buffer_get(remoteip, 256, remotesa);
- /* Check the ACL (we can make this better later) */
- ipsub = ((apr_ipsubnet_t **)(udp_recv_acl_array->elts))[i];
- if(ipsub)
- {
- if(!apr_ipsubnet_test( ipsub, remotesa))
- {
- debug_msg("Ignoring data from %s\n", remoteip);
- continue; /* to the next channel that needs read */
- }
- }
+ /* Check the ACL (we can make this better later) */
+ if(channel->acl)
+ {
+ if(!apr_ipsubnet_test( channel->acl, remotesa))
+ {
+ debug_msg("Ignoring data from %s\n", remoteip);
+ return;
+ }
+ }
- if(!strcasecmp(protocol, "xdr"))
- {
- XDR x;
- Ganglia_message msg;
- Ganglia_host_data *hostdata = NULL;
-
- /* Create the XDR receive stream */
- xdrmem_create(&x, buf, max_udp_message_len, XDR_DECODE);
-
- /* Flush the data... */
- memset( &msg, 0, sizeof(Ganglia_message));
-
- /* Read the gangliaMessage from the stream */
- if(!xdr_Ganglia_message(&x, &msg))
- {
- continue;
- }
-
- /* Process the host information and get the Ganglia_host_data.
- * We call this _after_ we process the content of the message
- * because the newer message format allows for proxy information
- * to be sent. NOTE: The ACL test above looks at the IP header
- * and not the proxy information provided. */
- hostdata = Ganglia_host_data_get( remoteip, remotesa, &msg);
- if(!hostdata)
- {
- /* Processing of this message is finished ... */
- xdr_free((xdrproc_t)xdr_Ganglia_message, (char *)&msg);
- continue;
- }
+ /* Create the XDR receive stream */
+ xdrmem_create(&x, buf, max_udp_message_len, XDR_DECODE);
- /* Save the message from this particular host */
- Ganglia_message_save( hostdata, &msg );
+ /* Flush the data... */
+ memset( &msg, 0, sizeof(Ganglia_message));
-#if 0
- /* Save the message to the hostdata metric hash */
- old_metric = Ganglia_old_metric_get( msg.id );
- if(old_metric)
- {
- /* Move this data into a newer format (later) */
- debug_msg("%s\t(%s)\t=>\t%s", hostdata->ip, hostdata->hostname, old_metric->name);
- }
-#endif
+ /* Read the gangliaMessage from the stream */
+ if(!xdr_Ganglia_message(&x, &msg))
+ {
+ return;
+ }
- /*
- xdr_free((xdrproc_t)xdr_Ganglia_message, (char *)&msg);
- */
-
- /* If I want to find out how much data I decoded
- decoded = xdr_getpos(&x); */
- }
- }
+ hostdata = Ganglia_host_data_get( remoteip, remotesa, &msg);
+ if(!hostdata)
+ {
+ /* Processing of this message is finished ... */
+ xdr_free((xdrproc_t)xdr_Ganglia_message, (char *)&msg);
+ return;
}
+
+ /* Save the message from this particular host */
+ Ganglia_message_save( hostdata, &msg );
}
static void
@@ -591,7 +664,7 @@ setup_udp_send_array( void )
for(i = 0; i< num_udp_send_channels; i++)
{
cfg_t *udp_send_channel;
- char *mcast_join, *mcast_if, *protocol, *ip;
+ char *mcast_join, *mcast_if, *ip;
int port;
apr_socket_t *socket = NULL;
apr_pool_t *pool = NULL;
@@ -601,14 +674,12 @@ setup_udp_send_array( void )
mcast_join = cfg_getstr( udp_send_channel, "mcast_join" );
mcast_if = cfg_getstr( udp_send_channel, "mcast_if" );
port = cfg_getint( udp_send_channel, "port");
- protocol = cfg_getstr( udp_send_channel, "protocol");
- debug_msg("udp_send_channel mcast_join=%s mcast_if=%s ip=%s port=%d protocol=%s\n",
+ debug_msg("udp_send_channel mcast_join=%s mcast_if=%s ip=%s port=%d\n",
mcast_join? mcast_join:"NULL",
mcast_if? mcast_if:"NULL",
ip,
- port,
- protocol? protocol:"NULL");
+ port);
/* Create a subpool */
apr_pool_create(&pool, global_context);
@@ -642,82 +713,6 @@ setup_udp_send_array( void )
}
}
-static void
-setup_tcp_accept_pollset( void )
-{
- apr_status_t status;
- int i, num_tcp_accept_channels = cfg_size( config_file, "tcp_accept_channel");
-
- /* Create my TCP accept pollset */
- apr_pollset_create(&tcp_accept_pollset, num_tcp_accept_channels, global_context, 0);
-
- /* Create my TCP accept ACL array */
- tcp_accept_acl_array = apr_array_make( global_context, num_tcp_accept_channels,
- sizeof(apr_ipsubnet_t *));
-
- for(i=0; i< num_tcp_accept_channels; i++)
- {
- cfg_t *tcp_accept_channel = cfg_getnsec( config_file, "tcp_accept_channel", i);
- char *bindaddr, *protocol, *allow_ip, *allow_mask, *interface;
- int port;
- apr_socket_t *socket = NULL;
- apr_ipsubnet_t *ipsub = NULL;
- apr_pollfd_t socket_pollfd;
- apr_pool_t *pool = NULL;
-
- port = cfg_getint( tcp_accept_channel, "port");
- bindaddr = cfg_getstr( tcp_accept_channel, "bind");
- protocol = cfg_getstr( tcp_accept_channel, "protocol");
- allow_ip = cfg_getstr( tcp_accept_channel, "allow_ip");
- allow_mask = cfg_getstr( tcp_accept_channel, "allow_mask");
- interface = cfg_getstr( tcp_accept_channel, "interface");
-
- debug_msg("tcp_accept_channel bind=%s port=%d protocol=%s\n",
- bindaddr? bindaddr: "NULL", port,
- protocol? protocol:"NULL");
-
- /* Create a subpool context */
- apr_pool_create(&pool, global_context);
-
- /* Create the socket for the channel */
- socket = create_tcp_server(pool, port, bindaddr, interface);
- if(!socket)
- {
- fprintf(stderr,"Unable to create tcp_accept_channel. Exiting.\n");
- exit(1);
- }
-
- /* Build the socket poll file descriptor structure */
- socket_pollfd.desc_type = APR_POLL_SOCKET;
- socket_pollfd.reqevents = APR_POLLIN;
- socket_pollfd.desc.s = socket;
- socket_pollfd.client_data = protocol;
-
- /* Add the socket to the pollset */
- status = apr_pollset_add(tcp_accept_pollset, &socket_pollfd);
- if(status != APR_SUCCESS)
- {
- fprintf(stderr,"Failed to add socket to pollset. Exiting.\n");
- exit(1);
- }
-
- /* Save the ACL information */
- if(allow_ip)
- {
- status = apr_ipsubnet_create(&ipsub, allow_ip, allow_mask, pool);
- if(status != APR_SUCCESS)
- {
- fprintf(stderr,"Unable to build ACL for ip=%s mask=%s. Exiting.\n",
- allow_ip, allow_mask);
- exit(1);
- }
- }
-
- /* ipsub of NULL means no acl in effect */
- *(apr_ipsubnet_t **)apr_array_push(tcp_accept_acl_array) = ipsub;
- }
-}
-
static apr_status_t
print_xml_header( apr_socket_t *client )
{
@@ -785,9 +780,9 @@ print_host_start( apr_socket_t *client, Ganglia_host_data *hostinfo)
(int)(hostinfo->last_heard_from / APR_USEC_PER_SEC),
tn,
20, /*tmax for now is always 20 */
- 0 /*dmax*/,
- "unspecified", /*location*/
- 0 /*gmond_started*/);
+ 0 /* TODO: (config option) dmax*/,
+ "unspecified", /* TODO: (location) location*/
+ 0 /*TODO: (heartbeat) gmond_started*/);
return apr_send(client, hostxml, &len);
}
@@ -838,12 +833,14 @@ host_metric_value( Ganglia_25metric *metric, Ganglia_message *message )
apr_snprintf(value, 1024, metric->fmt, message->Ganglia_message_u.u_short);
return value;
case GANGLIA_VALUE_SHORT:
+ /* For right now.. there are no metrics which are signed shorts... use u_short */
apr_snprintf(value, 1024, metric->fmt, message->Ganglia_message_u.u_short);
return value;
case GANGLIA_VALUE_UNSIGNED_INT:
apr_snprintf(value, 1024, metric->fmt, message->Ganglia_message_u.u_int);
return value;
case GANGLIA_VALUE_INT:
+ /* For right now.. there are no metric which are signed ints... use u_int */
apr_snprintf(value, 1024, metric->fmt, message->Ganglia_message_u.u_int);
return value;
case GANGLIA_VALUE_FLOAT:
@@ -865,7 +862,7 @@ print_host_metric( apr_socket_t *client, Ganglia_metric_data *data )
apr_size_t len;
apr_time_t now;
- metric = Ganglia_25metric_bykey( data->message.id );
+ metric = Ganglia_25metric_bykey( data? data->message.id: -1 );
if(!metric)
return APR_SUCCESS;
@@ -893,122 +890,130 @@ print_host_end( apr_socket_t *client)
}
static void
-poll_tcp_accept_channels(apr_interval_time_t timeout)
+process_tcp_accept_channel(const apr_pollfd_t *desc)
{
apr_status_t status;
- const apr_pollfd_t *descs = NULL;
- apr_int32_t num = 0;
+ apr_hash_index_t *hi, *metric_hi;
+ void *val;
+ apr_socket_t *client, *server;
+ apr_sockaddr_t *remotesa = NULL;
+ char remoteip[256];
+ apr_pool_t *client_context = NULL;
+ Ganglia_channel *channel;
+
+ server = desc->desc.s;
+ /* We could also use the apr_socket_data_get/set() functions
+ * to have per socket user data .. see APR docs */
+ channel = desc->client_data;
+
+ /* Create a context for the client connection */
+ apr_pool_create(&client_context, global_context);
+
+ /* Accept the connection */
+ status = apr_accept(&client, server, client_context);
+ if(status != APR_SUCCESS)
+ {
+ goto close_accept_socket;
+ }
+
+ apr_socket_addr_get(&remotesa, APR_REMOTE, client);
+ /* This function is in ./lib/apr_net.c and not APR. The
+ * APR counterpart is apr_sockaddr_ip_get() but we don't
+ * want to malloc memory evertime we call this */
+ apr_sockaddr_ip_buffer_get(remoteip, 256, remotesa);
- /* Poll for data with given timeout */
- status = apr_pollset_poll(tcp_accept_pollset, timeout, &num, &descs);
+ /* Check the ACL (we can make this better later) */
+ if(channel->acl)
+ {
+ if(!apr_ipsubnet_test( channel->acl, remotesa))
+ {
+ debug_msg("Ignoring connection from %s\n", remoteip);
+ goto close_accept_socket;
+ }
+ }
+
+ /* Print the DTD, GANGLIA_XML and CLUSTER tags */
+ status = print_xml_header(client);
if(status != APR_SUCCESS)
- return;
+ goto close_accept_socket;
- if(num>0)
+ /* Walk the host hash */
+ for(hi = apr_hash_first(client_context, hosts);
+ hi;
+ hi = apr_hash_next(hi))
{
- int i;
+ apr_hash_this(hi, NULL, NULL, &val);
+ status = print_host_start(client, (Ganglia_host_data *)val);
+ if(status != APR_SUCCESS)
+ {
+ goto close_accept_socket;
+ }
- /* We have data to read */
- for(i=0; i< num; i++)
+ /* Send the metric info for this particular host */
+ for(metric_hi = apr_hash_first(client_context, ((Ganglia_host_data *)val)->metrics);
+ metric_hi;
+ metric_hi = apr_hash_next(metric_hi))
{
- apr_socket_t *client, *server;
- apr_sockaddr_t *remotesa = NULL;
- char *protocol, remoteip[256];
- apr_ipsubnet_t *ipsub;
- apr_pool_t *client_context = NULL;
-
- server = descs[i].desc.s;
- /* We could also use the apr_socket_data_get/set() functions
- * to have per socket user data .. see APR docs */
- protocol = descs[i].client_data;
-
- /* Create a context for the client connection */
- apr_pool_create(&client_context, global_context);
-
- /* Accept the connection */
- status = apr_accept(&client, server, client_context);
- if(status != APR_SUCCESS)
+ void *metric;
+ apr_hash_this(metric_hi, NULL, NULL, &metric);
+
+ /* Print each of the metrics for a host ... */
+ if(print_host_metric(client, metric) != APR_SUCCESS)
{
goto close_accept_socket;
}
+ }
- apr_socket_addr_get(&remotesa, APR_REMOTE, client);
- /* This function is in ./lib/apr_net.c and not APR. The
- * APR counterpart is apr_sockaddr_ip_get() but we don't
- * want to malloc memory evertime we call this */
- apr_sockaddr_ip_buffer_get(remoteip, 256, remotesa);
+ /* Close the host tag */
+ status = print_host_end(client);
+ if(status != APR_SUCCESS)
+ {
+ goto close_accept_socket;
+ }
+ }
- /* Check the ACL (we can make this better later) */
- ipsub = ((apr_ipsubnet_t **)(tcp_accept_acl_array->elts))[i];
- if(ipsub)
- {
- if(!apr_ipsubnet_test( ipsub, remotesa))
- {
- debug_msg("Ignoring connection from %s\n", remoteip);
- goto close_accept_socket;
- }
- }
+ /* Close the CLUSTER and GANGLIA_XML tags */
+ print_xml_footer(client);
- /* At this point send data over the socket */
- if(!strcasecmp(protocol, "xml"))
- {
- apr_status_t status;
- apr_hash_index_t *hi, *metric_hi;
- void *val;
-
- /* Print the DTD, GANGLIA_XML and CLUSTER tags */
- status = print_xml_header(client);
- if(status != APR_SUCCESS)
- goto close_accept_socket;
-
- /* Walk the host hash */
- for(hi = apr_hash_first(client_context, hosts);
- hi;
- hi = apr_hash_next(hi))
- {
- apr_hash_this(hi, NULL, NULL, &val);
- status = print_host_start(client, (Ganglia_host_data *)val);
- if(status != APR_SUCCESS)
- {
- goto close_accept_socket;
- }
-
- /* Send the metric info for this particular host */
- for(metric_hi = apr_hash_first(client_context, ((Ganglia_host_data *)val)->metrics);
- metric_hi;
- metric_hi = apr_hash_next(metric_hi))
- {
- void *metric;
- apr_hash_this(metric_hi, NULL, NULL, &metric);
-
- /* Print each of the metrics for a host ... */
- if(print_host_metric(client, metric) != APR_SUCCESS)
- {
- goto close_accept_socket;
- }
- }
+ /* Close down the accepted socket */
+close_accept_socket:
+ apr_shutdown(client, APR_SHUTDOWN_READ);
+ apr_socket_close(client);
+ apr_pool_destroy(client_context);
+}
- /* Close the host tag */
- status = print_host_end(client);
- if(status != APR_SUCCESS)
- {
- goto close_accept_socket;
- }
- }
- /* Close the CLUSTER and GANGLIA_XML tags */
- print_xml_footer(client);
- }
+static void
+poll_listen_channels( apr_interval_time_t timeout )
+{
+ apr_status_t status;
+ const apr_pollfd_t *descs = NULL;
+ apr_int32_t num = 0;
+ apr_int32_t i;
- /* Close down the accepted socket */
- close_accept_socket:
- apr_shutdown(client, APR_SHUTDOWN_READ);
- apr_socket_close(client);
- apr_pool_destroy(client_context);
- }
+ /* Poll for incoming data */
+ status = apr_pollset_poll(listen_channels, timeout, &num, &descs);
+ if(status != APR_SUCCESS)
+ return;
+
+ for(i = 0; i< num ; i++)
+ {
+ Ganglia_channel *channel = descs[i].client_data;
+ switch( channel->type )
+ {
+ case UDP_RECV_CHANNEL:
+ process_udp_recv_channel(descs+i);
+ break;
+ case TCP_ACCEPT_CHANNEL:
+ process_tcp_accept_channel(descs+i);
+ break;
+ default:
+ continue;
+ }
}
}
+
/* This function will send a datagram to every udp_send_channel specified */
static int
udp_send_message( char *buf, int len )
@@ -1042,6 +1047,12 @@ tcp_send_message( char *buf, int len )
return 0;
}
+static int
+send_message( char *buf, int len )
+{
+ return udp_send_message( buf, len ) + tcp_send_message( buf, len );
+}
+
static Ganglia_metric_callback *
Ganglia_metric_cb_define( char *name, g_val_t (*cb)(void))
{
@@ -1054,10 +1065,48 @@ Ganglia_metric_cb_define( char *name, g_val_t (*cb)(void))
return NULL;
metric->cb = cb;
+
apr_hash_set( metric_callbacks, metric->name, APR_HASH_KEY_STRING, metric);
return metric;
}
+#if 0
+g_val_t
+gexec_func ( void )
+{
+ g_val_t val;
+
+ if( gmond_config.no_gexec || ( SUPPORT_GEXEC == 0 ) )
+ snprintf(val.str, MAX_G_STRING_SIZE, "%s", "OFF");
+ else
+ snprintf(val.str, MAX_G_STRING_SIZE, "%s", "ON");
+
+ return val;
+}
+#endif
+
+g_val_t
+heartbeat_func( void )
+{
+ g_val_t val;
+
+ val.uint32 = started / APR_USEC_PER_SEC;
+ debug_msg("my start_time is %d\n", val.uint32);
+ return val;
+}
+
+#if 0
+g_val_t
+location_func(void)
+{
+ g_val_t val;
+
+ strncpy(val.str, gmond_config.location, MAX_G_STRING_SIZE);
+ debug_msg("my location is %s", val.str);
+ return val;
+}
+#endif
+
/* This function imports the metrics from libmetrics right now but in the future
* we could easily do this via DSO. */
static void
@@ -1102,39 +1151,276 @@ setup_metric_callbacks( void )
Ganglia_metric_cb_define("mem_buffers", mem_buffers_func);
Ganglia_metric_cb_define("mem_cached", mem_cached_func);
Ganglia_metric_cb_define("swap_free", swap_free_func);
+
+ Ganglia_metric_cb_define("heartbeat", heartbeat_func);
+
+ /* Add platform specific metrics here... */
}
-
-int
-process_collection_groups( void )
+
+void
+setup_collection_groups( void )
{
int i, num_collection_groups = cfg_size( config_file, "collection_group" );
+
+ /* Create the collection group array */
+ collection_groups = apr_array_make( global_context, num_collection_groups,
+ sizeof(Ganglia_collection_group *));
- for(i=0; i< num_collection_groups; i++)
+ for(i = 0; i < num_collection_groups; i++)
{
int j, num_metrics;
+ cfg_t *group_conf;
+ Ganglia_collection_group *group = apr_pcalloc( global_context,
+ sizeof(Ganglia_collection_group));
+ if(!group)
+ {
+ fprintf(stderr,"Unable to malloc memory for collection group. Exiting.\n");
+ exit(1);
+ }
- cfg_t *group = cfg_getnsec( config_file, "collection_group", i);
- char *name = cfg_getstr( group, "name");
- num_metrics = cfg_size( group, "metric" );
+ group_conf = cfg_getnsec( config_file, "collection_group", i);
+ group->once = cfg_getbool( group_conf, "collect_once");
+ group->collect_every = cfg_getint( group_conf, "collect_every");
+ group->time_threshold = cfg_getint( group_conf, "time_threshold");
+ /* Set to collect and send immediately */
+ group->next_collect = 0;
+ group->next_send = 0;
+
+ num_metrics = cfg_size( group_conf, "metric" );
+ group->metric_array = apr_array_make(global_context, num_metrics,
+ sizeof(Ganglia_metric_callback *));
for(j=0; j< num_metrics; j++)
{
- cfg_t *metric = cfg_getnsec( group, "metric", j );
+ cfg_t *metric = cfg_getnsec( group_conf, "metric", j );
+ char *name = cfg_getstr ( metric, "name");
+ float value_threshold = cfg_getfloat( metric, "value_threshold");
+
+ Ganglia_metric_callback *metric_cb = (Ganglia_metric_callback *)
+ apr_hash_get( metric_callbacks, name, APR_HASH_KEY_STRING );
+ Ganglia_25metric *metric_info = Ganglia_25metric_byname(name);
+
+ if(!metric_cb)
+ {
+ fprintf(stderr,"Unable to collect metric '%s' on this platform. Exiting.\n", name);
+ exit(1);
+ }
+
+ if(!metric_info)
+ {
+ fprintf(stderr,"Unable to send metric '%s' (not in protocol.x). Exiting.\n", name);
+ exit(1);
+ }
+
+ /* This sets the key for this particular metric.
+ * The value is set by the callback function later */
+ metric_cb->msg.id = metric_info->key;
+
+ /* Save the location of information about this particular metric */
+ metric_cb->info = metric_info;
+
+ /* Set the value threshold for this particular metric */
+ metric_cb->value_threshold = value_threshold;
+
+ if(group->once)
+ {
+ /* If this metric will only be collected once, run it now at setup... */
+ metric_cb->now = metric_cb->cb();
+ memset( &(metric_cb->last), 0, sizeof(g_val_t));
+ }
+ else
+ {
+ memset( &(metric_cb->now), 0, sizeof(g_val_t));
+ memset( &(metric_cb->last), 0, sizeof(g_val_t));
+ }
+
+ *(Ganglia_metric_callback **)apr_array_push(group->metric_array) = metric_cb;
+ }
+
+ /* Save the collection group the collection group array */
+ *(Ganglia_collection_group **)apr_array_push(collection_groups) = group;
+ }
+}
+
+/* TODO: It might be necessary in the future to use a heap for the collection groups.
+ * Running through an array should suffice for now */
+apr_time_t
+process_collection_groups( apr_time_t now )
+{
+ int i,j;
+ apr_time_t next = 0;
+
+ /* Run through each collection group and collect any data that needs collecting... */
+ for(i=0; i< collection_groups->nelts; i++)
+ {
+ Ganglia_collection_group *group = ((Ganglia_collection_group **)(collection_groups->elts))[i];
+
+ debug_msg("process_collection_group #%d", i);
+
+ if(group->once)
+ {
+ /* This group is only collected once at setup time */
+ debug_msg("\tgroup #%d is only collected once. skipping.", i);
+ continue;
+ }
+
+ if( group->next_collect <= now )
+ {
+ debug_msg("\tgroup #%d needs to be collected now", i);
+ /* This group needs to be collected now */
+ for(j=0; j< group->metric_array->nelts; j++)
+ {
+ Ganglia_metric_callback *cb = ((Ganglia_metric_callback **)(group->metric_array->elts))[j];
+
+ debug_msg("\tgroup #%d metric '%s' being collected now", i, cb->name);
+ cb->last = cb->now;
+ cb->now = cb->cb();
+
+ /* Check the value threshold. If passed.. set this group to send immediately. */
+ if( cb->value_threshold >= 0.0 )
+ {
+ debug_msg("\tmetric '%s' has value_threshold %f", cb->name, cb->value_threshold);
+ switch(cb->info->type)
+ {
+ case GANGLIA_VALUE_UNKNOWN:
+ case GANGLIA_VALUE_STRING:
+ /* do nothing for non-numeric data */
+ break;
+ case GANGLIA_VALUE_UNSIGNED_SHORT:
+ if( abs( cb->last.uint16 - cb->now.uint16 ) >= cb->value_threshold )
+ group->next_send = 0; /* send immediately */
+ break;
+ case GANGLIA_VALUE_SHORT:
+ if( abs( cb->last.int16 - cb->now.int16 ) >= cb->value_threshold )
+ group->next_send = 0; /* send immediately */
+ break;
+ case GANGLIA_VALUE_UNSIGNED_INT:
+ if( abs( cb->last.uint32 - cb->now.uint32 ) >= cb->value_threshold )
+ group->next_send = 0; /* send immediately */
+ break;
+ case GANGLIA_VALUE_INT:
+ if( abs( cb->last.int32 - cb->now.int32 ) >= cb->value_threshold )
+ group->next_send = 0; /* send immediately */
+ break;
+ case GANGLIA_VALUE_FLOAT:
+ if( abs( cb->last.f - cb->now.f ) >= cb->value_threshold )
+ group->next_send = 0; /* send immediately */
+ break;
+ case GANGLIA_VALUE_DOUBLE:
+ if( abs( cb->last.d - cb->now.d ) >= cb->value_threshold )
+ group->next_send = 0; /* send immediately */
+ break;
+ default:
+ break;
+ }
+
+ }
+
+ }
+ /* Set the next time this group should be collected */
+ group->next_collect = now + (group->collect_every * APR_USEC_PER_SEC);
+ if(debug_level)
+ {
+ char timestr[APR_CTIME_LEN];
+ apr_ctime(timestr, group->next_collect);
+ debug_msg("\tcollection_group #%d next collection at %s", i, timestr);
+ }
+ }
+ else
+ {
+ debug_msg("\tcollection_group #%d does not need to be collected at this time.",i);
+ }
+ }
+
+
+ /* TODO: this would be done better with a heap...
+ * Send any groups that need to be sent and
+ * Find out exactly when we need to run process_collection_groups again */
+ for(i=0; i< collection_groups->nelts; i++)
+ {
+ Ganglia_collection_group *group = ((Ganglia_collection_group **)(collection_groups->elts))[i];
+
+ /* Send any groups that need to be sent now */
+ if( group->next_send <= now )
+ {
+ debug_msg("\tcollection_group #%d will send data", i);
+ /* This group needs to be sent */
+ for(j=0; j< group->metric_array->nelts; j++)
+ {
+ XDR x;
+ int len, errors;
+ char metricmsg[max_udp_message_len];
+ Ganglia_metric_callback *cb = ((Ganglia_metric_callback **)(group->metric_array->elts))[j];
+
+ /* Build the message */
+ switch(cb->info->type)
+ {
+ case GANGLIA_VALUE_UNKNOWN:
+ /* The 2.5.x protocol doesn't allow for unknown values. :( Do nothing. */
+ continue;
+ case GANGLIA_VALUE_STRING:
+ cb->msg.Ganglia_message_u.str = cb->now.str;
+ break;
+ case GANGLIA_VALUE_UNSIGNED_SHORT:
+ cb->msg.Ganglia_message_u.u_short = cb->now.uint16;
+ break;
+ case GANGLIA_VALUE_SHORT:
+ /* TODO: currently there are no signed short values in protocol.x
+ * As soon as we add one, we need to implement it here... */
+ break;
+ case GANGLIA_VALUE_UNSIGNED_INT:
+ cb->msg.Ganglia_message_u.u_int = cb->now.uint32;
+ break;
+ case GANGLIA_VALUE_INT:
+ /* TODO: currently there are no signed int value in protocol.x
+ * As soon as we add one, we need to implement it here... */
+ break;
+ case GANGLIA_VALUE_FLOAT:
+ cb->msg.Ganglia_message_u.f = cb->now.f;
+ break;
+ case GANGLIA_VALUE_DOUBLE:
+ cb->msg.Ganglia_message_u.d = cb->now.d;
+ break;
+ default:
+ continue;
+ }
- /* Process the data for this metric */
-
+ /* Send the message */
+ xdrmem_create(&x, metricmsg, max_udp_message_len, XDR_ENCODE);
+ xdr_Ganglia_message(&x, &(cb->msg));
+ len = xdr_getpos(&x);
+ errors = send_message( metricmsg, len );
+ debug_msg("\tsent message of length %d with %d errors", len, errors);
+ if(!errors)
+ {
+ /* If the message send ok. Schedule the next time threshold. */
+ group->next_send = now + group->time_threshold * APR_USEC_PER_SEC;
+ }
+ }
+ }
+ /* Find the next time we need to run process_collection_group() */
+ if(!next)
+ {
+ next = group->next_collect;
+ }
+ else
+ {
+ if(group->next_collect < next )
+ {
+ next = group->next_collect;
+ }
}
}
- return 2;
+ /* If next is 0... drop back in here in 60 seconds (no loops) */
+ return next? next: apr_time_now() + 60 * APR_USEC_PER_SEC;
}
int
main ( int argc, char *argv[] )
{
- apr_interval_time_t now, stop;
- int next_collection;
+ apr_time_t now, next_collection;
/* Mark the time this gmond started */
started = apr_time_now();
@@ -1167,43 +1453,37 @@ main ( int argc, char *argv[] )
if(!deaf)
{
- setup_udp_recv_pollset();
- setup_tcp_accept_pollset();
+ setup_listen_channels_pollset();
}
if(!mute)
{
setup_metric_callbacks();
+ setup_collection_groups();
setup_udp_send_array();
}
/* Create the host hash table */
hosts = apr_hash_make( global_context );
- next_collection = 0;
- for(;;)
+ for(next_collection = 0;;)
{
- now = apr_time_now();
- stop = now + (next_collection* APR_USEC_PER_SEC);
+ now = apr_time_now();
+
/* Read data until we need to collect/write data */
- for(; now < stop ;)
+ if(!deaf)
{
- if(!deaf)
+ for(; mute || now < next_collection;)
{
- poll_tcp_accept_channels(0);
- poll_udp_recv_channels(stop - now);
- }
- now = apr_time_now();
+ /* TODO: merge all receive channels into one poll */
+ poll_listen_channels(next_collection - now);
+ now = apr_time_now();
+ }
}
if(!mute)
{
- next_collection = process_collection_groups();
- }
- else
- {
- next_collection = 3600; /* if we're mute.
- set the default timeout large...*/
+ next_collection = process_collection_groups( now );
}
}
View
34 monitor-core/gmond/gmond.conf
@@ -3,32 +3,44 @@ behavior {
user = nobody
}
udp_send_channel {
- ip = 239.2.11.71
+ ip = 127.0.0.1
port = 8649
}
udp_recv_channel {
port = 8649
}
+tcp_accept_channel {
+ port = 8649
+}
+collection_group {
+ collect_once = true
+ time_threshold = 20
+ metric {
+ name = "heartbeat"
+ }
+}
collection_group {
- name = "cpu_stat"
+ collect_every = 2
+ time_threshold = 60
metric {
name = "cpu_user"
- absolute_minimum = 0
- absolute_maximum = 100
}
metric {
- name = "cpu_sys"
- absolute_minimum = 0
- absolute_maximum = 100
+ name = "cpu_system"
}
metric {
name = "cpu_idle"
- absolute_minimum = 0
- absolute_maximum = 100
}
metric {
name = "cpu_nice"
- absolute_minimum = 0
- absolute_maximum = 100
}
}
+collection_group {
+ collect_every = 5
+ metric {
+ name = "mem_free"
+ }
+ metric {
+ name = "mem_total"
+ }
+}
View
8 monitor-core/lib/apr_net.c
@@ -51,14 +51,14 @@ APR_DECLARE(apr_status_t) apr_sockaddr_ip_buffer_get(char *addr, int len,
}
static apr_socket_t *
-create_net_client(apr_pool_t *context, int type, char *ipaddr, apr_port_t port)
+create_net_client(apr_pool_t *context, int type, char *host, apr_port_t port)
{
apr_sockaddr_t *remotesa = NULL;
apr_socket_t *sock = NULL;
apr_status_t status;
int family = APR_UNSPEC;
- status = apr_sockaddr_info_get(&remotesa, ipaddr, APR_UNSPEC, port, 0, context);
+ status = apr_sockaddr_info_get(&remotesa, host, APR_UNSPEC, port, 0, context);
if(status!= APR_SUCCESS)
{
return NULL;
@@ -84,9 +84,9 @@ create_net_client(apr_pool_t *context, int type, char *ipaddr, apr_port_t port)
}
apr_socket_t *
-create_udp_client(apr_pool_t *context, char *ipaddr, apr_port_t port)
+create_udp_client(apr_pool_t *context, char *host, apr_port_t port)
{
- return create_net_client(context, SOCK_DGRAM, ipaddr, port);
+ return create_net_client(context, SOCK_DGRAM, host, port);
}
static apr_socket_t *

0 comments on commit 9069c9c

Please sign in to comment.
Something went wrong with that request. Please try again.