- Timestamp:
- 04/27/11 14:45:41 (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/dataLogger.cc
r10453 r10474 62 62 #include <sys/stat.h> 63 63 64 //#define HAS_FITS 64 #define HAS_FITS 65 //#define ONE_RUN_FITS_ONLY 65 66 66 67 #include <fstream> … … 70 71 71 72 #ifdef HAS_FITS 72 //#include <astroroot.h>73 73 #include "Fits.h" 74 74 #endif 75 76 //Dim structures 77 struct DataLoggerStats { 78 long long sizeWritten; 79 long long freeSpace; 80 long writingRate; 81 }; 82 83 struct NumSubAndFitsType { 84 int numSubscriptions; 85 int numOpenFits; 86 }; 75 87 76 88 class DataLogger : public StateMachineDim, DimInfoHandler … … 107 119 ///run number (-1 means no run number specified) 108 120 int fRunNumber; 109 ///Current year110 // short fYear;111 ///Current Month112 // short fMonth;113 ///Current Day114 // short fDay;115 ///Current Hour116 // short fHour;117 ///Current Minute118 // short fMin;119 ///Current Second120 // short fSec;121 ///Current Milliseconds122 // int fMs;123 121 ///Current Service Quality 124 122 int fQuality; … … 216 214 if (*numCopies < 1) 217 215 { 216 if (dimInfo) 217 delete dimInfo; 218 218 #ifdef HAS_FITS 219 219 if (dailyFile.IsOpen()) … … 222 222 runFile.Close(); 223 223 #endif 224 if (dimInfo)225 delete dimInfo;226 224 if (numCopies) 227 225 delete numCopies; … … 268 266 ///Allocate the buffers required for fits 269 267 void AllocateFITSBuffers(SubscriptionType& sub); 268 269 #ifdef ONE_RUN_FITS_ONLY 270 270 ///FITS file for runs. only one, hence dealt with in the dataLogger itself 271 271 FITS* fRunFitsFile; 272 #endif 272 #endif //one_run_fits_only 273 #endif//has_fits 273 274 public: 274 275 ///checks with fServiceList whether or not the services got updated 275 voidCheckForServicesUpdate();276 bool CheckForServicesUpdate(); 276 277 277 278 private: … … 292 293 long long fBaseSizeRun; 293 294 ///Service for opened files 294 DimService* fOpenedFiles; 295 char* fDimBuffer; 296 inline void NotifyOpenedFile(std::string name, int type); 295 DimService* fOpenedDailyFiles; 296 DimService* fOpenedRunFiles; 297 DimService* fNumSubAndFits; 298 NumSubAndFitsType fNumSubAndFitsData; 299 // char* fDimBuffer; 300 inline void NotifyOpenedFile(std::string name, int type, DimService* service); 297 301 298 302 }; //DataLogger … … 312 316 const char* DataLogger::fRunNumberInfo = "RUN_NUMBER"; 313 317 318 314 319 void DataLogger::ServicesMonitoring() 315 320 { 316 321 //create the DIM service 317 322 int dataSize = 2*sizeof(long long) + sizeof(long); 318 char* data = new char[dataSize]; 319 memset(data, 0, dataSize); 320 DimDescribedService srvc((GetName()+"/STATS").c_str(), "x:2;l:1", static_cast<void*>(data), dataSize, 321 "Add description here"); 323 324 DataLoggerStats statVar; 325 statVar.sizeWritten = 0; 326 statVar.freeSpace = 0; 327 statVar.writingRate = 0; 328 329 struct statvfs vfs; 330 if (!statvfs(fDailyFileName.c_str(), &vfs)) 331 statVar.freeSpace = vfs.f_bsize*vfs.f_bavail; 332 else 333 statVar.freeSpace = -1; 334 // DimDescribedService srvc((GetName()+"/STATS").c_str(), "x:2;l:1", &statVar, dataSize,//static_cast<void*>(data), dataSize, 335 // "Add description here"); 336 DimService srvc ("DATA_LOGGER/STATS", "x:2;l:1", &statVar, dataSize); 322 337 double deltaT = 1; 323 338 fPreviousSize = 0; 324 325 long long& targetSize = reinterpret_cast<long long*>(data)[0];326 long long& targetFreeSpace = reinterpret_cast<long long*>(data)[1];327 long& targetRate = reinterpret_cast<long*>(data + 2*sizeof(long long))[0];328 339 //loop-wait for broadcast 329 340 while (fContinueMonitoring) … … 371 382 fFileSizesMap[fFullRunReportFileName] = st.st_size; 372 383 } 373 if (fDailyLogFile.is_open()) 374 {375 st ruct statvfs vfs;376 statvfs(fDailyFileName.c_str(), &vfs);377 targetFreeSpace = vfs.f_bsize*vfs.f_bavail;378 }384 385 if (!statvfs(fDailyFileName.c_str(), &vfs)) 386 statVar.freeSpace = vfs.f_bsize*vfs.f_bavail; 387 else 388 statVar.freeSpace = -1; 389 379 390 //sum up all the file sizes. past and present 380 targetSize= 0;391 statVar.sizeWritten = 0; 381 392 for (std::map<std::string, long long>::iterator it=fFileSizesMap.begin(); it != fFileSizesMap.end(); it++) 382 targetSize+= it->second;383 targetSize-= fBaseSizeDaily;384 targetSize-= fBaseSizeRun;393 statVar.sizeWritten += it->second; 394 statVar.sizeWritten -= fBaseSizeDaily; 395 statVar.sizeWritten -= fBaseSizeRun; 385 396 //FIXME get the actual time elapsed 386 targetRate = (targetSize - fPreviousSize)/deltaT; 387 fPreviousSize = targetSize; 388 // if (targetRate != 0) //if data has been written 389 { 390 std::cout << "fBaseSizeDaily: " << fBaseSizeDaily << " fBaseSizeRun: " << fBaseSizeRun << std::endl; 391 //std::cout << "Written Size: " << targetSize << ", free space: " << targetFreeSpace << ", data rate: " << targetRate << " Bytes/s" << std::endl; 392 393 srvc.updateService(static_cast<void*>(data), dataSize); 397 statVar.writingRate = (statVar.sizeWritten - fPreviousSize)/deltaT; 398 fPreviousSize = statVar.sizeWritten; 399 if (statVar.writingRate != 0) //if data has been written 400 { 401 //std::cout << "rate: " << statVar.writingRate << std::endl; 402 srvc.updateService(&statVar, dataSize);//static_cast<void*>(data), dataSize); 394 403 } 395 404 } 396 delete[] data;397 405 } 398 406 … … 408 416 { 409 417 //initialize member data 410 fDailyFileName = " .";411 fRunFileName = " .";418 fDailyFileName = "/home/lyard/log";//"."; 419 fRunFileName = "/home/lyard/log";//"."; 412 420 fRunNumber = 12345; 413 421 #ifdef HAS_FITS 422 #ifdef ONE_RUN_FITS_ONLY 414 423 fRunFitsFile = NULL; 424 #endif 415 425 #endif 416 426 //Give a name to this machine's specific states … … 422 432 423 433 /*Add the possible transitions for this machine*/ 424 425 434 AddTransition(kSM_DailyOpen, fTransStart, kSM_Ready, kSM_BadDailyConfig) 426 (boost::bind(&DataLogger::StartPlease, this)) 427 ("start the daily logging. daily file location must be specified already");435 (boost::bind(&DataLogger::StartPlease, this)); 436 // ("start the daily logging. daily file location must be specified already"); 428 437 429 438 AddTransition(kSM_Ready, fTransStop, kSM_DailyOpen, kSM_WaitingRun, kSM_Logging) 430 (boost::bind(&DataLogger::GoToReadyPlease, this)) 431 439 (boost::bind(&DataLogger::GoToReadyPlease, this)); 440 // ("stop the data logging"); 432 441 433 442 AddTransition(kSM_Logging, fTransStartRun, kSM_WaitingRun, kSM_BadRunConfig) 434 (boost::bind(&DataLogger::StartRunPlease, this)) 435 ("start the run logging. run file location must be specified already.");443 (boost::bind(&DataLogger::StartRunPlease, this)); 444 // ("start the run logging. run file location must be specified already."); 436 445 437 446 AddTransition(kSM_WaitingRun, fTransStopRun, kSM_Logging) 438 (boost::bind(&DataLogger::StopRunPlease, this)) 439 ("");447 (boost::bind(&DataLogger::StopRunPlease, this)); 448 // (""); 440 449 441 450 AddTransition(kSM_Ready, fTransReset, kSM_Error, kSM_BadDailyConfig, kSM_BadRunConfig, kSM_Error) 442 (boost::bind(&DataLogger::GoToReadyPlease, this)) 443 ("transition to exit error states. dunno if required or not, would close the daily file if already openned.");451 (boost::bind(&DataLogger::GoToReadyPlease, this)); 452 // ("transition to exit error states. dunno if required or not, would close the daily file if already openned."); 444 453 445 454 AddTransition(kSM_WaitingRun, fTransWait, kSM_DailyOpen) … … 449 458 450 459 AddConfiguration(fConfigDay, "C", kSM_Ready, kSM_BadDailyConfig) 451 (boost::bind(&DataLogger::ConfigureDailyFileName, this, _1)) 452 ("configure the daily file location. cannot be done before the file is actually opened");460 (boost::bind(&DataLogger::ConfigureDailyFileName, this, _1));; 461 // ("configure the daily file location. cannot be done before the file is actually opened"); 453 462 454 463 AddConfiguration(fConfigRun, "C", kSM_Ready, kSM_BadDailyConfig, kSM_DailyOpen, kSM_WaitingRun, kSM_BadRunConfig) 455 (boost::bind(&DataLogger::ConfigureRunFileName, this, _1)) 456 ("configure the run file location. cannot be done before the file is actually opened, and not in a dailly related error.");464 (boost::bind(&DataLogger::ConfigureRunFileName, this, _1)); 465 // ("configure the run file location. cannot be done before the file is actually opened, and not in a dailly related error."); 457 466 458 467 //Provide a logging command … … 464 473 (boost::bind(&DataLogger::LogMessagePlease, this, _1)); 465 474 466 fServiceList.SetHandler(this);475 fServiceList.SetHandler(this); 467 476 CheckForServicesUpdate(); 468 477 … … 473 482 fBaseSizeRun = 0; 474 483 //start the open files service 475 fDimBuffer = new char[256]; 476 memset(fDimBuffer, 0, sizeof(int)); 477 fDimBuffer[sizeof(int)] = '\0'; 484 // fDimBuffer = new char[256]; 485 // memset(fDimBuffer, 0, sizeof(int)); 486 // fDimBuffer[sizeof(int)] = '\0'; 487 478 488 //gives the entire buffer size. Otherwise, dim overwrites memory at bizarre locations if smaller size is given at creation time. 479 fOpenedFiles = new DimDescribedService((GetName()+"/FILENAME").c_str(), "i:1;C", static_cast<void*>(fDimBuffer), 256, 480 "Add description here"); 481 482 489 // fOpenedFiles = new DimDescribedService((GetName()+"/FILENAME").c_str(), "i:1;C", static_cast<void*>(fDimBuffer), 256, "Add description here"); 490 fOpenedDailyFiles = new DimService((GetName() + "/FILENAME_DAILY").c_str(), const_cast<char*>(""));//"i:1;C", static_cast<void*>(fDimBuffer), 256); 491 fOpenedRunFiles = new DimService((GetName() + "/FILENAME_RUN").c_str(), const_cast<char*>("")); 492 fOpenedDailyFiles->setQuality(0); 493 fOpenedRunFiles->setQuality(0); 494 fOpenedDailyFiles->updateService(); 495 fOpenedRunFiles->updateService(); 496 fNumSubAndFitsData.numSubscriptions = 0; 497 fNumSubAndFitsData.numOpenFits = 0; 498 fNumSubAndFits = new DimService((GetName() + "/NUM_SUBS").c_str(), "i:2", &fNumSubAndFitsData, sizeof(NumSubAndFitsType)); 499 483 500 } 484 501 // -------------------------------------------------------------------------- … … 490 507 // 491 508 //FIXME The service must be udpated so that I get the first notification. This should not be 492 voidDataLogger::CheckForServicesUpdate()509 bool DataLogger::CheckForServicesUpdate() 493 510 { 494 511 bool serviceUpdated = false; 495 512 //get the current server list 496 513 const std::vector<std::string> serverList = fServiceList.GetServerList(); … … 505 522 break; 506 523 if (givenServers == serverList.end())//server vanished. Remove it 524 { 507 525 toBeDeleted.push_back(cListe->first); 526 serviceUpdated = true; 527 } 528 508 529 } 509 530 for (std::vector<std::string>::const_iterator it = toBeDeleted.begin(); it != toBeDeleted.end(); it++) 510 531 fServiceSubscriptions.erase(*it); 511 512 532 //now crawl through the list of servers, and see if there was some updates 513 533 for (std::vector<std::string>::const_iterator i=serverList.begin(); i!=serverList.end();i++) … … 535 555 { 536 556 toBeDeleted.push_back(serverSubs->first); 557 serviceUpdated = true; 537 558 } 538 559 } … … 547 568 {//service not found. Add it 548 569 cSubs->second[*givenSubs].dimInfo = new DimStampedInfo(((*i) + "/" + *givenSubs).c_str(), const_cast<char*>(""), this); 570 serviceUpdated = true; 549 571 } 550 572 } … … 559 581 continue; 560 582 liste[*j].dimInfo = new DimStampedInfo(((*i) + "/" + (*j)).c_str(), const_cast<char*>(""), this); 583 serviceUpdated = true; 561 584 } 562 585 } 563 586 } 587 return serviceUpdated; 564 588 } 565 589 // -------------------------------------------------------------------------- … … 569 593 DataLogger::~DataLogger() 570 594 { 595 //release the services subscriptions 596 fServiceSubscriptions.clear(); 571 597 //exit the monitoring loop 572 598 fContinueMonitoring = false; 573 delete[] fDimBuffer; 574 delete fOpenedFiles; 599 // delete[] fDimBuffer; 575 600 fMonitoringThread.join(); 576 601 //close the files … … 583 608 if (fRunReportFile.is_open()) 584 609 fRunReportFile.close(); 585 //release the services subscriptions 586 fServiceSubscriptions.clear(); 610 delete fOpenedDailyFiles; 611 delete fOpenedRunFiles; 612 delete fNumSubAndFits; 613 //TODO notify that all files were closed 587 614 #ifdef HAS_FITS 615 #ifdef ONE_RUN_FITS_ONLY 588 616 if (fRunFitsFile != NULL) 589 617 delete fRunFitsFile; 590 618 fRunFitsFile = NULL; 619 #endif 591 620 #endif 592 621 } … … 719 748 { 720 749 DimInfo* I = getInfo(); 750 SubscriptionsListType::iterator x; 751 std::map<std::string, SubscriptionType>::iterator y; 721 752 if (I==NULL) 722 753 { 723 CheckForServicesUpdate(); 754 if (CheckForServicesUpdate()) 755 { 756 //services were updated. Notify 757 fNumSubAndFitsData.numSubscriptions = 0; 758 for (x=fServiceSubscriptions.begin(); x != fServiceSubscriptions.end(); x++) 759 fNumSubAndFitsData.numSubscriptions += x->second.size(); 760 fNumSubAndFits->updateService(); 761 } 724 762 return; 725 763 } … … 727 765 //this is a fix for a bug that provides bad Infos when a server starts 728 766 bool found = false; 729 SubscriptionsListType::iterator x;730 std::map<std::string, SubscriptionType>::iterator y;731 767 for (x=fServiceSubscriptions.begin(); x != fServiceSubscriptions.end(); x++) 732 768 {//find current service is subscriptions … … 933 969 int DataLogger::ConfigureDailyFileName(const Event& evt) 934 970 { 971 std::cout << "Configure Daily File Name" << std::endl; 935 972 if (evt.GetText() != NULL) 936 973 fDailyFileName = std::string(evt.GetText()); … … 949 986 int DataLogger::ConfigureRunFileName(const Event& evt) 950 987 { 988 std::cout << "Configure Run File Name" << std::endl; 951 989 if (evt.GetText() != NULL) 952 990 fRunFileName = std::string(evt.GetText()); … … 976 1014 //! this is not a problem though because file are not opened so often. 977 1015 //! @ param type the type of the opened file. 0 = none open, 1 = log, 2 = text, 4 = fits 978 inline void DataLogger::NotifyOpenedFile(std::string name, int type )1016 inline void DataLogger::NotifyOpenedFile(std::string name, int type, DimService* service) 979 1017 { 980 1018 //std::cout << "name: " << name << " size: " << name.size() << std::endl; 981 reinterpret_cast<int*>(fDimBuffer)[0] = type; 982 strcpy(&fDimBuffer[sizeof(int)], name.c_str()); 983 fOpenedFiles->updateService(static_cast<void*>(fDimBuffer), name.size() + 1 + sizeof(int)); 1019 // reinterpret_cast<int*>(fDimBuffer)[0] = type; 1020 // strcpy(&fDimBuffer[sizeof(int)], name.c_str()); 1021 service->setQuality(type); 1022 service->updateService(const_cast<char*>(name.c_str())); 1023 // fOpenedFiles->updateService(static_cast<void*>(fDimBuffer), name.size() + 1 + sizeof(int)); 984 1024 } 985 1025 // -------------------------------------------------------------------------- … … 1017 1057 fPreviousSize = 0; 1018 1058 //notify that files were opened 1019 NotifyOpenedFile(sTime.str(), 3); 1059 std::string actualTargetDir; 1060 if (fDailyFileName == ".") 1061 { 1062 char currentPath[FILENAME_MAX]; 1063 getcwd(currentPath, sizeof(currentPath)); 1064 actualTargetDir = currentPath; 1065 } 1066 else 1067 { 1068 actualTargetDir = fDailyFileName; 1069 } 1070 std::cout << actualTargetDir << '/' << sTime.str() << std::endl; 1071 NotifyOpenedFile(actualTargetDir + '/' + sTime.str(), 3, fOpenedDailyFiles); 1020 1072 1021 1073 … … 1056 1108 fFileSizesMap[partialName] = 0; 1057 1109 } 1058 sub.dailyFile.Open(partialName, serviceName, NULL );1110 sub.dailyFile.Open(partialName, serviceName, NULL, &fNumSubAndFitsData.numOpenFits); 1059 1111 //notify the opening 1060 NotifyOpenedFile(sTime.str() + '_' + serviceName, 4); 1061 1112 std::string actualTargetDir; 1113 if (fDailyFileName == ".") 1114 { 1115 char currentPath[FILENAME_MAX]; 1116 getcwd(currentPath, sizeof(currentPath)); 1117 actualTargetDir = currentPath; 1118 } 1119 else 1120 { 1121 actualTargetDir = fDailyFileName; 1122 } 1123 NotifyOpenedFile(actualTargetDir + '/' + sTime.str(), 4, fOpenedDailyFiles); 1124 fNumSubAndFits->updateService(); 1062 1125 } 1063 1126 if (!sub.runFile.IsOpen() && (GetCurrentState() == kSM_Logging)) … … 1065 1128 std::stringstream sRun; 1066 1129 sRun << fRunNumber; 1130 #ifdef ONE_RUN_FITS_ONLY 1067 1131 std::string partialName = fRunFileName + '/' + sRun.str() + ".fits";//'_' + serviceName + ".fits"; 1068 1132 if (fRunFitsFile == NULL) 1069 1133 { 1134 #else 1135 std::string partialName = fRunFileName + '/' + sRun.str() + '_' + serviceName + ".fits"; 1136 #endif 1070 1137 //get the size of the file we're about to open 1071 1138 if (fFileSizesMap.find(partialName) == fFileSizesMap.end()) … … 1078 1145 fFileSizesMap[partialName] = 0; 1079 1146 } 1147 #ifdef ONE_RUN_FITS_ONLY 1080 1148 try 1081 1149 { 1082 1150 fRunFitsFile = new FITS(partialName, RWmode::Write); 1151 (fNumSubAndFitsData.numOpenFits)++; 1083 1152 } 1084 1153 catch (CCfits::FitsError e) … … 1088 1157 throw runtime_error(err.str()); 1089 1158 } 1090 NotifyOpenedFile(sRun.str(), 4);// + '_' + serviceName, 4); 1159 #endif 1160 std::string actualTargetDir; 1161 if (fRunFileName == ".") 1162 { 1163 char currentPath[FILENAME_MAX]; 1164 getcwd(currentPath, sizeof(currentPath)); 1165 actualTargetDir = currentPath; 1166 } 1167 else 1168 { 1169 actualTargetDir = fRunFileName; 1170 } 1171 NotifyOpenedFile(actualTargetDir + '/' + sRun.str(), 4, fOpenedRunFiles);// + '_' + serviceName, 4); 1172 #ifdef ONE_RUN_FITS_ONLY 1091 1173 } 1092 sub.runFile.Open(partialName, serviceName, fRunFitsFile); 1174 sub.runFile.Open(partialName, serviceName, fRunFitsFile, &fNumSubAndFitsData.numOpenFits); 1175 #else 1176 sub.runFile.Open(partialName, serviceName, NULL, &fNumSubAndFitsData.numOpenFits); 1177 #endif //one_run_fits_only 1178 fNumSubAndFits->updateService(); 1179 1093 1180 } 1094 1181 } … … 1218 1305 fFileSizesMap[fFullRunReportFileName] = 0; 1219 1306 } 1220 NotifyOpenedFile(sRun.str(), 3); 1307 std::string actualTargetDir; 1308 if (fRunFileName == ".") 1309 { 1310 char currentPath[FILENAME_MAX]; 1311 getcwd(currentPath, sizeof(currentPath)); 1312 actualTargetDir = currentPath; 1313 } 1314 else 1315 { 1316 actualTargetDir = fRunFileName; 1317 } 1318 NotifyOpenedFile(actualTargetDir + '/' + sRun.str(), 3, fOpenedRunFiles); 1221 1319 1222 1320 return kSM_Logging; … … 1242 1340 j->second.runFile.Close(); 1243 1341 } 1342 #ifdef ONE_RUN_FITS_ONLY 1244 1343 if (fRunFitsFile != NULL) 1245 1344 { 1246 1345 delete fRunFitsFile; 1247 1346 fRunFitsFile = NULL; 1248 } 1249 #endif 1347 std::cout << "FNumSub2: " << fNumSubAndFitsData.numOpenFits << std::endl; 1348 (fNumSubAndFitsData.numOpenFits)--; 1349 std::cout << "FNumSub3: " << fNumSubAndFitsData.numOpenFits << std::endl; 1350 } 1351 #endif 1352 #endif 1353 NotifyOpenedFile("None", 0, fOpenedRunFiles); 1354 fNumSubAndFits->updateService(); 1250 1355 return kSM_WaitingRun; 1251 1356 … … 1278 1383 j->second.runFile.Close(); 1279 1384 } 1385 #ifdef ONE_RUN_FITS_ONLY 1280 1386 if (fRunFitsFile != NULL) 1281 1387 { 1282 1388 delete fRunFitsFile; 1283 fRunFitsFile = NULL; 1284 } 1285 #endif 1389 fRunFitsFile = NULL; 1390 (fNumSubAndFitsData.numOpenFits)--; 1391 } 1392 #endif 1393 #endif 1394 if (GetCurrentState() == kSM_Logging) 1395 NotifyOpenedFile("None", 0, fOpenedRunFiles); 1396 if (GetCurrentState() == kSM_Logging || 1397 GetCurrentState() == kSM_WaitingRun || 1398 GetCurrentState() == kSM_DailyOpen) 1399 { 1400 NotifyOpenedFile("None", 0, fOpenedDailyFiles); 1401 fNumSubAndFits->updateService(); 1402 } 1286 1403 return kSM_Ready; 1287 1404 } … … 1333 1450 1334 1451 logger.SetReady(); 1335 // logger.StartPlease(); 1452 1336 1453 shell.Run(); // Run the shell 1337 1454 logger.SetNotReady();
Note:
See TracChangeset
for help on using the changeset viewer.