--- projects/cms/source/ihost/ihost.c 2002/05/13 11:01:27 1.8 +++ projects/cms/source/ihost/ihost.c 2002/05/19 14:58:06 1.14 @@ -1,14 +1,36 @@ +/* + * i-scream central monitoring system + * Copyright (C) 2000-2002 i-scream + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + #include -#include #include #include #include #include -#include +#include "ukcprog.h" #include -#include +#include +#include "statgrab.h" +#include +#include #define RECONFIGURE_RETURN_CODE 2 +#define UDP_MAX_PACKET_SIZE 8192 typedef struct{ int fm_port; @@ -59,9 +81,9 @@ int ihost_configure(ihost_state_t *ihost_state){ return -1; } - memset((char *)&addr, 0, sizeof addr); + memset(&addr, 0, sizeof addr); addr.sin_family = AF_INET; - memcpy((char *)&addr.sin_addr, &haddr, sizeof haddr); + memcpy(&addr.sin_addr, &haddr, sizeof haddr); addr.sin_port = htons(ihost_state->fm_port); if (connect(sd, (struct sockaddr *)&addr, sizeof addr) != 0) { @@ -142,7 +164,7 @@ int ihost_configure(ihost_state_t *ihost_state){ reply=sock_comm(fm_fd_r, fm_fd_w, "FILTER"); if((reply== NULL) || (strncasecmp(reply, "ERROR", 5)==0)){ - errf("Server error (%m)"); + errf("Server error FILTER failed (%m)"); return -1; } reply_ptr=strchr(reply,';'); @@ -206,9 +228,9 @@ int heartbeat(ihost_state_t *ihost_state){ return -1; } - memset((char *)&addr, 0, sizeof addr); + memset(&addr, 0, sizeof addr); addr.sin_family = AF_INET; - memcpy((char *)&addr.sin_addr, &haddr, sizeof haddr); + memcpy(&addr.sin_addr, &haddr, sizeof haddr); addr.sin_port = htons(ihost_state->server_tcp_port); if (connect(sd, (struct sockaddr *)&addr, sizeof addr) != 0) { @@ -232,7 +254,7 @@ int heartbeat(ihost_state_t *ihost_state){ errf("Server error"); return -1; } - if (ihost_state->fm_host!=NULL) free(ihost_state->fm_host); + reply=sock_comm(fm_fd_r, fm_fd_w, "CONFIG"); if ((reply==NULL) || (strncasecmp(reply, "ERROR", 5) == 0) ) { errf("Server error"); @@ -272,6 +294,9 @@ int heartbeat(ihost_state_t *ihost_state){ return -1; } + fflush(fm_fd_r); + fflush(fm_fd_w); + if(fclose(fm_fd_r) !=0){ errf("Failed to close read FD (%m)"); return -1; @@ -284,13 +309,96 @@ int heartbeat(ihost_state_t *ihost_state){ return exitcode; } +char *stat_grab(ihost_state_t *ihost_state, int counter){ +#define NUM_STATS 9 + char *stats[NUM_STATS]; + char *xml_data=NULL; + char *xml_data_p; + int x=0; + + stats[0]=get_cpu_stats(); + stats[1]=get_disk_stats(); + stats[2]=get_load_stats(); + stats[3]=get_memory_stats(); + stats[4]=get_os_info(); + stats[5]=get_page_stats(); + stats[6]=get_process_stats(); + stats[7]=get_swap_stats(); + stats[8]=get_user_stats(); + for(;x%s", counter, ihost_state->my_fqdn, time(NULL), "127.0.0.1", ihost_state->key, xml_data); + free(xml_data_p); + + return xml_data; +} + +int send_stats(ihost_state_t *ihost_state, char *data_stream){ + struct sockaddr_in addr; + struct in_addr haddr; + + int sd; + size_t len; + + len=strlen(data_stream); + if(len>UDP_MAX_PACKET_SIZE){ + errf("Too big to send to server. Please reconfigure client and server and recompile"); + exit(1); + } + + if (get_host_addr(ihost_state->server_fqdn, &haddr) != 0){ + errf("Failed to resolve address %s (%m)", ihost_state->fm_host); + return -1; + } + + if((sd=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0){ + errf("failed to create UDP socket (%m)"); + return -1; + } + + memset(&addr, 0, sizeof(addr)); + addr.sin_family=AF_INET; + memcpy((char *)&addr.sin_addr, &haddr, sizeof haddr); + addr.sin_port = htons(ihost_state->server_udp_port); + + if((sendto(sd, data_stream, len, 0, (struct sockaddr *) &addr, sizeof(addr))) != len){ + errf("Send the wrong number of bytes (%m)"); + return -1; + } + + close(sd); + + printf("%s\n",data_stream); + return 0; +} + int main(int argc, char **argv){ ihost_state_t ihost_state; int heartbeat_exit; int counter=0; + long udp_time=0, tcp_time=0, stat_grab_time=0, cur_time=0; + int sleep_delay=0; + char *xml_stats; - /* NULL'ify so i can tell if i need to free it or not */ ihost_state.fm_host=NULL; ihost_state.my_fqdn=NULL; @@ -315,20 +423,45 @@ int main(int argc, char **argv){ exit(1); } - while(TRUE){ + for(;;){ + cur_time=time(NULL); + if(cur_time>=tcp_time){ + /*printf("sending TCP\n");*/ + heartbeat_exit=heartbeat(&ihost_state); + if(heartbeat_exit==RECONFIGURE_RETURN_CODE){ + /*errf("heartbeat needs to be reconfigured");*/ + ihost_configure(&ihost_state); + /* So udp doesn't wait til next sending before updating */ + udp_time=0; + } + if(heartbeat_exit==-1){ + errf("ah crap"); + exit(1); + } + tcp_time=time(NULL)+ihost_state.tcp_update_time; + } - heartbeat_exit=heartbeat(&ihost_state); - if(heartbeat_exit==RECONFIGURE_RETURN_CODE){ - errf("heartbeat needs to be reconfigured"); - ihost_configure(&ihost_state); + if(cur_time>=udp_time){ + /*printf("sending UDP\n");*/ + stat_grab_time=time(NULL); + if((xml_stats=stat_grab(&ihost_state, counter++)) == NULL){ + errf("Failed to get stats (%m)"); + exit(1); + } + stat_grab_time=time(NULL)-stat_grab_time; + send_stats(&ihost_state, xml_stats); + free(xml_stats); + udp_time=time(NULL)+ihost_state.udp_update_time-stat_grab_time; } - if(heartbeat_exit==-1){ - errf("ah crap"); - exit(1); - } - printf("Count : %d\n",counter++); - printf("waiting %d\n",ihost_state.tcp_update_time); - sleep(ihost_state.tcp_update_time); + + if(tcp_time0) sleep(sleep_delay); } return 0; }