Changeset 159 for Evidence/DColl.cc
- Timestamp:
- 02/04/10 15:26:55 (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
Evidence/DColl.cc
r152 r159 38 38 #include <regex.h> 39 39 40 using namespace std; 41 40 42 // 41 43 // Class declaration … … 47 49 DimStampedInfo *DataItem; 48 50 DimService *HistService; 49 struct EvidenceHistoryItem *HistBuffer;50 int HistPointer;51 char *Buffer; 52 int Next; 51 53 double LastValue; 52 54 double MinAbsChange; … … 101 103 // Request configuration data 102 104 char *Change = GetConfig(SERVER_NAME " minchange"); 103 104 105 DataDir = GetConfig(SERVER_NAME " datadir"); 105 106 106 char *Logname = GetConfig(SERVER_NAME " logfile"); 107 108 107 SizeUpdateDelay = atoi(GetConfig(SERVER_NAME " sizeupdate")); 109 110 108 HistSize = atoi(GetConfig(SERVER_NAME " histsize")); 111 if (HistSize < 1) HistSize = 1; // Minimum one items 112 109 if (HistSize < 3*sizeof(int)) HistSize = 3*sizeof(int); 113 110 HistDir = GetConfig(SERVER_NAME " histdir"); 114 111 … … 163 160 // Subscribe to list of servers at DIS_DNS 164 161 AddService("DIS_DNS/SERVER_LIST"); 165 166 DimClient::sendCommand("DColl/Log", SERVER_NAME" *** Logging started ***");167 162 } 168 163 … … 171 166 // 172 167 DataHandler::~DataHandler() { 173 174 DimClient::sendCommand("DColl/Log", SERVER_NAME" *** Logging stopped ***");175 168 176 169 // Delete DIM subscriptions and command first so handlers and not called anymore … … 179 172 } 180 173 delete LogCommand; 181 174 182 175 // Save history buffers to files (replace '/' by '_') 176 State(INFO, "Writing history buffers to files"); 177 183 178 for (int i=0; i<List.size(); i++) { 184 179 string Name = List[i].HistService->getName(); … … 186 181 FILE *File = fopen((HistDir + "/" + Name).c_str(), "wb"); 187 182 if (File != NULL) { 188 fwrite(&List[i]. HistPointer, sizeof(List[i].HistPointer), 1, File);189 fwrite(List[i]. HistBuffer, sizeof(EvidenceHistoryItem), HistSize, File);183 fwrite(&List[i].Next, sizeof(List[i].Next), 1, File); 184 fwrite(List[i].Buffer, sizeof(char), HistSize, File); 190 185 fclose(File); 191 186 } 192 187 delete List[i].HistService; 193 delete[] List[i]. HistBuffer;188 delete[] List[i].Buffer; 194 189 } 195 190 … … 223 218 void DataHandler::infoHandler() { 224 219 220 static const int WrapMark[] = {0, -1}; 221 static const int EndMark[] = {0, 0}; 222 225 223 DimInfo *Info = getInfo(); 226 224 227 225 // Check if service available 228 if (Info->getSize()==strlen(NO_LINK)+1 && strcmp(Info->getString(), NO_LINK)==0) return; 229 226 if (!ServiceOK(Info)) return; 227 228 // 229 // ====== Part A: Handle service subscriptions === 230 // 231 230 232 // If service is DIS_DNS/SERVER_LIST, subscribe to all SERVICE_LIST services 231 233 if (strcmp(Info->getName(), "DIS_DNS/SERVER_LIST") == 0) { … … 259 261 } 260 262 263 // 264 // ====== Part B: Handle opening data files === 265 // 266 261 267 // If it is time to open new data file, close the current one 262 268 if (time(NULL) >= TimeForNextFile) { … … 296 302 TimeForNextFile = mktime(T); 297 303 } 298 304 305 // 306 // ====== Part C: Handle writing to data file === 307 // 308 299 309 // Identify index of service 300 int Service; 310 int Service; 301 311 for (Service=0; Service<List.size(); Service++) if (Info == List[Service].DataItem) break; 302 312 if (Service == List.size()) return; // Service not found 303 313 304 // If negative value for absolute change, ignore this entry305 if (List[Service].MinAbsChange < 0) return;314 // If negative value for absolute change, do not write to file 315 if (List[Service].MinAbsChange >= 0) { 306 316 307 317 // Write data header … … 313 323 // Translate data into ASCII 314 324 char *Text = EvidenceServer::ToString(Info); 325 315 326 if (Text != NULL) { 316 327 // Replace all control characters by white space … … 320 331 fprintf(DataFile, "%s\n", Text); 321 332 322 // Add to history buffer if change large enough323 if ((fabs(atof(Text)-List[Service].LastValue) > List[Service].MinAbsChange)) {324 List[Service].HistBuffer[List[Service].HistPointer].Seconds = Info->getTimestamp();325 List[Service].HistBuffer[List[Service].HistPointer].Value = atof(Text);326 List[Service].HistService->updateService();327 List[Service].HistPointer++;328 if (List[Service].HistPointer >= HistSize) List[Service].HistPointer = 0;329 List[Service].LastValue = atof(Text);330 }331 333 free(Text); 332 334 } 333 335 else fprintf(DataFile, "Cannot interpret format identifier\n"); 334 336 335 fflush(DataFile);336 337 337 // Terminate if error because otherwise infinite loop might result as 338 338 // next call to this infoHandler() will try to (re-)open file … … 343 343 } 344 344 345 // Update datafile size service 345 // Update datafile size service (not every time to avoid infinite loop) 346 346 if (time(NULL) - DataSizeLastUpdate > SizeUpdateDelay) { 347 fflush(DataFile); // not continuously to reduce load 348 347 349 DataSizekB = FileSize(DataFile); 348 350 DataSizeService->updateService(); 349 351 DataSizeLastUpdate = time(NULL); 350 352 } 353 354 } // Check for MinAbsChange 355 356 // 357 // ====== Part D: Handle history service === 358 // 359 360 if (Info->getSize() == 0) return; 361 362 // Check if data should be added to history buffer 363 char *Text = EvidenceServer::ToString(Info); 364 if (Text != NULL && strcmp(Info->getFormat(),"C") != 0 365 && fabs(atof(Text)-List[Service].LastValue) < fabs(List[Service].MinAbsChange)) { 366 free(Text); 367 return; 368 } 369 free(Text); 370 371 // Check if data fits into buffer 372 if (HistSize < Info->getSize() + 5*sizeof(int)) return; 373 374 int Size = Info->getSize() + 4*sizeof(int), Next = List[Service].Next; 375 void *WrapPos = NULL; 376 char *Buffer = List[Service].Buffer; 377 int Oldest = *(int *) Buffer; 378 379 // Check if buffer wrap-around (write wrap mark after Oldest is adjusted) 380 if (Next + Size >= HistSize) { 381 WrapPos = Buffer + Next; 382 Next = 4; 383 } 384 385 // Adapt pointer to oldest entry 386 while ((Oldest < Next + Size) && 387 (Oldest + *((int *) (Buffer + Oldest) + 1) + 2*sizeof(int) > Next)) { 388 // Check for wrap-around 389 if (memcmp(Buffer + Oldest, WrapMark, sizeof(WrapMark)) == 0) { 390 Oldest = 4; 391 continue; 392 } 393 // Check if end marker reached, then only one event fits buffer 394 if (memcmp(Buffer + Oldest, EndMark, sizeof(EndMark)) == 0) { 395 Oldest = Next; 396 break; 397 } 398 // Move to next entry 399 Oldest += *((int *) (Buffer + Oldest) + 1) + 2*sizeof(int); 400 } 401 // Update pointer in buffer 402 *(int *) Buffer = Oldest; 403 404 // Write wrap mark if necessary 405 if (WrapPos != NULL) memcpy(WrapPos, WrapMark, sizeof(WrapMark)); 406 407 // Copy data into ring buffer 408 *((int *) (Buffer + Next)) = Info->getTimestamp(); 409 *((int *) (Buffer + Next + sizeof(int))) = Info->getSize(); 410 memcpy(Buffer + Next + 2*sizeof(int), Info->getData(), Info->getSize()); 411 412 // Adjust pointer for next entry and write end marker to buffer 413 Next += Info->getSize() + 2*sizeof(int); 414 memcpy(Buffer + Next, EndMark, sizeof(EndMark)); 415 416 List[Service].Next = Next; 351 417 } 352 418 … … 403 469 } 404 470 405 // Create new entry in item list406 471 struct Item New; 407 472 … … 413 478 } 414 479 } 415 480 416 481 // Create history service 417 New.HistBuffer = new struct EvidenceHistoryItem [HistSize]; 418 memset(New.HistBuffer, 0, HistSize*sizeof(EvidenceHistoryItem)); 419 New.HistPointer = 0; 482 New.Buffer = new char [HistSize]; 483 memset(New.Buffer, 0, HistSize); 484 *(int *) New.Buffer = 4; 485 New.Next = 4; 420 486 New.LastValue = DBL_MAX; 421 487 New.HistService = new DimService ((Name+".hist").c_str(), (char *) "C", 422 New. HistBuffer, HistSize*sizeof(EvidenceHistoryItem));423 488 New.Buffer, HistSize); 489 424 490 // Load history buffer from file if existing 425 491 string Filename = New.HistService->getName(); … … 427 493 FILE *File = fopen((HistDir + "/" + Filename).c_str(), "rb"); 428 494 if (File != NULL) { 429 fread(&New.HistPointer, sizeof(New.HistPointer), 1, File); 430 fread(New.HistBuffer, sizeof(EvidenceHistoryItem), HistSize, File); 431 fclose(File); 495 // Only load if current buffer size if equal or larger 496 if (FileSize(File) <= HistSize*sizeof(char)+sizeof(New.Next) && FileSize(File) != -1) { 497 fread(&New.Next, sizeof(New.Next), 1, File); 498 fread(New.Buffer, sizeof(char), HistSize, File); 499 fclose(File); 500 } 432 501 } 433 502
Note:
See TracChangeset
for help on using the changeset viewer.