Icinga-core 1.4.0
next gen monitoring
base/profiler.c
Go to the documentation of this file.
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
 All Data Structures Files Functions Variables Typedefs Defines