Changeset 152
- Timestamp:
- 01/27/10 15:28:06 (15 years ago)
- Location:
- Evidence
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
Evidence/Alarm.cc
r145 r152 51 51 AlarmSummary = new char [SUMMARYSIZE]; 52 52 MasterAlarm = 0; 53 53 54 54 char *ServerNames = GetConfig(SERVER_NAME " servers"); 55 55 -
Evidence/DColl.cc
r151 r152 11 11 written to the data file. Only if the new value has changed by a 12 12 minimum amout it will be added to the ring buffer. 13 - The history buffers are written to disk at program termination and 14 are tired to be read when adding a service. 13 15 - The command 'DColl/Log' writes the associated string to the log 14 16 file specified in the configuration. … … 23 25 24 26 #include "Evidence.h" 27 28 #include <string> 29 #include <sstream> 30 #include <vector> 31 #include <iomanip> 25 32 26 33 #include <math.h> … … 44 51 double LastValue; 45 52 double MinAbsChange; 46 } *List; 47 53 }; 54 vector<struct Item> List; 55 48 56 DimCommand *LogCommand; 49 57 50 unsigned int NumItems;51 char *Filename;52 58 FILE *DataFile; 53 59 FILE *LogFile; 60 char *Filename; 54 61 float DataSizekB, LogSizekB; 55 62 int DataSizeLastUpdate, LogSizeLastUpdate; 56 63 char *DataDir; 57 64 DimService *LogSizeService, *DataSizeService, *DataFilename; 65 string HistDir; 58 66 int HistSize; 59 67 int SizeUpdateDelay; … … 66 74 void infoHandler(); 67 75 void commandHandler(); 68 void AddService( char *);76 void AddService(string); 69 77 float FileSize(FILE *); 70 78 … … 80 88 81 89 // Initialization to prevent freeing unallocated memory 82 Filename = NULL;83 90 DataFile = NULL; 84 91 LogFile = NULL; 85 List = NULL; 92 Filename = NULL; 93 86 94 LogSizeService = NULL; 87 95 DataSizeService = NULL; … … 93 101 // Request configuration data 94 102 char *Change = GetConfig(SERVER_NAME " minchange"); 103 95 104 DataDir = GetConfig(SERVER_NAME " datadir"); 105 96 106 char *Logname = GetConfig(SERVER_NAME " logfile"); 107 97 108 SizeUpdateDelay = atoi(GetConfig(SERVER_NAME " sizeupdate")); 109 98 110 HistSize = atoi(GetConfig(SERVER_NAME " histsize")); 99 111 if (HistSize < 1) HistSize = 1; // Minimum one items 112 113 HistDir = GetConfig(SERVER_NAME " histdir"); 100 114 101 115 // Open log file … … 148 162 149 163 // Subscribe to list of servers at DIS_DNS 150 AddService( (char *)"DIS_DNS/SERVER_LIST");164 AddService("DIS_DNS/SERVER_LIST"); 151 165 152 166 DimClient::sendCommand("DColl/Log", SERVER_NAME" *** Logging started ***"); … … 158 172 DataHandler::~DataHandler() { 159 173 160 // Delete DIM services and command first so handlers and not called anymore 161 for (int i=0; i<NumItems; i++) { 174 DimClient::sendCommand("DColl/Log", SERVER_NAME" *** Logging stopped ***"); 175 176 // Delete DIM subscriptions and command first so handlers and not called anymore 177 for (int i=0; i<List.size(); i++) { 178 delete List[i].DataItem; 179 } 180 delete LogCommand; 181 182 // Save history buffers to files (replace '/' by '_') 183 for (int i=0; i<List.size(); i++) { 184 string Name = List[i].HistService->getName(); 185 for (int j=0; j<Name.size(); j++) if (Name[j] == '/') Name[j] = '_'; 186 FILE *File = fopen((HistDir + "/" + Name).c_str(), "wb"); 187 if (File != NULL) { 188 fwrite(&List[i].HistPointer, sizeof(List[i].HistPointer), 1, File); 189 fwrite(List[i].HistBuffer, sizeof(EvidenceHistoryItem), HistSize, File); 190 fclose(File); 191 } 162 192 delete List[i].HistService; 163 delete List[i].DataItem;164 193 delete[] List[i].HistBuffer; 165 194 } 166 free(List);167 195 168 196 delete DataFilename; 197 delete[] Filename; 198 169 199 //delete LogSizeService; // These create segmentation faults?! 170 200 //delete DataSizeService; 171 172 delete LogCommand;173 free(Filename);174 201 175 202 // Close files … … 203 230 // If service is DIS_DNS/SERVER_LIST, subscribe to all SERVICE_LIST services 204 231 if (strcmp(Info->getName(), "DIS_DNS/SERVER_LIST") == 0) { 205 char *Token = strtok(Info->getString(), " +-!|@");232 char *Token = strtok(Info->getString(), "@"); 206 233 while (Token != NULL) { 207 char *Buf; 208 if (MakeString(&Buf, "%s/SERVICE_LIST", Token) != -1) { 209 AddService(Buf); 210 free(Buf); 211 } 212 else State(ERROR, "MakeString() failed for server %s", Token); 234 if (isalpha(*Token) == 0) Token++; // Name can start with +,-,! 213 235 214 Token = strtok(NULL, "|"); 215 Token = strtok(NULL, "+-!|@"); 236 AddService(string(Token)+"/SERVICE_LIST"); 237 238 Token = strtok(NULL, "|"); 239 Token = strtok(NULL, "|@"); // ???? Why needed ????? 216 240 } 217 241 return; … … 221 245 // Subscribe to all services (but not to commands and RPCs) 222 246 if (strstr(Info->getName(), "/SERVICE_LIST") != NULL) { 223 char *Name = strtok(Info->getString(), "+-!|"); 247 248 char *Name = strtok(Info->getString(), "|"); 224 249 while (Name != NULL) { 225 250 char *Type = strtok(NULL, "\n"); 226 251 if (Type == NULL) return; // for safety, should not happen 252 if (isalpha(*Name) == 0) Name++; // Name can start with +,-,! 227 253 if (strstr(Type, "|CMD")==NULL && strstr(Type, "|RPC")==NULL) { 228 254 AddService(Name); 229 255 } 230 Name = strtok(NULL, " +-!|");256 Name = strtok(NULL, "|"); 231 257 } 232 258 return; … … 245 271 time_t Time = time(NULL); 246 272 struct tm *T = localtime(&Time); 247 273 ostringstream Buf; 274 275 // Generate file name from date 248 276 if(T->tm_hour >= DATE_ROLLOVER) T->tm_mday++; 249 277 if (mktime(T) == -1) State(ERROR, "mktime() failed, check filename"); 250 251 free(Filename); 252 if (MakeString(&Filename, "%s/%d%02d%02d.slow", DataDir, T->tm_year+1900, T->tm_mon+1, T->tm_mday) == -1) State(FATAL, "Could not create filename, MakeString() failed"); 278 Buf << DataDir << "/" << T->tm_year+1900 << setw(2) << setfill('0') << T->tm_mon+1 << T->tm_mday << ".slow"; 279 280 // Copy filename to permanent buffer 281 delete[] Filename; 282 Filename = new char [Buf.str().size()+1]; 283 strcpy(Filename, Buf.str().c_str()); 284 285 // Open file 253 286 if ((DataFile = fopen(Filename, "a")) == NULL) { 254 287 State(FATAL, "Could not open data file '%s' (%s)", Filename, strerror(errno)); … … 266 299 // Identify index of service 267 300 int Service; 268 for (Service=0; Service< NumItems; Service++) if (Info == List[Service].DataItem) break;269 if (Service == NumItems) return; // Service not found301 for (Service=0; Service<List.size(); Service++) if (Info == List[Service].DataItem) break; 302 if (Service == List.size()) return; // Service not found 270 303 271 304 // If negative value for absolute change, ignore this entry … … 360 393 // Add service to watch list 361 394 // 362 void DataHandler::AddService( char *Name) {395 void DataHandler::AddService(string Name) { 363 396 364 397 // Do not subscribe to history services (otherwise infinite loop) 365 if ( strstr(Name, ".hist") != NULL) return;398 if (Name.find(".hist") != string::npos) return; 366 399 367 400 // Check if already subscribed to this service 368 for (int i=0; i<NumItems; i++) { 369 if(strcmp(Name, List[i].DataItem->getName()) == 0) return; 370 } 371 372 // Increase capacity of item list 373 struct Item *New = (struct Item *) realloc(List, (NumItems+1)*sizeof(struct Item)); 374 if (New != NULL) List = New; 375 else { 376 State(ERROR, "Could not allocate memory for item list, service '' not added (%s)", Name, strerror(errno)); 377 return; 378 } 379 401 for (int i=0; i<List.size(); i++) { 402 if (Name == List[i].DataItem->getName()) return; 403 } 404 405 // Create new entry in item list 406 struct Item New; 407 380 408 // Set minimum required change by comparing to regular expressions 381 List[NumItems].MinAbsChange = 0;409 New.MinAbsChange = 0; 382 410 for (int i=0; i<RegExCount; i++) { 383 if (regexec(&RegEx[i], Name, (size_t) 0, NULL, 0) == 0) { 384 List[NumItems].MinAbsChange = MinChange[i]; 385 } 386 } 387 388 List[NumItems].LastValue = DBL_MAX; 389 411 if (regexec(&RegEx[i], Name.c_str(), (size_t) 0, NULL, 0) == 0) { 412 New.MinAbsChange = MinChange[i]; 413 } 414 } 415 390 416 // Create history service 391 List[NumItems].HistBuffer = new struct EvidenceHistoryItem [HistSize]; 392 memset(List[NumItems].HistBuffer, 0, HistSize*sizeof(EvidenceHistoryItem)); 393 List[NumItems].HistPointer = 0; 394 395 char *Buf; 396 if (MakeString(&Buf, "%s.hist", Name) == -1) { 397 State(ERROR, "Could not create history service for '%s', MakeString() failed", Name); 398 } 399 else { 400 List[NumItems].HistService = new DimService (Buf, (char *) "C", 401 List[NumItems].HistBuffer, HistSize*sizeof(EvidenceHistoryItem)); 402 free(Buf); 403 } 404 417 New.HistBuffer = new struct EvidenceHistoryItem [HistSize]; 418 memset(New.HistBuffer, 0, HistSize*sizeof(EvidenceHistoryItem)); 419 New.HistPointer = 0; 420 New.LastValue = DBL_MAX; 421 New.HistService = new DimService ((Name+".hist").c_str(), (char *) "C", 422 New.HistBuffer, HistSize*sizeof(EvidenceHistoryItem)); 423 424 // Load history buffer from file if existing 425 string Filename = New.HistService->getName(); 426 for (int j=0; j<Filename.size(); j++) if (Filename[j] == '/') Filename[j] = '_'; 427 FILE *File = fopen((HistDir + "/" + Filename).c_str(), "rb"); 428 if (File != NULL) { 429 fread(&New.HistPointer, sizeof(New.HistPointer), 1, File); 430 fread(New.HistBuffer, sizeof(EvidenceHistoryItem), HistSize, File); 431 fclose(File); 432 } 433 405 434 // Subscribe to service 406 List[NumItems].DataItem = new DimStampedInfo(Name, NO_LINK, this);407 408 // Increase number only after all set-up409 NumItems++;435 New.DataItem = new DimStampedInfo(Name.c_str(), NO_LINK, this); 436 437 // Add item to list 438 List.push_back(New); 410 439 } 411 440 -
Evidence/Edd/Edd.cc
r151 r152 174 174 Grid->attach(this); 175 175 Legend = new QwtLegend(); 176 Legend->setItemMode(QwtLegend::ClickableItem); 176 177 insertLegend(Legend, QwtPlot::TopLegend); 177 178 179 connect(this, SIGNAL(legendClicked (QwtPlotItem *)), SLOT(LegendClicked(QwtPlotItem *))); 180 178 181 // Connect to DIM handler 179 182 if (connect(Handler, SIGNAL(YEP(DimInfo *, int, QString, QByteArray, QString)), SLOT(Update(DimInfo *, int, QString, QByteArray, QString))) == false) { … … 409 412 } 410 413 411 //412 414 // Opening context menu 413 //414 415 void Edd_Plot::contextMenuEvent(QContextMenuEvent *Event) { 415 416 … … 417 418 } 418 419 420 // Drag&Drop method 421 void Edd_Plot::LegendClicked(QwtPlotItem *Item) { 422 423 QDrag *Drag = new QDrag(this); 424 QMimeData *MimeData = new QMimeData; 425 MimeData->setText(Item->title().text().remove(".hist")); 426 Drag->setMimeData(MimeData); 427 Drag->exec(); 428 } 429 430 431 // Zoom completely out 419 432 void Edd_Plot::MenuZoomOut() { 420 433 … … 648 661 Graph = new Edd_Plot(); 649 662 for (int i=0; i<18; i++) { 650 Text = Text.sprintf("B IAS/VOLT/ID00/00-%.3d",i);663 Text = Text.sprintf("Bias/VOLT/ID00/00-%.3d",i); 651 664 Value = new Edd_Indicator(Text); 652 665 BiasLayout->addWidget(Value, i%9+1, 0+i/9, 1, 1); 653 666 Graph->AddService(Text); 654 667 655 Text = Text.sprintf("B IAS/VOLT/ID00/01-%.3d",i);668 Text = Text.sprintf("Bias/VOLT/ID00/01-%.3d",i); 656 669 Value = new Edd_Indicator(Text); 657 670 BiasLayout->addWidget(Value, i%9+1, 2+i/9, 1, 1); … … 660 673 661 674 BiasLayout->addWidget(Graph, 0, 4, 12, 3); 662 Value = new Edd_Indicator("B IAS/Status");675 Value = new Edd_Indicator("Bias/Status"); 663 676 Value->setMaximumWidth(200); 664 677 BiasLayout->addWidget(Value, 0, 0, 1, 3); 665 678 666 Textout = new Edd_Textout("B IAS/Textout");679 Textout = new Edd_Textout("Bias/Textout"); 667 680 Textout->setFixedWidth(400); 668 681 BiasLayout->addWidget(Textout, 10, 0, 4, 4); -
Evidence/Edd/Edd.h
r142 r152 96 96 97 97 void HandleZoom(const QwtDoubleRect &); 98 void contextMenuEvent(QContextMenuEvent *); 98 void contextMenuEvent(QContextMenuEvent *); 99 void LegendClicked(QwtPlotItem *); 99 100 void MenuZoomOut(); 100 101 void MenuSingleTrace(); -
Evidence/Evidence.cc
r144 r152 26 26 27 27 bool EvidenceServer::ExitRequest = false; 28 string __StatusName; 28 29 29 30 // Constructor starts server with given name … … 34 35 ConfigList = NULL; 35 36 ConfigNum = 0; 37 __StatusName = string(Name) + "/Status"; 36 38 37 39 // Catch some signals … … 41 43 signal(SIGHUP, &SignalHandler); // Terminal closed 42 44 43 // Create server name 44 if (MakeString(&StatusName, "%s/Status", Name) == -1) { 45 State(FATAL, "Could not generate service name, asprintf() failed"); 46 } 45 // Catch C++ unhandled exceptions 46 set_terminate(Terminate); 47 47 48 48 // Start server 49 Status = new DimService( StatusName, (char *) "Server started");49 Status = new DimService(__StatusName.c_str(), (char *) "Server started"); 50 50 51 51 start(Name); … … 56 56 EvidenceServer::~EvidenceServer() { 57 57 58 free(StatusName);59 60 58 for (unsigned int i=0; i<ConfigNum; i++) { 61 59 delete[] ConfigList[i].Name; … … 95 93 va_end(ArgumentPointer); 96 94 97 snprintf(TBuf, sizeof(TBuf), "%s (%s): %s", StatusName, StateString[Severity], Tmp); // Normal string95 snprintf(TBuf, sizeof(TBuf), "%s (%s): %s", __StatusName.c_str(), StateString[Severity], Tmp); // Normal string 98 96 snprintf(SBuf, sizeof(SBuf), "%s*%c", Tmp, (char) Severity); 99 97 *(strrchr(SBuf, '*')) = '\0'; // String with severity encoding … … 115 113 // The memory allocated by all calls to this function will be freed by 116 114 // the destructor. 117 char* EvidenceServer::GetConfig(const char *Item ) {115 char* EvidenceServer::GetConfig(const char *Item, const char *Default) { 118 116 119 117 // Determine configuration file update time … … 138 136 DimRpcInfo Config((char *) "ConfigRequest", (char *) ""); 139 137 Config.setData((char *) Item); 140 138 char *Result = Config.getString(); 139 141 140 // Terminate if not successful 142 if (strlen(Config.getString()) == 0) { 143 State(FATAL, "Missing configuration data '%s'", Item); 141 if (strlen(Result) == 0) { 142 if (Default == NULL) State(FATAL, "Missing configuration data '%s'", Item); 143 Result = (char *) Default; 144 144 } 145 145 … … 157 157 158 158 // Allocate memory for strings, and copy data to this memory 159 ConfigList[ItemNo].Value = new char [strlen( Config.getString())+1];159 ConfigList[ItemNo].Value = new char [strlen(Result)+1]; 160 160 ConfigList[ItemNo].Name = new char [strlen(Item)+1]; 161 161 strcpy(ConfigList[ItemNo].Name, Item); 162 strcpy(ConfigList[ItemNo].Value, Config.getString());162 strcpy(ConfigList[ItemNo].Value, Result); 163 163 164 164 ConfigList[ItemNo].Time = Time; … … 175 175 176 176 EvidenceServer::ExitRequest = true; 177 } 178 179 // C++ exception handler 180 void EvidenceServer::Terminate() { 181 182 string Msg = __StatusName + ": Caught unhandled exception"; 183 printf("%s\n", Msg.c_str()); 184 DimClient::sendCommand("DColl/Log", Msg.c_str()); 185 186 abort(); 177 187 } 178 188 … … 182 192 183 193 char *Text; 194 int R; 184 195 185 196 if (strlen(Item->getFormat()) != 1) return NULL; 186 197 187 198 switch (*(Item->getFormat())) { 188 case 'I': MakeString(&Text, "%d", Item->getInt()); break;189 case 'C': MakeString(&Text, "%s", Item->getString()); break;190 case 'S': MakeString(&Text, "%hd", Item->getShort()); break;191 case 'F': MakeString(&Text, "%.5f", Item->getFloat()); break;192 case 'D': MakeString(&Text, "%.5f", Item->getDouble()); break;193 case 'X': MakeString(&Text, "%lld", Item->getLonglong()); break;199 case 'I': R = asprintf(&Text, "%d", Item->getInt()); break; 200 case 'C': R = asprintf(&Text, "%s", Item->getString()); break; 201 case 'S': R = asprintf(&Text, "%hd", Item->getShort()); break; 202 case 'F': R = asprintf(&Text, "%.5f", Item->getFloat()); break; 203 case 'D': R = asprintf(&Text, "%.5f", Item->getDouble()); break; 204 case 'X': R = asprintf(&Text, "%lld", Item->getLonglong()); break; 194 205 default: return NULL; 195 206 } 196 207 197 return Text; 198 } 199 200 // 201 // Generate string with vasprintf() 202 // 203 // The pointer will be set to NULL in case of error, so can always safely passed to free(). 204 // In case vasprintf() is not available on a particular system, the functionality can 205 // be manually implemented in this routine. 206 // 207 int EvidenceServer::MakeString(char **Pointer, const char *Format, ...) { 208 209 int Ret; 210 va_list ArgumentPointer; 211 212 va_start(ArgumentPointer, Format); 213 if ((Ret = vasprintf(Pointer, Format, ArgumentPointer)) == -1) Pointer = NULL; 214 va_end(ArgumentPointer); 215 216 return Ret; 217 } 208 return (R == -1) ? NULL : Text; 209 } -
Evidence/Evidence.h
r142 r152 4 4 #include <stdio.h> 5 5 #include <stdarg.h> 6 #include <string> 6 7 #include <errno.h> 8 #include <exception> 7 9 8 10 #include "dis.hxx" … … 11 13 #define NO_LINK (char *) "__&DIM&NOLINK&__" // Data if no link available 12 14 #define STATUS_SIZE 1000 // Bytes for status service string 15 16 using namespace std; 13 17 14 18 // Declaration of item for history buffer (see DColl.cc) … … 29 33 unsigned int ConfigNum; 30 34 31 char *StatusName;32 35 DimService *Status; 33 36 34 static void SignalHandler(int); // static needed for signal() function 37 static void SignalHandler(int); // static for signal() 38 static void Terminate(); // static for set_terminate() 35 39 void errorHandler(int, int, char *); 36 40 void exitHandler(int); … … 43 47 44 48 void State(StateType, const char *, ...); 49 char* GetConfig(const char *, const char * = NULL); 50 static char* ToString(DimInfo *); 45 51 46 char* GetConfig(const char *);47 static char *ToString(DimInfo *);48 static int MakeString(char **Pointer, const char *Format, ...);49 50 52 static bool ExitRequest; 51 53 }; -
Evidence/Makefile
r144 r152 20 20 @rm -f $(PROG2) $(PROG2).o 21 21 @rm -f $(PROG3) $(PROG3).o 22 22 @rm -f Evidence.o
Note:
See TracChangeset
for help on using the changeset viewer.