Large installation CGI optimization patch

Cary Petterborg PetterborgCa at ldschurch.org
Thu Mar 3 19:34:31 CET 2011


I have been working on a simple change to the xsddefault.c file which seems to be a good optimization for large installations. Our installation has 43,500 services and 4,200 hosts. The CGI's tend to take a while to go through the status.dat file as a result. The way that the routine is written to read in the status.dat file has some design drawbacks that make it interpret the lines more slowly than it could.

If the status.dat file is uncorrupted (which if it is corrupted, there are more problems than reading that file in), then the order of testing for different types of data on the line consumes more time than it should. If you are already inside a definition of a service, host, or whatever, there is no reason to test whether you are going to run into another object definition start line until after you have ended the definition that you are currently in. The optimization that I have made just takes that into account, and it no longer has to do 10 strcmp() calls for every line it reads. When an object definition starts (e.g. "hoststatus {"), just set a flag, then clear it when you get to the end ("}"). Then when you look at a line, don't look for the possible definition lines, just check the flag and look for variable/value pair (var=value).

In our case, the speed increase is not dramatic, but it is significant. The average time to execute for one of the CGI's was reduced by .7 seconds. While this is only about 10%, this reduces the load on the web server significantly when there are many requests for these pages. In some cases (when the server is busy) it reduces the execution time by as much as 3 seconds, which is more like 40%.

I'm submitting this modification for evaluation and comment. Hopefully it can make it into the Nagios code base.

Cary Petterborg

---------------------

Below is the output of a diff of xsddefault.c from the version of 3.2.1 that we are currently using (*most* of the differences are just the indentation of the section that is now enclosed within an if statement):

Index: xsddefault.c
===================================================================
--- xsddefault.c (revision 1955)
+++ xsddefault.c              (working copy)
@@ -766,6 +766,7 @@
               unsigned long triggered_by=0;
               unsigned long duration=0L;
               int x=0;
+             int in_block = FALSE;

                /* initialize some vars */
@@ -815,47 +816,66 @@
                               if(input[0]=='#' || input[0]=='\x0')
                                               continue;
