00001 // 00002 // WordMonitor.cc 00003 // 00004 // Part of the ht://Dig package <http://www.htdig.org/> 00005 // Copyright (c) 1999, 2000, 2001 The ht://Dig Group 00006 // For copyright details, see the file COPYING in your distribution 00007 // or the GNU General Public License version 2 or later 00008 // <http://www.gnu.org/copyleft/gpl.html> 00009 // 00010 // $Id: WordMonitor_8cc-source.html,v 1.1 2008年06月08日 10:13:17 sebdiaz Exp $ 00011 // 00012 00013 #ifdef HAVE_CONFIG_H 00014 #include "config.h" 00015 #endif /* HAVE_CONFIG_H */ 00016 00017 #include <stdlib.h> 00018 #include <signal.h> 00019 #include <unistd.h> 00020 00021 #include "StringList.h" 00022 #include "WordMonitor.h" 00023 00024 #define WORD_MONITOR_RRD 1 00025 #define WORD_MONITOR_READABLE 2 00026 00027 char* WordMonitor::values_names[WORD_MONITOR_VALUES_SIZE] = { 00028 "", 00029 "C.Write", 00030 "C.Read", 00031 "C.Compress 1/1", 00032 "C.Compress 1/2", 00033 "C.Compress 1/3", 00034 "C.Compress 1/4", 00035 "C.Compress 1/5", 00036 "C.Compress 1/6", 00037 "C.Compress 1/7", 00038 "C.Compress 1/8", 00039 "C.Compress 1/9", 00040 "C.Compress 1/10", 00041 "C.Compress 1/>10", 00042 "C.P_IBTREE", 00043 "C.P_LBTREE", 00044 "C.P_UNKNOWN", 00045 "C.Put", 00046 "C.Get (0)", 00047 "C.Get (NEXT)", 00048 "C.Get (SET_RANGE)", 00049 "C.Get (Other)", 00050 "G.LEVEL", 00051 "G.PGNO", 00052 "C.CMP", 00053 0 00054 }; 00055 00056 WordMonitor::WordMonitor(const Configuration &config) 00057 { 00058 memset((char*)values, '0円', sizeof(unsigned int) * WORD_MONITOR_VALUES_SIZE); 00059 memset((char*)old_values, '0円', sizeof(unsigned int) * WORD_MONITOR_VALUES_SIZE); 00060 started = elapsed = time(0); 00061 output_style = WORD_MONITOR_READABLE; 00062 if((period = config.Value("wordlist_monitor_period"))) { 00063 const String& desc = config.Find("wordlist_monitor_output"); 00064 StringList fields(desc, ','); 00065 00066 if(fields.Count() > 0) { 00067 char* filename = fields[0]; 00068 if(filename[0] == '0円') 00069 output = stderr; 00070 else { 00071 output = fopen(filename, "a"); 00072 if(!output) { 00073 fprintf(stderr, "WordMonitor::WordMonitor: cannot open %s for writing ", filename); 00074 perror(""); 00075 output = stderr; 00076 return; 00077 } 00078 } 00079 if(fields.Count() > 1) { 00080 char* style = fields[1]; 00081 if(!strcasecmp(style, "rrd")) 00082 output_style = WORD_MONITOR_RRD; 00083 else 00084 output_style = WORD_MONITOR_READABLE; 00085 } 00086 } 00087 Start(); 00088 } 00089 } 00090 00091 WordMonitor::~WordMonitor() 00092 { 00093 Stop(); 00094 if(output != stderr) 00095 fclose(output); 00096 } 00097 00098 const String 00099 WordMonitor::Report() const 00100 { 00101 String output; 00102 int i; 00103 time_t now = time(0); 00104 00105 if(output_style == WORD_MONITOR_RRD) 00106 output << (int)now << ":"; 00107 00108 for(i = 0; i < WORD_MONITOR_VALUES_SIZE; i++) { 00109 if(!values_names[i]) break; 00110 if(values_names[i][0]) { 00111 if(output_style == WORD_MONITOR_READABLE) { 00112 output << values_names[i] << ": " << values[i]; 00113 if((now - elapsed) > 0) { 00114 output << ", per sec : " << (int)(values[i] / (now - started)); 00115 output << ", delta : " << (values[i] - old_values[i]); 00116 output << ", per sec : " << (int)((values[i] - old_values[i]) / (now - elapsed)); 00117 } 00118 output << "|"; 00119 } else if(output_style == WORD_MONITOR_RRD) { 00120 output << values[i] << ":"; 00121 } 00122 } 00123 } 00124 memcpy((char*)old_values, (char*)values, sizeof(unsigned int) * WORD_MONITOR_VALUES_SIZE); 00125 return output; 00126 } 00127 00128 void 00129 WordMonitor::Start() 00130 { 00131 if(period < 5) { 00132 fprintf(stderr, "WordMonitor::Start: wordlist_monitor_period must be > 5 (currently %d) otherwise monitoring is not accurate\n", period); 00133 return; 00134 } 00135 00136 fprintf(output, "----------------- WordMonitor starting -------------------\n"); 00137 if(output_style == WORD_MONITOR_RRD) { 00138 fprintf(output, "Started:%ld\n", started); 00139 fprintf(output, "Period:%d\n", period); 00140 fprintf(output, "Time:"); 00141 int i; 00142 for(i = 0; i < WORD_MONITOR_VALUES_SIZE; i++) { 00143 if(!values_names[i]) break; 00144 if(values_names[i][0]) 00145 fprintf(output, "%s:", values_names[i]); 00146 } 00147 fprintf(output, "\n"); 00148 } 00149 fflush(output); 00150 } 00151 00152 void 00153 WordMonitor::Click() 00154 { 00155 // 00156 // Do not report if less than <period> since last report. 00157 // 00158 if(time(0) - elapsed >= period) { 00159 fprintf(output, "%s\n", (const char*)Report()); 00160 elapsed = time(0); 00161 fflush(output); 00162 } 00163 } 00164 00165 void 00166 WordMonitor::Stop() 00167 { 00168 if(period > 0) { 00169 // 00170 // Make sure last report is at least one second older than the previous one. 00171 // 00172 if(time(0) - elapsed < 1) 00173 sleep(2); 00174 fprintf(output, "%s\n", (const char*)Report()); 00175 fprintf(output, "----------------- WordMonitor finished -------------------\n"); 00176 } 00177 } 00178 00179 // 00180 // C interface to WordMonitor instance 00181 // 00182 00183 extern "C" { 00184 void word_monitor_click(void *nmonitor) 00185 { 00186 WordMonitor* monitor = (WordMonitor*)nmonitor; 00187 if(monitor) 00188 monitor->Click(); 00189 } 00190 void word_monitor_add(void *nmonitor, int index, unsigned int value) 00191 { 00192 WordMonitor* monitor = (WordMonitor*)nmonitor; 00193 if(monitor) 00194 monitor->Add(index, value); 00195 } 00196 void word_monitor_set(void *nmonitor, int index, unsigned int value) 00197 { 00198 WordMonitor* monitor = (WordMonitor*)nmonitor; 00199 if(monitor) 00200 monitor->Set(index, value); 00201 } 00202 unsigned int word_monitor_get(void *nmonitor, int index) 00203 { 00204 WordMonitor* monitor = (WordMonitor*)nmonitor; 00205 if(monitor) 00206 return monitor->Get(index); 00207 else 00208 return 0; 00209 } 00210 }