Changeset 11219 for trunk/FACT++/src/datalogger.cc
- Timestamp:
- 06/30/11 14:01:39 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/datalogger.cc
r11218 r11219 63 63 64 64 #include <fstream> 65 #include <mutex>66 65 67 66 #include <boost/bind.hpp> … … 199 198 kSM_BadNightlyConfig = 0x101, ///< the folder specified for Nightly logging does not exist or has bad permissions 200 199 kSM_BadRunConfig = 0x102, ///< the folder specified for the run logging does not exist or has wrong permissions or no run number 201 kSM_WriteError = 0x103, ///< Denotes that an error occured while writing a file (text or fits). 200 kSM_RunWriteError = 0x103, ///< Denotes that an error occured while writing a run file (text or fits). 201 kSM_DailyWriteError = 0x103,///< Denots that an error occured while writing a daily file (text or fits). 202 202 } localstates_t; 203 203 … … 297 297 ///variables for computing statistics 298 298 DataLoggerStats fStatVar; 299 ///mutex to make sure that the Stats are not accessed while updating300 // mutex fStatsMutex;301 ///services notification thread302 // boost::thread fMonitoringThread;303 ///end of the monitoring304 // bool fContinueMonitoring;305 299 ///stores the size of each file that is or was open 306 300 map<string, long> fFileSizesMap; … … 353 347 ///add a new run number 354 348 void AddNewRunNumber(int64_t newRun, Time time); 349 std::vector<int64_t> previousRunNumbers; 355 350 ///removes the oldest run number, and close the relevant files. 356 351 void RemoveOldestRunNumber(); … … 380 375 bool RememberFileOrigSizePlease(string& fileName, bool nightly); 381 376 ///Checks if the input osftream is in error state, and if so close it. 382 bool CheckForOfstreamError(ofstream& out); 383 ///Goes to Write error state and also closes all opened files 384 void GoToWriteErrorState(); 377 bool CheckForOfstreamError(ofstream& out, bool isDailyStream); 378 ///Goes to Write error states 379 void GoToRunWriteErrorState(); 380 void GoToNightlyWriteErrorState(); 385 381 ///Checks if a given path exist 386 382 bool DoesPathExist(string path); … … 556 552 //! @param out the ofstream that should be checked 557 553 // 558 bool DataLogger::CheckForOfstreamError(ofstream& out )554 bool DataLogger::CheckForOfstreamError(ofstream& out, bool isDailyStream) 559 555 { 560 556 if (out.good()) … … 562 558 563 559 Error("An error occured while writing to a text file. Closing it"); 564 // if (out.is_open()) 565 // out.close(); 566 GoToWriteErrorState(); 560 if (out.is_open()) 561 out.close(); 562 if (isDailyStream) 563 GoToNightlyWriteErrorState(); 564 else 565 GoToRunWriteErrorState(); 567 566 568 567 return false; 569 // SetCurrentState(kSM_WriteError);570 568 } 571 569 // -------------------------------------------------------------------------- … … 700 698 // 701 699 //! Compiles a file name 700 //! @param run the run number 701 //! @param service the service name, if any 702 //! @param extension the extension to add, if any 703 // 704 string DataLogger::CompileFileName(const uint32_t run, const string& service, const string& extension) 705 { 706 ostringstream str; 707 //output base of file name 708 str << setfill('0') << setw(8) << run; 709 710 //output service name 711 if (!service.empty()) 712 str << "_" << service; 713 714 //output appropriate extension 715 if (!extension.empty()) 716 str << "." << extension; 717 return str.str(); 718 } 719 // -------------------------------------------------------------------------- 720 // 721 //! Compiles a file name withh path 702 722 //! @param path the base path where to put the file 703 723 //! @param time the time at which the file is created … … 706 726 //! @param extension the extension to add, if any 707 727 // 708 //string DataLogger::CompileFileName(const string &path, uint32_t run, const string &service, const string & extension, const Time &time)709 string DataLogger::CompileFileName(const uint32_t run, const string& service, const string& extension)//, const Time& time)710 {711 ostringstream str;712 //output base of file name713 str << setfill('0') << setw(8) << run;714 715 //output service name716 if (!service.empty())717 str << "_" << service;718 719 //output appropriate extension720 if (!extension.empty())721 str << "." << extension;722 return str.str();723 }724 725 728 string DataLogger::CompileFileNameWithPath(const string& path, const uint32_t run, const string& service, const string& extension, const Time& time) 726 729 { … … 783 786 { 784 787 y->second.runFile.Close(); 785 786 Info("Closed: "+y->second.runFile.fFileName);787 788 } 788 789 //if a grouping file is on, decrease the number of opened fits manually … … 802 803 bool DataLogger::calculateTotalSizeWritten(DataLoggerStats& statVar, bool isPrinting) 803 804 { 804 //mutex805 // if (!isPrinting)806 // fStatsMutex.lock();807 805 #ifdef HAVE_FITS 808 806 if (isPrinting) … … 872 870 statVar.sizeWritten -= fBaseSizeRun; 873 871 874 //mutex875 // if (!isPrinting)876 // fStatsMutex.unlock();877 878 872 return shouldWarn; 879 873 } 880 874 881 // --------------------------------------------------------------------------882 //883 //! Monitor the number of opened files and total size written, and distributes this data through a Dim service884 //885 //886 /*887 void DataLogger::ServicesMonitoring()888 {889 struct statvfs vfs;890 if (!statvfs(fNightlyFilePath.c_str(), &vfs))891 fStatVar.freeSpace = vfs.f_bsize*vfs.f_bavail;892 else893 fStatVar.freeSpace = -1;894 895 DimDescribedService srvc ("DATA_LOGGER/STATS", "X:3", fStatVar, "Add description here");896 fPreviousSize = 0;897 //loop-wait for broadcast898 while (fContinueMonitoring)899 {900 if (fStatsPeriodDuration == 0.0f)901 {902 sleep(0.1f);903 continue;904 }905 906 sleep(fStatsPeriodDuration);907 908 909 fStatsMutex.lock();910 911 if (fStatVar.writingRate != 0) //if data has been written912 {913 srvc.updateService();914 915 if(fDebugIsOn)916 {917 ostringstream str;918 str << "Size written: " << fStatVar.sizeWritten/1000 << " kB; writing rate: ";919 str << fStatVar.writingRate/1000 << " kB/s; free space: ";920 str << fStatVar.freeSpace/(1000*1000) << " MB";921 Debug(str);922 }923 }924 fStatsMutex.unlock();925 }926 }927 */928 875 // -------------------------------------------------------------------------- 929 876 // … … 945 892 AddStateName(kSM_BadNightlyConfig, "ErrNightlyFolder", "The folder for the nighly summary files is invalid."); 946 893 AddStateName(kSM_BadRunConfig, "ErrRunFolder", "The folder for the run files is invalid."); 947 AddStateName(kSM_WriteError, "ErrWrite", "An error occured while writing to a file."); 894 AddStateName(kSM_DailyWriteError, "ErrDailyWrite", "An error occured while writing to a daily (and run) file."); 895 AddStateName(kSM_RunWriteError, "ErrRunWrite", "An error occured while writing to a run file."); 948 896 949 897 // Add the possible transitions for this machine … … 952 900 ("Start the nightly logging. Nightly file location must be specified already"); 953 901 954 AddEvent(kSM_Ready, "STOP", kSM_NightlyOpen, kSM_WaitingRun, kSM_Logging, kSM_ WriteError)902 AddEvent(kSM_Ready, "STOP", kSM_NightlyOpen, kSM_WaitingRun, kSM_Logging, kSM_DailyWriteError, kSM_RunWriteError) 955 903 (boost::bind(&DataLogger::GoToReadyPlease, this)) 956 904 ("Stop all data logging, close all files."); … … 964 912 ("Wait for a run to be started, open run-files as soon as a run number arrives."); 965 913 966 AddEvent(kSM_Ready, "RESET", kSM_Error, kSM_BadNightlyConfig, kSM_BadRunConfig, kSM_ WriteError)914 AddEvent(kSM_Ready, "RESET", kSM_Error, kSM_BadNightlyConfig, kSM_BadRunConfig, kSM_DailyWriteError, kSM_RunWriteError) 967 915 (boost::bind(&DataLogger::GoToReadyPlease, this)) 968 916 ("Transition to exit error states. Closes the any open file."); … … 1020 968 1021 969 // provide services control commands 1022 AddEvent("SET_DE UG_MODE", "B:1", kSM_NightlyOpen, kSM_Logging, kSM_WaitingRun, kSM_Ready)970 AddEvent("SET_DEBUG_MODE", "B:1", kSM_NightlyOpen, kSM_Logging, kSM_WaitingRun, kSM_Ready) 1023 971 (boost::bind(&DataLogger::SetDebugOnOff, this, _1)) 1024 ("Switch debug mode on or off. Debug mode prints i fnormation about every service written to a file."972 ("Switch debug mode on or off. Debug mode prints information about every service written to a file." 1025 973 "|Enable[bool]:Enable of disable debug mode (yes/no)."); 1026 974 … … 1063 1011 fStatsMonitoring = new DimDescribedService(GetName() + "/STATS", "X:3", fStatVar, "Add description here"); 1064 1012 1065 //mutex1066 // fContinueMonitoring = true;1067 // fMonitoringThread = boost::thread(boost::bind(&DataLogger::ServicesMonitoring, this));1068 1013 fBaseSizeNightly = 0; 1069 1014 fBaseSizeRun = 0; … … 1089 1034 //first let's go to the ready state 1090 1035 GoToReadyPlease(); 1036 dim_lock(); 1091 1037 //release the services subscriptions 1092 1038 fServiceSubscriptions.clear(); 1093 //exit the monitoring loop 1094 //mutex 1095 // fContinueMonitoring = false; 1096 // fMonitoringThread.join(); 1039 1097 1040 //clear any remaining run number (should remain only one) 1098 1041 while (fRunNumber.size() > 0) 1099 1042 { 1100 1043 RemoveOldestRunNumber(); 1101 1044 } 1102 1045 dim_unlock(); 1103 1046 delete fOpenedNightlyFiles; 1104 1047 delete fOpenedRunFiles; … … 1169 1112 if (I==NULL) 1170 1113 return; 1114 1115 //it may happen that we try to write a dimInfo while closing files. Prevent that with a dim_lock() 1116 dim_lock(); 1117 1171 1118 //check if the service pointer corresponds to something that we subscribed to 1172 1119 //this is a fix for a bug that provides bad Infos when a server starts … … 1174 1121 SubscriptionsListType::iterator x; 1175 1122 map<string, SubscriptionType>::iterator y; 1176 1123 for (x=fServiceSubscriptions.begin(); x != fServiceSubscriptions.end(); x++) 1177 1124 {//find current service is subscriptions 1178 1125 for (y=x->second.begin(); y!=x->second.end();y++) … … 1188 1135 { 1189 1136 DimServiceInfoList::infoHandler(); 1137 dim_unlock(); 1190 1138 return; 1191 1139 } 1192 1140 if (I->getSize() <= 0 || I->getData()==NULL) 1141 { 1142 dim_unlock(); 1193 1143 return; 1194 1144 } 1195 1145 // Make sure that getTimestampMillisecs is NEVER called before 1196 1146 // getTimestamp is properly called 1197 1147 // check that the message has been updated by something, i.e. must be different from its initial value 1198 1148 if (I->getTimestamp() == 0) 1149 { 1150 dim_unlock(); 1199 1151 return; 1200 1152 } 1201 1153 // FIXME: Here we have to check if we have received the 1202 1154 // service with the run-number. … … 1207 1159 ReportPlease(I, y->second); 1208 1160 1161 dim_unlock(); 1209 1162 //update the fits files sizes 1210 1163 UpdateStatisticsService(); … … 1292 1245 return; 1293 1246 } 1247 for (std::vector<int64_t>::const_iterator it=previousRunNumbers.begin(); it != previousRunNumbers.end(); it++) 1248 { 1249 if (*it == newRun) 1250 { 1251 Error("Newly provided run number has already been used (or is still in use). Going to error state"); 1252 SetCurrentState(kSM_BadRunConfig); 1253 return; 1254 } 1255 } 1294 1256 if (fDebugIsOn) 1295 1257 { … … 1315 1277 { 1316 1278 if (it->reportFile->is_open()) 1279 { 1317 1280 it->reportFile->close(); 1281 Info("Closing: "+it->reportName); 1282 } 1318 1283 #ifdef RUN_LOGS 1319 1284 if (it->logFile->is_open()) 1285 { 1320 1286 it->logFile->close(); 1287 Info("Closing: "+it->logName); 1288 } 1321 1289 #endif 1322 1290 } … … 1496 1464 { 1497 1465 fNightlyReportFile << header.str() << text << endl; 1498 if (!CheckForOfstreamError(fNightlyReportFile ))1466 if (!CheckForOfstreamError(fNightlyReportFile, true)) 1499 1467 return; 1500 1468 } … … 1503 1471 { 1504 1472 *targetRunFile << header.str() << text << endl; 1505 if (!CheckForOfstreamError(*targetRunFile ))1473 if (!CheckForOfstreamError(*targetRunFile, false)) 1506 1474 return; 1507 1475 } … … 1515 1483 { 1516 1484 MessageImp(fNightlyLogFile).Write(cTime, msg.str().c_str(), fQuality); 1517 if (!CheckForOfstreamError(fNightlyLogFile ))1485 if (!CheckForOfstreamError(fNightlyLogFile, true)) 1518 1486 return; 1519 1487 } … … 1521 1489 { 1522 1490 MessageImp(*targetRunFile).Write(cTime, msg.str().c_str(), fQuality); 1523 if (!CheckForOfstreamError(*targetRunFile ))1491 if (!CheckForOfstreamError(*targetRunFile, false)) 1524 1492 return; 1525 1493 } … … 1788 1756 } 1789 1757 1758 // -------------------------------------------------------------------------- 1759 // 1760 //! Configure a given file name 1761 //! @param target 1762 //! where to put the result 1763 //! @param type 1764 //! what to append to the created path. currently only run or nightly 1765 //! @param evt 1766 //! the event transporting the path 1767 //! @returns 1768 //! currently only the current state. 1769 // 1790 1770 int DataLogger::ConfigureFileName(string &target, const string &type, const EventImp &evt) 1791 1771 { … … 1906 1886 { 1907 1887 fNightlyLogFile.close(); 1888 Info("Closed: "+fFullNightlyReportFileName); 1908 1889 return kSM_BadNightlyConfig; 1909 1890 } … … 1980 1961 if (!sub.nightlyFile.Open(partialName, serviceName, NULL, &fNumSubAndFitsData.numOpenFits, this, 0)) 1981 1962 { 1982 GoTo WriteErrorState();1963 GoToRunWriteErrorState(); 1983 1964 //SetCurrentState(kSM_WriteError); 1984 1965 return; … … 2026 2007 Error(str); 2027 2008 cRunNumber->runFitsFile = shared_ptr<CCfits::FITS>();//NULL; 2028 GoTo WriteErrorState();2009 GoToRunWriteErrorState(); 2029 2010 //SetCurrentState(kSM_WriteError); 2030 2011 return; … … 2042 2023 if (!sub.runFile.Open(partialName, serviceName, (cRunNumber->runFitsFile).get(), &fNumSubAndFitsData.numOpenFits, this, sub.runNumber)) 2043 2024 { 2044 GoTo WriteErrorState();2025 GoToRunWriteErrorState(); 2045 2026 //SetCurrentState(kSM_WriteError); 2046 2027 return; … … 2049 2030 else 2050 2031 { 2051 if ( sub.runFile.Open(partialName, serviceName, NULL, &fNumSubAndFitsData.numOpenFits, this, sub.runNumber))2032 if (!sub.runFile.Open(partialName, serviceName, NULL, &fNumSubAndFitsData.numOpenFits, this, sub.runNumber)) 2052 2033 { 2053 GoTo WriteErrorState();2034 GoToRunWriteErrorState(); 2054 2035 //SetCurrentState(kSM_WriteError); 2055 2036 return; … … 2096 2077 switch (flist[i].first.first->name()[0]) 2097 2078 { 2098 case 'c': dataQualifier << " B"; break; // FIXME: To be checked!2079 case 'c': dataQualifier << "S"; break; 2099 2080 case 's': dataQualifier << "I"; break; 2100 2081 case 'i': dataQualifier << "J"; break; … … 2128 2109 if (!sub.nightlyFile.Write(sub.fConv.get())) 2129 2110 { 2130 GoToWriteErrorState(); 2111 sub.nightlyFile.Close(); 2112 GoToNightlyWriteErrorState(); 2131 2113 return; 2132 2114 //SetCurrentState(kSM_WriteError); … … 2138 2120 if (!sub.runFile.Write(sub.fConv.get())) 2139 2121 { 2140 GoToWriteErrorState(); 2122 sub.runFile.Close(); 2123 GoToRunWriteErrorState(); 2141 2124 return; 2142 2125 //SetCurrentState(kSM_WriteError); … … 2145 2128 } 2146 2129 #endif //if has_fits 2147 2148 void DataLogger::GoToWriteErrorState() 2149 { 2150 GoToReadyPlease(); 2151 SetCurrentState(kSM_WriteError); 2152 } 2153 2130 // -------------------------------------------------------------------------- 2131 // 2132 //! Go to Run Write Error State 2133 // A write error has occurred. Checks what is the current state and take appropriate action 2134 void DataLogger::GoToRunWriteErrorState() 2135 { 2136 if ((GetCurrentState() != kSM_RunWriteError) && 2137 (GetCurrentState() != kSM_DailyWriteError)) 2138 SetCurrentState(kSM_RunWriteError); 2139 } 2140 // -------------------------------------------------------------------------- 2141 // 2142 //! Go to Nightly Write Error State 2143 // A write error has occurred. Checks what is the current state and take appropriate action 2144 void DataLogger::GoToNightlyWriteErrorState() 2145 { 2146 if (GetCurrentState() != kSM_DailyWriteError) 2147 SetCurrentState(kSM_DailyWriteError); 2148 } 2154 2149 std::string DataLogger::SetCurrentState(int state, const char *txt, const std::string &cmd) 2155 2150 { … … 2309 2304 str << "Writing FITS row " << i << " in " << groupName << ": " << text << " (file_write_tblbytes, rc=" << status << ")"; 2310 2305 Error(str); 2311 GoToWriteErrorState(); 2306 GoToRunWriteErrorState(); 2307 delete groupFile; 2312 2308 return; 2313 2309 } … … 2332 2328 Debug("Stopping Run Logging..."); 2333 2329 } 2330 //it may be that dim tries to write a dimInfo at the same time as we're closing files. Prevent this 2331 2332 dim_lock(); 2334 2333 for (list<RunNumberType>::const_iterator it=fRunNumber.begin(); it != fRunNumber.end(); it++) 2335 2334 { … … 2342 2341 #ifdef RUN_LOGS 2343 2342 it->logFile->close(); 2343 Info("Closed: "+it->logName); 2344 2344 2345 #endif 2345 2346 it->reportFile->close(); 2347 Info("Closed: "+it->reportName); 2346 2348 } 2347 2349 … … 2362 2364 RemoveOldestRunNumber(); 2363 2365 } 2364 2366 dim_unlock(); 2365 2367 return kSM_WaitingRun; 2366 2368 } … … 2379 2381 if (GetCurrentState() == kSM_Logging) 2380 2382 StopRunPlease(); 2381 2383 //it may be that dim tries to write a dimInfo while we're closing files. Prevent that 2384 dim_lock(); 2385 const string baseFileName = CompileFileNameWithPath(fNightlyFilePath, "", ""); 2382 2386 if (fNightlyLogFile.is_open()) 2387 { 2383 2388 fNightlyLogFile.close(); 2389 Info("Closed: "+baseFileName+".log"); 2390 } 2384 2391 if (fNightlyReportFile.is_open()) 2392 { 2385 2393 fNightlyReportFile.close(); 2386 2394 Info("Closed: "+baseFileName+".rep"); 2395 } 2387 2396 #ifdef HAVE_FITS 2388 2397 for (SubscriptionsListType::iterator i = fServiceSubscriptions.begin(); i != fServiceSubscriptions.end(); i++) … … 2390 2399 { 2391 2400 if (j->second.nightlyFile.IsOpen()) 2392 j->second.nightlyFile.Close(); ;2401 j->second.nightlyFile.Close(); 2393 2402 } 2394 2403 #endif … … 2404 2413 CreateFitsGrouping(fOpenedNightlyFits, 0); 2405 2414 #endif 2415 dim_unlock(); 2406 2416 return kSM_Ready; 2407 2417 }
Note:
See TracChangeset
for help on using the changeset viewer.