-                              else if(!strcmp(input,"info {"))
-                                              data_type=XSDDEFAULT_INFO_DATA;
-                              else if(!strcmp(input,"programstatus {"))
-                                              data_type=XSDDEFAULT_PROGRAMSTATUS_DATA;
-                              else if(!strcmp(input,"hoststatus {")){
-                                              data_type=XSDDEFAULT_HOSTSTATUS_DATA;
-                                              temp_hoststatus=(hoststatus *)malloc(sizeof(hoststatus));
-                                              if(temp_hoststatus){
-                                                              temp_hoststatus->host_name=NULL;
-                                                              temp_hoststatus->plugin_output=NULL;
-                                                              temp_hoststatus->long_plugin_output=NULL;
-                                                              temp_hoststatus->perf_data=NULL;
-                                                              temp_hoststatus->check_options=0;
-                                                      }
-                                      }
-                              else if(!strcmp(input,"servicestatus {")){
-                                              data_type=XSDDEFAULT_SERVICESTATUS_DATA;
-                                              temp_servicestatus=(servicestatus *)malloc(sizeof(servicestatus));
-                                              if(temp_servicestatus){
-                                                              temp_servicestatus->host_name=NULL;
-                                                              temp_servicestatus->description=NULL;
-                                                              temp_servicestatus->plugin_output=NULL;
-                                                              temp_servicestatus->long_plugin_output=NULL;
-                                                              temp_servicestatus->perf_data=NULL;
-                                                              temp_servicestatus->check_options=0;
-                                                      }
-                                      }
-                              else if(!strcmp(input,"contactstatus {")){
-                                              data_type=XSDDEFAULT_CONTACTSTATUS_DATA;
-                                              /* unimplemented */
-                                      }
-                              else if(!strcmp(input,"hostcomment {"))
-                                              data_type=XSDDEFAULT_HOSTCOMMENT_DATA;
-                              else if(!strcmp(input,"servicecomment {"))
-                                              data_type=XSDDEFAULT_SERVICECOMMENT_DATA;
-                              else if(!strcmp(input,"hostdowntime {"))
-                                              data_type=XSDDEFAULT_HOSTDOWNTIME_DATA;
-                              else if(!strcmp(input,"servicedowntime {"))
-                                              data_type=XSDDEFAULT_SERVICEDOWNTIME_DATA;
+                             if (!in_block ) {
+                                             if(!strcmp(input,"info {")) {
+                                                             in_block = TRUE;
+                                                             data_type=XSDDEFAULT_INFO_DATA;
+                                             }
+                                             else if(!strcmp(input,"programstatus {")){
+                                                             in_block = TRUE;
+                                                             data_type=XSDDEFAULT_PROGRAMSTATUS_DATA;
+                                             }
+                                             else if(!strcmp(input,"hoststatus {")){
+                                                             in_block = TRUE;
+                                                             data_type=XSDDEFAULT_HOSTSTATUS_DATA;
+                                                             temp_hoststatus=(hoststatus *)malloc(sizeof(hoststatus));
+                                                             if(temp_hoststatus){
+                                                                             temp_hoststatus->host_name=NULL;
+                                                                             temp_hoststatus->plugin_output=NULL;
+                                                                             temp_hoststatus->long_plugin_output=NULL;
+                                                                             temp_hoststatus->perf_data=NULL;
+                                                                             temp_hoststatus->check_options=0;
+                                                                                             }
+                                                                             }
+                                             else if(!strcmp(input,"servicestatus {")){
+                                                             in_block = TRUE;
+                                                             data_type=XSDDEFAULT_SERVICESTATUS_DATA;
+                                                             temp_servicestatus=(servicestatus *)malloc(sizeof(servicestatus));
+                                                             if(temp_servicestatus){
+                                                                             temp_servicestatus->host_name=NULL;
+                                                                             temp_servicestatus->description=NULL;
+                                                                             temp_servicestatus->plugin_output=NULL;
+                                                                             temp_servicestatus->long_plugin_output=NULL;
+                                                                             temp_servicestatus->perf_data=NULL;
+                                                                             temp_servicestatus->check_options=0;
+                                                                                             }
+                                                                             }
+                                             else if(!strcmp(input,"contactstatus {")){
+                                                             in_block = TRUE;
+                                                             data_type=XSDDEFAULT_CONTACTSTATUS_DATA;
+                                                             /* unimplemented */
+                                                                             }
+                                             else if(!strcmp(input,"hostcomment {")){
+                                                             in_block = TRUE;
+                                                             data_type=XSDDEFAULT_HOSTCOMMENT_DATA;
+                                             }
+                                             else if(!strcmp(input,"servicecomment {")){
+                                                             in_block = TRUE;
+                                                             data_type=XSDDEFAULT_SERVICECOMMENT_DATA;
+                                             }
+                                             else if(!strcmp(input,"hostdowntime {")){
+                                                             in_block = TRUE;
+                                                             data_type=XSDDEFAULT_HOSTDOWNTIME_DATA;
+                                             }
+                                             else if(!strcmp(input,"servicedowntime {")){
+                                                             in_block = TRUE;
+                                                             data_type=XSDDEFAULT_SERVICEDOWNTIME_DATA;
+                                             }
+                             }
+
                               else if(!strcmp(input,"}")){
+                                             in_block = FALSE;
                                                switch(data_type){


 NOTICE: This email message is for the sole use of the intended recipient(s) and may contain confidential and privileged information. Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.monitoring-lists.org/archive/developers/attachments/20110303/b5f7bc00/attachment.html>
-------------- next part --------------
------------------------------------------------------------------------------
Free Software Download: Index, Search & Analyze Logs and other IT data in 
Real-Time with Splunk. Collect, index and harness all the fast moving IT data 
generated by your applications, servers and devices whether physical, virtual
or in the cloud. Deliver compliance at lower cost and gain new business 
insights. http://p.sf.net/sfu/splunk-dev2dev 
-------------- next part --------------
_______________________________________________
Nagios-devel mailing list
Nagios-devel at lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nagios-devel


More information about the Developers mailing list