00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifdef HAVE_CONFIG_H
00014 #include "config.h"
00015 #endif
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
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
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
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 }