![]() |
Icinga-core 1.4.0
next gen monitoring
|
00001 /***************************************************************************** 00002 * 00003 * STATUSDATA.C - External status data for Icinga CGIs 00004 * 00005 * Copyright (c) 2000-2008 Ethan Galstad (egalstad@nagios.org) 00006 * Copyright (c) 2009-2011 Icinga Development Team (http://www.icinga.org) 00007 * 00008 * License: 00009 * 00010 * This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License version 2 as 00012 * published by the Free Software Foundation. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software 00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00022 * 00023 *****************************************************************************/ 00024 00025 /*********** COMMON HEADER FILES ***********/ 00026 00027 #include "../include/config.h" 00028 #include "../include/common.h" 00029 #include "../include/objects.h" 00030 #include "../include/statusdata.h" 00031 00032 #ifdef NSCORE 00033 #include "../include/icinga.h" 00034 #include "../include/broker.h" 00035 #endif 00036 #ifdef NSCGI 00037 #include "../include/cgiutils.h" 00038 #endif 00039 00040 /**** IMPLEMENTATION SPECIFIC HEADER FILES ****/ 00041 00042 #ifdef USE_XSDDEFAULT 00043 #include "../xdata/xsddefault.h" /* default routines */ 00044 #endif 00045 00046 00047 #ifdef NSCORE 00048 extern int aggregate_status_updates; 00049 #endif 00050 00051 #ifdef NSCGI 00052 hoststatus *hoststatus_list=NULL; 00053 hoststatus *hoststatus_list_tail=NULL; 00054 servicestatus *servicestatus_list=NULL; 00055 servicestatus *servicestatus_list_tail=NULL; 00056 00057 hoststatus **hoststatus_hashlist=NULL; 00058 servicestatus **servicestatus_hashlist=NULL; 00059 00060 extern int use_pending_states; 00061 #endif 00062 00063 int dummy; /* reduce compiler warnings */ 00064 00065 #ifdef NSCORE 00066 00067 /******************************************************************/ 00068 /****************** TOP-LEVEL OUTPUT FUNCTIONS ********************/ 00069 /******************************************************************/ 00070 00071 /* initializes status data at program start */ 00072 int initialize_status_data(char *config_file){ 00073 int result=OK; 00074 00075 /**** IMPLEMENTATION-SPECIFIC CALLS ****/ 00076 #ifdef USE_XSDDEFAULT 00077 result=xsddefault_initialize_status_data(config_file); 00078 #endif 00079 00080 return result; 00081 } 00082 00083 00084 /* update all status data (aggregated dump) */ 00085 int update_all_status_data(void){ 00086 int result=OK; 00087 00088 #ifdef USE_EVENT_BROKER 00089 /* send data to event broker */ 00090 broker_aggregated_status_data(NEBTYPE_AGGREGATEDSTATUS_STARTDUMP,NEBFLAG_NONE,NEBATTR_NONE,NULL); 00091 #endif 00092 00093 /**** IMPLEMENTATION-SPECIFIC CALLS ****/ 00094 #ifdef USE_XSDDEFAULT 00095 result=xsddefault_save_status_data(); 00096 #endif 00097 00098 #ifdef USE_EVENT_BROKER 00099 /* send data to event broker */ 00100 broker_aggregated_status_data(NEBTYPE_AGGREGATEDSTATUS_ENDDUMP,NEBFLAG_NONE,NEBATTR_NONE,NULL); 00101 #endif 00102 00103 if(result!=OK) 00104 return ERROR; 00105 00106 return OK; 00107 } 00108 00109 00110 /* cleans up status data before program termination */ 00111 int cleanup_status_data(char *config_file,int delete_status_data){ 00112 int result=OK; 00113 00114 /**** IMPLEMENTATION-SPECIFIC CALLS ****/ 00115 #ifdef USE_XSDDEFAULT 00116 result=xsddefault_cleanup_status_data(config_file,delete_status_data); 00117 #endif 00118 00119 return result; 00120 } 00121 00122 00123 00124 /* updates program status info */ 00125 int update_program_status(int aggregated_dump){ 00126 00127 #ifdef USE_EVENT_BROKER 00128 /* send data to event broker (non-aggregated dumps only) */ 00129 if(aggregated_dump==FALSE) 00130 broker_program_status(NEBTYPE_PROGRAMSTATUS_UPDATE,NEBFLAG_NONE,NEBATTR_NONE,NULL); 00131 #endif 00132 00133 /* currently a noop if aggregated updates is TRUE */ 00134 00135 /* update all status data if we're not aggregating updates */ 00136 if(aggregate_status_updates==FALSE) 00137 update_all_status_data(); 00138 00139 return OK; 00140 } 00141 00142 00143 00144 /* updates host status info */ 00145 int update_host_status(host *hst,int aggregated_dump){ 00146 00147 #ifdef USE_EVENT_BROKER 00148 /* send data to event broker (non-aggregated dumps only) */ 00149 if(aggregated_dump==FALSE) 00150 broker_host_status(NEBTYPE_HOSTSTATUS_UPDATE,NEBFLAG_NONE,NEBATTR_NONE,hst,NULL); 00151 #endif 00152 00153 /* currently a noop if aggregated updates is TRUE */ 00154 00155 /* update all status data if we're not aggregating updates */ 00156 if(aggregate_status_updates==FALSE) 00157 update_all_status_data(); 00158 00159 return OK; 00160 } 00161 00162 00163 00164 /* updates service status info */ 00165 int update_service_status(service *svc,int aggregated_dump){ 00166 00167 #ifdef USE_EVENT_BROKER 00168 /* send data to event broker (non-aggregated dumps only) */ 00169 if(aggregated_dump==FALSE) 00170 broker_service_status(NEBTYPE_SERVICESTATUS_UPDATE,NEBFLAG_NONE,NEBATTR_NONE,svc,NULL); 00171 #endif 00172 00173 /* currently a noop if aggregated updates is TRUE */ 00174 00175 /* update all status data if we're not aggregating updates */ 00176 if(aggregate_status_updates==FALSE) 00177 update_all_status_data(); 00178 00179 return OK; 00180 } 00181 00182 00183 00184 /* updates contact status info */ 00185 int update_contact_status(contact *cntct,int aggregated_dump){ 00186 00187 #ifdef USE_EVENT_BROKER 00188 /* send data to event broker (non-aggregated dumps only) */ 00189 if(aggregated_dump==FALSE) 00190 broker_contact_status(NEBTYPE_CONTACTSTATUS_UPDATE,NEBFLAG_NONE,NEBATTR_NONE,cntct,NULL); 00191 #endif 00192 00193 /* currently a noop if aggregated updates is TRUE */ 00194 00195 /* update all status data if we're not aggregating updates */ 00196 if(aggregate_status_updates==FALSE) 00197 update_all_status_data(); 00198 00199 return OK; 00200 } 00201 #endif 00202 00203 00204 00205 00206 00207 #ifdef NSCGI 00208 00209 /******************************************************************/ 00210 /******************* TOP-LEVEL INPUT FUNCTIONS ********************/ 00211 /******************************************************************/ 00212 00213 00214 /* reads in all status data */ 00215 int read_status_data(char *config_file,int options){ 00216 int result=OK; 00217 00218 /**** IMPLEMENTATION-SPECIFIC CALLS ****/ 00219 #ifdef USE_XSDDEFAULT 00220 result=xsddefault_read_status_data(config_file,options); 00221 #endif 00222 #ifdef USE_XSDDB 00223 result=xsddb_read_status_data(config_file,options); 00224 #endif 00225 00226 return result; 00227 } 00228 00229 00230 00231 /******************************************************************/ 00232 /****************** CHAINED HASH FUNCTIONS ************************/ 00233 /******************************************************************/ 00234 00235 /* adds hoststatus to hash list in memory */ 00236 int add_hoststatus_to_hashlist(hoststatus *new_hoststatus){ 00237 hoststatus *temp_hoststatus=NULL; 00238 hoststatus *lastpointer=NULL; 00239 int hashslot=0; 00240 int i=0; 00241 00242 /* initialize hash list */ 00243 if(hoststatus_hashlist==NULL){ 00244 00245 hoststatus_hashlist=(hoststatus **)malloc(sizeof(hoststatus *)*HOSTSTATUS_HASHSLOTS); 00246 if(hoststatus_hashlist==NULL) 00247 return 0; 00248 00249 for(i=0;i<HOSTSTATUS_HASHSLOTS;i++) 00250 hoststatus_hashlist[i]=NULL; 00251 } 00252 00253 if(!new_hoststatus) 00254 return 0; 00255 00256 hashslot=hashfunc(new_hoststatus->host_name,NULL,HOSTSTATUS_HASHSLOTS); 00257 lastpointer=NULL; 00258 for(temp_hoststatus=hoststatus_hashlist[hashslot];temp_hoststatus && compare_hashdata(temp_hoststatus->host_name,NULL,new_hoststatus->host_name,NULL)<0;temp_hoststatus=temp_hoststatus->nexthash) 00259 lastpointer=temp_hoststatus; 00260 00261 if(!temp_hoststatus || (compare_hashdata(temp_hoststatus->host_name,NULL,new_hoststatus->host_name,NULL)!=0)){ 00262 if(lastpointer) 00263 lastpointer->nexthash=new_hoststatus; 00264 else 00265 hoststatus_hashlist[hashslot]=new_hoststatus; 00266 new_hoststatus->nexthash=temp_hoststatus; 00267 00268 return 1; 00269 } 00270 00271 /* else already exists */ 00272 return 0; 00273 } 00274 00275 00276 int add_servicestatus_to_hashlist(servicestatus *new_servicestatus){ 00277 servicestatus *temp_servicestatus=NULL, *lastpointer=NULL; 00278 int hashslot=0; 00279 int i=0; 00280 00281 /* initialize hash list */ 00282 if(servicestatus_hashlist==NULL){ 00283 00284 servicestatus_hashlist=(servicestatus **)malloc(sizeof(servicestatus *)*SERVICESTATUS_HASHSLOTS); 00285 if(servicestatus_hashlist==NULL) 00286 return 0; 00287 00288 for(i=0;i< SERVICESTATUS_HASHSLOTS;i++) 00289 servicestatus_hashlist[i]=NULL; 00290 } 00291 00292 if(!new_servicestatus) 00293 return 0; 00294 00295 hashslot=hashfunc(new_servicestatus->host_name,new_servicestatus->description,SERVICESTATUS_HASHSLOTS); 00296 lastpointer=NULL; 00297 for(temp_servicestatus=servicestatus_hashlist[hashslot];temp_servicestatus && compare_hashdata(temp_servicestatus->host_name,temp_servicestatus->description,new_servicestatus->host_name,new_servicestatus->description)<0;temp_servicestatus=temp_servicestatus->nexthash) 00298 lastpointer=temp_servicestatus; 00299 00300 if(!temp_servicestatus || (compare_hashdata(temp_servicestatus->host_name,temp_servicestatus->description,new_servicestatus->host_name,new_servicestatus->description)!=0)){ 00301 if(lastpointer) 00302 lastpointer->nexthash=new_servicestatus; 00303 else 00304 servicestatus_hashlist[hashslot]=new_servicestatus; 00305 new_servicestatus->nexthash=temp_servicestatus; 00306 00307 00308 return 1; 00309 } 00310 00311 /* else already exists */ 00312 return 0; 00313 } 00314 00315 00316 00317 /******************************************************************/ 00318 /********************** ADDITION FUNCTIONS ************************/ 00319 /******************************************************************/ 00320 00321 00322 /* adds a host status entry to the list in memory */ 00323 int add_host_status(hoststatus *new_hoststatus){ 00324 char date_string[MAX_DATETIME_LENGTH]; 00325 00326 /* make sure we have what we need */ 00327 if(new_hoststatus==NULL) 00328 return ERROR; 00329 if(new_hoststatus->host_name==NULL) 00330 return ERROR; 00331 00332 /* massage host status a bit */ 00333 if(new_hoststatus!=NULL){ 00334 switch(new_hoststatus->status){ 00335 case 0: 00336 new_hoststatus->status=HOST_UP; 00337 break; 00338 case 1: 00339 new_hoststatus->status=HOST_DOWN; 00340 break; 00341 case 2: 00342 new_hoststatus->status=HOST_UNREACHABLE; 00343 break; 00344 default: 00345 new_hoststatus->status=HOST_UP; 00346 break; 00347 } 00348 if(new_hoststatus->has_been_checked==FALSE){ 00349 if(use_pending_states==TRUE) 00350 new_hoststatus->status=HOST_PENDING; 00351 my_free(new_hoststatus->plugin_output); 00352 if(new_hoststatus->should_be_scheduled==TRUE){ 00353 get_time_string(&new_hoststatus->next_check,date_string,sizeof(date_string),LONG_DATE_TIME); 00354 dummy=asprintf(&new_hoststatus->plugin_output,"Host check scheduled for %s",date_string); 00355 } 00356 else{ 00357 /* passive-only hosts that have just been scheduled for a forced check */ 00358 if(new_hoststatus->checks_enabled==FALSE && new_hoststatus->next_check!=(time_t)0L && (new_hoststatus->check_options & CHECK_OPTION_FORCE_EXECUTION)){ 00359 get_time_string(&new_hoststatus->next_check,date_string,sizeof(date_string),LONG_DATE_TIME); 00360 dummy=asprintf(&new_hoststatus->plugin_output,"Forced host check scheduled for %s",date_string); 00361 } 00362 /* passive-only hosts not scheduled to be checked */ 00363 else 00364 new_hoststatus->plugin_output=(char *)strdup("Host is not scheduled to be checked..."); 00365 } 00366 } 00367 } 00368 00369 new_hoststatus->next=NULL; 00370 new_hoststatus->nexthash=NULL; 00371 00372 /* add new hoststatus to hoststatus chained hash list */ 00373 if(!add_hoststatus_to_hashlist(new_hoststatus)) 00374 return ERROR; 00375 00376 /* object cache file is already sorted, so just add new items to end of list */ 00377 if(hoststatus_list==NULL){ 00378 hoststatus_list=new_hoststatus; 00379 hoststatus_list_tail=new_hoststatus; 00380 } 00381 else{ 00382 hoststatus_list_tail->next=new_hoststatus; 00383 hoststatus_list_tail=new_hoststatus; 00384 } 00385 00386 return OK; 00387 } 00388 00389 00390 /* adds a service status entry to the list in memory */ 00391 int add_service_status(servicestatus *new_svcstatus){ 00392 char date_string[MAX_DATETIME_LENGTH]; 00393 00394 /* make sure we have what we need */ 00395 if(new_svcstatus==NULL) 00396 return ERROR; 00397 if(new_svcstatus->host_name==NULL || new_svcstatus->description==NULL) 00398 return ERROR; 00399 00400 00401 /* massage service status a bit */ 00402 if(new_svcstatus!=NULL){ 00403 switch(new_svcstatus->status){ 00404 case 0: 00405 new_svcstatus->status=SERVICE_OK; 00406 break; 00407 case 1: 00408 new_svcstatus->status=SERVICE_WARNING; 00409 break; 00410 case 2: 00411 new_svcstatus->status=SERVICE_CRITICAL; 00412 break; 00413 case 3: 00414 new_svcstatus->status=SERVICE_UNKNOWN; 00415 break; 00416 default: 00417 new_svcstatus->status=SERVICE_OK; 00418 break; 00419 } 00420 if(new_svcstatus->has_been_checked==FALSE){ 00421 if(use_pending_states==TRUE) 00422 new_svcstatus->status=SERVICE_PENDING; 00423 my_free(new_svcstatus->plugin_output); 00424 if(new_svcstatus->should_be_scheduled==TRUE){ 00425 get_time_string(&new_svcstatus->next_check,date_string,sizeof(date_string),LONG_DATE_TIME); 00426 dummy=asprintf(&new_svcstatus->plugin_output,"Service check scheduled for %s",date_string); 00427 } 00428 else{ 00429 /* passive-only services that have just been scheduled for a forced check */ 00430 if(new_svcstatus->checks_enabled==FALSE && new_svcstatus->next_check!=(time_t)0L && (new_svcstatus->check_options & CHECK_OPTION_FORCE_EXECUTION)){ 00431 get_time_string(&new_svcstatus->next_check,date_string,sizeof(date_string),LONG_DATE_TIME); 00432 dummy=asprintf(&new_svcstatus->plugin_output,"Forced service check scheduled for %s",date_string); 00433 } 00434 /* passive-only services not scheduled to be checked */ 00435 else 00436 new_svcstatus->plugin_output=(char *)strdup("Service is not scheduled to be checked..."); 00437 } 00438 } 00439 } 00440 00441 new_svcstatus->next=NULL; 00442 new_svcstatus->nexthash=NULL; 00443 00444 /* add new servicestatus to servicestatus chained hash list */ 00445 if(!add_servicestatus_to_hashlist(new_svcstatus)) 00446 return ERROR; 00447 00448 /* object cache file is already sorted, so just add new items to end of list */ 00449 if(servicestatus_list==NULL){ 00450 servicestatus_list=new_svcstatus; 00451 servicestatus_list_tail=new_svcstatus; 00452 } 00453 else{ 00454 servicestatus_list_tail->next=new_svcstatus; 00455 servicestatus_list_tail=new_svcstatus; 00456 } 00457 00458 return OK; 00459 } 00460 00461 00462 00463 00464 00465 /******************************************************************/ 00466 /*********************** CLEANUP FUNCTIONS ************************/ 00467 /******************************************************************/ 00468 00469 00470 /* free all memory for status data */ 00471 void free_status_data(void){ 00472 hoststatus *this_hoststatus=NULL; 00473 hoststatus *next_hoststatus=NULL; 00474 servicestatus *this_svcstatus=NULL; 00475 servicestatus *next_svcstatus=NULL; 00476 00477 /* free memory for the host status list */ 00478 for(this_hoststatus=hoststatus_list;this_hoststatus!=NULL;this_hoststatus=next_hoststatus){ 00479 next_hoststatus=this_hoststatus->next; 00480 my_free(this_hoststatus->host_name); 00481 my_free(this_hoststatus->plugin_output); 00482 my_free(this_hoststatus->long_plugin_output); 00483 my_free(this_hoststatus->perf_data); 00484 my_free(this_hoststatus); 00485 } 00486 00487 /* free memory for the service status list */ 00488 for(this_svcstatus=servicestatus_list;this_svcstatus!=NULL;this_svcstatus=next_svcstatus){ 00489 next_svcstatus=this_svcstatus->next; 00490 my_free(this_svcstatus->host_name); 00491 my_free(this_svcstatus->description); 00492 my_free(this_svcstatus->plugin_output); 00493 my_free(this_svcstatus->long_plugin_output); 00494 my_free(this_svcstatus->perf_data); 00495 my_free(this_svcstatus); 00496 } 00497 00498 /* free hash lists reset list pointers */ 00499 my_free(hoststatus_hashlist); 00500 my_free(servicestatus_hashlist); 00501 hoststatus_list=NULL; 00502 servicestatus_list=NULL; 00503 00504 return; 00505 } 00506 00507 00508 00509 00510 /******************************************************************/ 00511 /************************ SEARCH FUNCTIONS ************************/ 00512 /******************************************************************/ 00513 00514 00515 /* find a host status entry */ 00516 hoststatus *find_hoststatus(char *host_name){ 00517 hoststatus *temp_hoststatus=NULL; 00518 00519 if(host_name==NULL || hoststatus_hashlist==NULL) 00520 return NULL; 00521 00522 for(temp_hoststatus=hoststatus_hashlist[hashfunc(host_name,NULL,HOSTSTATUS_HASHSLOTS)];temp_hoststatus && compare_hashdata(temp_hoststatus->host_name,NULL,host_name,NULL)<0;temp_hoststatus=temp_hoststatus->nexthash); 00523 00524 if(temp_hoststatus && (compare_hashdata(temp_hoststatus->host_name,NULL,host_name,NULL)==0)) 00525 return temp_hoststatus; 00526 00527 return NULL; 00528 } 00529 00530 00531 /* find a service status entry */ 00532 servicestatus *find_servicestatus(char *host_name,char *svc_desc){ 00533 servicestatus *temp_servicestatus=NULL; 00534 00535 if(host_name==NULL || svc_desc==NULL || servicestatus_hashlist==NULL) 00536 return NULL; 00537 00538 for(temp_servicestatus=servicestatus_hashlist[hashfunc(host_name,svc_desc,SERVICESTATUS_HASHSLOTS)];temp_servicestatus && compare_hashdata(temp_servicestatus->host_name,temp_servicestatus->description,host_name,svc_desc)<0;temp_servicestatus=temp_servicestatus->nexthash); 00539 00540 if(temp_servicestatus && (compare_hashdata(temp_servicestatus->host_name,temp_servicestatus->description,host_name,svc_desc)==0)) 00541 return temp_servicestatus; 00542 00543 return NULL; 00544 } 00545 00546 00547 00548 00549 /******************************************************************/ 00550 /*********************** UTILITY FUNCTIONS ************************/ 00551 /******************************************************************/ 00552 00553 00554 /* gets the total number of services of a certain state for a specific host */ 00555 int get_servicestatus_count(char *host_name, int type){ 00556 servicestatus *temp_status=NULL; 00557 int count=0; 00558 00559 if(host_name==NULL) 00560 return 0; 00561 00562 for(temp_status=servicestatus_list;temp_status!=NULL;temp_status=temp_status->next){ 00563 if(temp_status->status & type){ 00564 if(!strcmp(host_name,temp_status->host_name)) 00565 count++; 00566 } 00567 } 00568 00569 return count; 00570 } 00571 00572 00573 00574 #endif 00575