![]() |
Icinga-core 1.4.0
next gen monitoring
|
00001 /***************************************************************************** 00002 * 00003 * PROFILER.C - Event Profiler For Icinga 00004 * 00005 * Copyright: (c) 2009 Intellectual Reserve Inc. 00006 * Author: Steven D. Morrey (nagios-devel@lists.sourceforge.net) 00007 * 00008 * Description: 00009 * 00010 * Nagios is a network monitoring tool that will check hosts and services 00011 * that you specify. This utility adds the ability to profile the events 00012 * occuring within the application itself 00013 * 00014 * License: 00015 * 00016 * This program is free software; you can redistribute it and/or modify 00017 * it under the terms of the GNU General Public License version 2 as 00018 * published by the Free Software Foundation. 00019 * 00020 * This program is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * You should have received a copy of the GNU General Public License 00026 * along with this program; if not, write to the Free Software 00027 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00028 * 00029 *****************************************************************************/ 00030 00031 #include "../include/icinga.h" 00032 00033 /* make sure gcc3 won't hit here */ 00034 #ifndef GCCTOOOLD 00035 00036 #include "../include/profiler.h" 00037 00038 int profiler_item_count = -1; 00039 00040 int profiler_core_event_types[] = { 00041 EVENT_SERVICE_CHECK, 00042 EVENT_HOST_CHECK, 00043 EVENT_COMMAND_CHECK, 00044 EVENT_LOG_ROTATION, 00045 EVENT_PROGRAM_SHUTDOWN, 00046 EVENT_PROGRAM_RESTART, 00047 EVENT_CHECK_REAPER, 00048 EVENT_ORPHAN_CHECK, 00049 EVENT_RETENTION_SAVE, 00050 EVENT_STATUS_SAVE, 00051 EVENT_SCHEDULED_DOWNTIME, 00052 EVENT_SFRESHNESS_CHECK, 00053 EVENT_HFRESHNESS_CHECK, 00054 EVENT_EXPIRE_DOWNTIME, 00055 EVENT_RESCHEDULE_CHECKS, 00056 EVENT_EXPIRE_COMMENT, 00057 EVENT_USER_FUNCTION, 00058 EVENT_LOOP_COMPLETION 00059 }; 00060 00061 profiler_item * profiler; 00062 00063 00064 void profiler_init() 00065 { 00066 profiler = (profiler_item*)calloc(++profiler_item_count,sizeof(profiler_item)); 00067 profiler_add(EVENT_SERVICE_CHECK,"EVENT_SERVICE_CHECK"); 00068 profiler_add(EVENT_HOST_CHECK,"EVENT_HOST_CHECK"); 00069 profiler_add(EVENT_COMMAND_CHECK,"EVENT_COMMAND_CHECK"); 00070 profiler_add(EVENT_LOG_ROTATION,"EVENT_LOG_ROTATION"); 00071 profiler_add(EVENT_PROGRAM_SHUTDOWN,"EVENT_PROGRAM_SHUTDOWN"); 00072 profiler_add(EVENT_PROGRAM_RESTART,"EVENT_PROGRAM_RESTART"); 00073 profiler_add(EVENT_CHECK_REAPER,"EVENT_CHECK_REAPER"); 00074 profiler_add(EVENT_ORPHAN_CHECK,"EVENT_ORPHAN_CHECK"); 00075 profiler_add(EVENT_RETENTION_SAVE,"EVENT_RETENTION_SAVE"); 00076 profiler_add(EVENT_STATUS_SAVE,"EVENT_STATUS_SAVE"); 00077 profiler_add(EVENT_SCHEDULED_DOWNTIME,"EVENT_SCHEDULED_DOWNTIME"); 00078 profiler_add(EVENT_SFRESHNESS_CHECK,"EVENT_SFRESHNESS_CHECK"); 00079 profiler_add(EVENT_HFRESHNESS_CHECK,"EVENT_HFRESHNESS_CHECK"); 00080 profiler_add(EVENT_EXPIRE_DOWNTIME,"EVENT_EXPIRE_DOWNTIME"); 00081 profiler_add(EVENT_RESCHEDULE_CHECKS,"EVENT_RESCHEDULE_CHECKS"); 00082 profiler_add(EVENT_EXPIRE_COMMENT,"EVENT_EXPIRE_COMMENT"); 00083 profiler_add(EVENT_USER_FUNCTION,"EVENT_USER_FUNCTION"); 00084 profiler_add(EVENT_LOOP_COMPLETION,"EVENT_LOOP_COMPLETION"); 00085 profiler_enable_core(); 00086 } 00087 00088 void profiler_enable_core() 00089 { 00090 int x=0; 00091 int core_event_count = sizeof(profiler_core_event_types)/sizeof(int); 00092 while(x<=core_event_count) 00093 { 00094 profiler_setstate(profiler_core_event_types[x],1); 00095 x++; 00096 } 00097 } 00098 00099 void profiler_enable_all() 00100 { 00101 int x=0; 00102 while(x<=profiler_item_count) 00103 { 00104 profiler_setstate(x,1); 00105 x++; 00106 } 00107 } 00108 00109 void profiler_full_reset(profiler_item *p[]) 00110 { 00111 int x=0; 00112 while(x<= profiler_item_count) 00113 { 00114 profiler_item_reset(p[x]); 00115 x++; 00116 } 00117 } 00118 00119 void profiler_item_reset(profiler_item *p) 00120 { 00121 p->state=0; 00122 p->counter=0; 00123 p->elapsed=0; 00124 } 00125 00126 void profiler_free(profiler_item *p[], int count) 00127 { 00128 //Free the old memory 00129 int x=count; 00130 for(; x > 0; x--) 00131 { 00132 free(p[x]->name); 00133 free(p[x]); 00134 } 00135 } 00136 00137 void profiler_add(int event, char *name) 00138 { 00139 if(event >= profiler_item_count) 00140 { 00141 profiler_item_count = event; 00142 profiler = realloc(profiler,(sizeof(profiler_item) * (++profiler_item_count))); 00143 if(profiler == NULL) 00144 { 00145 printf("Could not allocate sufficient memory, exiting now!\n"); 00146 exit(0); 00147 } 00148 00149 } 00150 00151 profiler[event].state = 0; 00152 profiler[event].counter = 0; 00153 profiler[event].elapsed = 0; 00154 profiler[event].name = strdup(name); 00155 } 00156 00157 void profiler_setstate(int event,int state) 00158 { 00159 profiler[event].state = state; 00160 } 00161 00162 void profiler_rename(int p, char * name) 00163 { 00164 free(profiler[p].name); 00165 profiler[p].name = strdup(name); 00166 } 00167 00168 void profiler_update(int event, struct timeval start) 00169 { 00170 static int counter; 00171 struct timeval end; 00172 gettimeofday(&end,NULL); 00173 00174 //We do this to prevent segfaulting since it could be a we end up with a sparse array 00175 //It's ugly but it saves having to try and know everything that may be profiled in advance. 00176 //It's only slow the first time a new event type is profiled. 00177 while(event > profiler_item_count) 00178 { 00179 char name[20]; 00180 memset(name,'\0',20); 00181 sprintf(name,"UNKNOWN_%d",counter++); 00182 profiler_add(event,(char*)&name); 00183 } 00184 00185 if(profiler[event].state) 00186 { 00187 profiler[event].elapsed+=(double)((end.tv_usec - start.tv_usec)/1000000) + ((end.tv_sec - start.tv_sec)); 00188 profiler[event].counter++; 00189 } 00190 } 00191 00192 void profiler_output(FILE* fp) 00193 { 00194 int c; 00195 for(c=0; c < profiler_item_count; c++) 00196 { 00197 //Only print those that are turned on. 00198 if(profiler[c].state) 00199 { 00200 if(profiler[c].name) 00201 { 00202 fprintf(fp,"\tPROFILE_COUNTER_%s=%d\n",profiler[c].name,profiler[c].counter); 00203 fprintf(fp,"\tPROFILE_ELAPSED_%s=%f\n",profiler[c].name,profiler[c].elapsed); 00204 } 00205 } 00206 } 00207 00208 } 00209 00210 #endif