Changeset 10442 for trunk/FACT++/src/dataLogger.cc
- Timestamp:
- 04/21/11 12:27:37 (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/dataLogger.cc
r10421 r10442 54 54 #include "Description.h" 55 55 56 #define HAS_FITS 56 //for getting stat of opened files 57 #include <unistd.h> 58 //for getting disk free space 59 #include <sys/statvfs.h> 60 //for getting files sizes 61 #include <sys/stat.h> 62 63 //#define HAS_FITS 57 64 58 65 #include <fstream> 59 66 60 67 #include <boost/bind.hpp> 68 #include <boost/thread.hpp> 61 69 62 70 #ifdef HAS_FITS … … 259 267 ///Allocate the buffers required for fits 260 268 void AllocateFITSBuffers(SubscriptionType& sub); 269 ///FITS file for runs. only one, hence dealt with in the dataLogger itself 270 FITS* fRunFitsFile; 261 271 #endif 262 272 public: 263 273 ///checks with fServiceList whether or not the services got updated 264 274 void CheckForServicesUpdate(); 275 276 private: 277 ///monitoring notification loop 278 void ServicesMonitoring(); 279 ///services notification thread 280 boost::thread fMonitoringThread; 281 ///end of the monitoring 282 bool fContinueMonitoring; 283 ///required for accurate monitoring 284 std::map<std::string, long long> fFileSizesMap; 285 std::string fFullDailyLogFileName; 286 std::string fFullDailyReportFileName; 287 std::string fFullRunLogFileName; 288 std::string fFullRunReportFileName; 289 long long fBaseSizeDaily; 290 long long fPreviousSize; 291 long long fBaseSizeRun; 292 ///Service for opened files 293 DimService* fOpenedFiles; 294 char* fDimBuffer; 295 inline void NotifyOpenedFile(std::string name, int type); 265 296 266 297 }; //DataLogger … … 280 311 const char* DataLogger::fRunNumberInfo = "RUN_NUMBER"; 281 312 313 void DataLogger::ServicesMonitoring() 314 { 315 //create the DIM service 316 int dataSize = 2*sizeof(long long) + sizeof(long); 317 char* data = new char[dataSize]; 318 memset(data, 0, dataSize); 319 DimService srvc("DATALOGGER/STATS", "x:2;l:1", static_cast<void*>(data), dataSize); 320 double deltaT = 1; 321 fPreviousSize = 0; 322 323 long long& targetSize = reinterpret_cast<long long*>(data)[0]; 324 long long& targetFreeSpace = reinterpret_cast<long long*>(data)[1]; 325 long& targetRate = reinterpret_cast<long*>(data + 2*sizeof(long long))[0]; 326 //loop-wait for broadcast 327 while (fContinueMonitoring) 328 { 329 sleep(deltaT); 330 //update the fits files sizes 331 #ifdef HAS_FITS 332 SubscriptionsListType::iterator x; 333 std::map<std::string, SubscriptionType>::iterator y; 334 bool runFileDone = false; 335 for (x=fServiceSubscriptions.begin(); x != fServiceSubscriptions.end(); x++) 336 { 337 for (y=x->second.begin(); y != x->second.end(); y++) 338 { 339 if (y->second.runFile.IsOpen() && !runFileDone) 340 { 341 fFileSizesMap[y->second.runFile.fFileName] = y->second.runFile.GetWrittenSize(); 342 runFileDone = true; 343 } 344 if (y->second.dailyFile.IsOpen()) 345 fFileSizesMap[y->second.dailyFile.fFileName] = y->second.dailyFile.GetWrittenSize(); 346 } 347 } 348 #endif 349 struct stat st; 350 //gather log and report files sizes on disk 351 if (fDailyLogFile.is_open()) 352 { 353 stat(fFullDailyLogFileName.c_str(), &st); 354 fFileSizesMap[fFullDailyLogFileName] = st.st_size; 355 } 356 if (fDailyReportFile.is_open()) 357 { 358 stat(fFullDailyReportFileName.c_str(), &st); 359 fFileSizesMap[fFullDailyReportFileName] = st.st_size; 360 } 361 if (fRunLogFile.is_open()) 362 { 363 stat(fFullRunLogFileName.c_str(), &st); 364 fFileSizesMap[fFullRunLogFileName] = st.st_size; 365 } 366 if (fRunReportFile.is_open()) 367 { 368 stat(fFullRunReportFileName.c_str(), &st); 369 fFileSizesMap[fFullRunReportFileName] = st.st_size; 370 } 371 if (fDailyLogFile.is_open()) 372 { 373 struct statvfs vfs; 374 statvfs(fDailyFileName.c_str(), &vfs); 375 targetFreeSpace = vfs.f_bsize*vfs.f_bavail; 376 } 377 //sum up all the file sizes. past and present 378 targetSize = 0; 379 for (std::map<std::string, long long>::iterator it=fFileSizesMap.begin(); it != fFileSizesMap.end(); it++) 380 targetSize += it->second; 381 targetSize -= fBaseSizeDaily; 382 targetSize -= fBaseSizeRun; 383 //FIXME get the actual time elapsed 384 targetRate = (targetSize - fPreviousSize)/deltaT; 385 fPreviousSize = targetSize; 386 if (targetRate != 0) //if data has been written 387 { 388 std::cout << "fBaseSizeDaily: " << fBaseSizeDaily << " fBaseSizeRun: " << fBaseSizeRun << std::endl; 389 //std::cout << "Written Size: " << targetSize << ", free space: " << targetFreeSpace << ", data rate: " << targetRate << " Bytes/s" << std::endl; 390 391 srvc.updateService(static_cast<void*>(data), dataSize); 392 } 393 } 394 delete[] data; 395 } 396 397 282 398 // -------------------------------------------------------------------------- 283 399 // … … 293 409 fRunFileName = "/home/lyard/log"; 294 410 fRunNumber = 12345; 411 #ifdef HAS_FITS 412 fRunFitsFile = NULL; 413 #endif 295 414 //Give a name to this machine's specific states 296 415 AddStateName(kSM_DailyOpen, "DailyFileOpen"); … … 344 463 fServiceList.SetHandler(this); 345 464 CheckForServicesUpdate(); 465 466 //start the monitoring service 467 fContinueMonitoring = true; 468 fMonitoringThread = boost::thread(boost::bind(&DataLogger::ServicesMonitoring, this)); 469 fBaseSizeDaily = 0; 470 fBaseSizeRun = 0; 471 //start the open files service 472 fDimBuffer = new char[256]; 473 memset(fDimBuffer, 0, sizeof(int)); 474 fDimBuffer[sizeof(int)] = '\0'; 475 //gives the entire buffer size. Otherwise, dim overwrites memory at bizarre locations if smaller size is given at creation time. 476 fOpenedFiles = new DimService("DATALOGGER/FILENAME", "i:1;C", static_cast<void*>(fDimBuffer), 256); 477 346 478 347 479 } … … 433 565 DataLogger::~DataLogger() 434 566 { 567 //exit the monitoring loop 568 fContinueMonitoring = false; 569 delete[] fDimBuffer; 570 delete fOpenedFiles; 571 fMonitoringThread.join(); 435 572 //close the files 436 573 if (fDailyLogFile.is_open()) … … 444 581 //release the services subscriptions 445 582 fServiceSubscriptions.clear(); 583 #ifdef HAS_FITS 584 if (fRunFitsFile != NULL) 585 delete fRunFitsFile; 586 fRunFitsFile = NULL; 587 #endif 446 588 } 447 589 // -------------------------------------------------------------------------- … … 602 744 CheckForRunNumber(I); 603 745 ReportPlease(I, y->second); 746 604 747 } 605 748 … … 613 756 void DataLogger::CheckForRunNumber(DimInfo* I) 614 757 { 615 return;616 758 if (strstr(I->getName(), fRunNumberInfo) != NULL) 617 759 {//assumes that the run number is an integer … … 822 964 // -------------------------------------------------------------------------- 823 965 // 966 //! Notifies the DIM service that a particular file was opened 967 //! @ param name the base name of the opened file, i.e. without path nor extension. 968 //! WARNING: use string instead of string& because I pass values that do not convert to string&. 969 //! this is not a problem though because file are not opened so often. 970 //! @ param type the type of the opened file. 0 = none open, 1 = log, 2 = text, 4 = fits 971 inline void DataLogger::NotifyOpenedFile(std::string name, int type) 972 { 973 //std::cout << "name: " << name << " size: " << name.size() << std::endl; 974 reinterpret_cast<int*>(fDimBuffer)[0] = type; 975 strcpy(&fDimBuffer[sizeof(int)], name.c_str()); 976 fOpenedFiles->updateService(static_cast<void*>(fDimBuffer), name.size() + 1 + sizeof(int)); 977 } 978 // -------------------------------------------------------------------------- 979 // 824 980 //! Implements the Start transition. 825 981 //! Concatenates the given path for the daily file and the filename itself (based on the day), … … 833 989 std::stringstream sTime; 834 990 sTime << time.Y() << "_" << time.M() << "_" << time.D(); 835 std::string fullName = fDailyFileName + '/' + sTime.str() + ".log";836 837 fDailyLogFile.open(f ullName.c_str(), std::ios_base::out | std::ios_base::app); //maybe should be "app" instead of "ate" ??838 f ullName = fDailyFileName + '/' + sTime.str() + ".rep";839 fDailyReportFile.open(f ullName.c_str(), std::ios_base::out | std::ios_base::app);991 fFullDailyLogFileName = fDailyFileName + '/' + sTime.str() + ".log"; 992 993 fDailyLogFile.open(fFullDailyLogFileName.c_str(), std::ios_base::out | std::ios_base::app); //maybe should be "app" instead of "ate" ?? 994 fFullDailyReportFileName = fDailyFileName + '/' + sTime.str() + ".rep"; 995 fDailyReportFile.open(fFullDailyReportFileName.c_str(), std::ios_base::out | std::ios_base::app); 840 996 841 997 if (!fDailyLogFile.is_open() || !fDailyReportFile.is_open()) … … 844 1000 return kSM_BadDailyConfig; 845 1001 } 846 1002 //get the size of the newly opened file. 1003 struct stat st; 1004 stat(fFullDailyLogFileName.c_str(), &st); 1005 fBaseSizeDaily = st.st_size; 1006 stat(fFullDailyReportFileName.c_str(), &st); 1007 fBaseSizeDaily += st.st_size; 1008 fFileSizesMap.clear(); 1009 fBaseSizeRun = 0; 1010 fPreviousSize = 0; 1011 //notify that files were opened 1012 NotifyOpenedFile(sTime.str(), 3); 1013 1014 847 1015 return kSM_DailyOpen; 848 1016 } … … 873 1041 std::string partialName = fDailyFileName + '/' + sTime.str() + '_' + serviceName + ".fits"; 874 1042 AllocateFITSBuffers(sub); 875 sub.dailyFile.Open(partialName, serviceName); 1043 //get the size of the file we're about to open 1044 if (fFileSizesMap.find(partialName) == fFileSizesMap.end()) 1045 { 1046 struct stat st; 1047 if (!stat(partialName.c_str(), &st)) 1048 fBaseSizeDaily += st.st_size; 1049 fFileSizesMap[partialName] = 0; 1050 } 1051 sub.dailyFile.Open(partialName, serviceName, NULL); 1052 //notify the opening 1053 NotifyOpenedFile(sTime.str() + '_' + serviceName, 4); 1054 876 1055 } 877 1056 if (!sub.runFile.IsOpen() && (GetCurrentState() == kSM_Logging)) … … 879 1058 std::stringstream sRun; 880 1059 sRun << fRunNumber; 881 std::string partialName = fRunFileName + '/' + sRun.str() + '_' + serviceName + ".fits"; 882 sub.runFile.Open(partialName, serviceName); 1060 std::string partialName = fRunFileName + '/' + sRun.str() + ".fits";//'_' + serviceName + ".fits"; 1061 if (fRunFitsFile == NULL) 1062 { 1063 //get the size of the file we're about to open 1064 if (fFileSizesMap.find(partialName) == fFileSizesMap.end()) 1065 { 1066 struct stat st; 1067 if (!stat(partialName.c_str(), &st)) 1068 fBaseSizeRun += st.st_size; 1069 else 1070 fBaseSizeRun = 0; 1071 fFileSizesMap[partialName] = 0; 1072 } 1073 try 1074 { 1075 fRunFitsFile = new FITS(partialName, RWmode::Write); 1076 } 1077 catch (CCfits::FitsError e) 1078 { 1079 std::ostringstream err; 1080 err << "Could not open run file " << partialName; 1081 throw runtime_error(err.str()); 1082 } 1083 NotifyOpenedFile(sRun.str(), 4);// + '_' + serviceName, 4); 1084 } 1085 sub.runFile.Open(partialName, serviceName, fRunFitsFile); 883 1086 } 884 1087 } … … 915 1118 dataQualifier << flist[i].second.first; 916 1119 switch (flist[i].first.first->name()[0]) 917 { 1120 {//TODO handle all the data format cases 918 1121 case 'c': 919 1122 dataQualifier << "S"; … … 936 1139 break; 937 1140 case 'x': 1141 case 'X': 938 1142 dataQualifier << "K"; 939 1143 break; … … 981 1185 std::stringstream sRun; 982 1186 sRun << fRunNumber; 983 std::string fullName = fRunFileName + '/' + sRun.str() + ".log";984 fRunLogFile.open(f ullName.c_str(), std::ios_base::out | std::ios_base::app); //maybe should be app instead of ate985 986 f ullName = fRunFileName + '/' + sRun.str() + ".rep";987 fRunReportFile.open(f ullName.c_str(), std::ios_base::out | std::ios_base::app);1187 fFullRunLogFileName = fRunFileName + '/' + sRun.str() + ".log"; 1188 fRunLogFile.open(fFullRunLogFileName.c_str(), std::ios_base::out | std::ios_base::app); //maybe should be app instead of ate 1189 1190 fFullRunReportFileName = fRunFileName + '/' + sRun.str() + ".rep"; 1191 fRunReportFile.open(fFullRunReportFileName.c_str(), std::ios_base::out | std::ios_base::app); 988 1192 989 1193 if (!fRunLogFile.is_open() || !fRunReportFile.is_open()) … … 992 1196 return kSM_BadRunConfig; 993 1197 } 1198 //get the size of the newly opened file. 1199 struct stat st; 1200 fBaseSizeRun = 0; 1201 if (fFileSizesMap.find(fFullRunLogFileName) == fFileSizesMap.end()) 1202 { 1203 stat(fFullRunLogFileName.c_str(), &st); 1204 fBaseSizeRun += st.st_size; 1205 fFileSizesMap[fFullRunLogFileName] = 0; 1206 } 1207 if (fFileSizesMap.find(fFullRunReportFileName) == fFileSizesMap.end()) 1208 { 1209 stat(fFullRunReportFileName.c_str(), &st); 1210 fBaseSizeRun += st.st_size; 1211 fFileSizesMap[fFullRunReportFileName] = 0; 1212 } 1213 NotifyOpenedFile(sRun.str(), 3); 994 1214 995 1215 return kSM_Logging; … … 1015 1235 j->second.runFile.Close(); 1016 1236 } 1237 if (fRunFitsFile != NULL) 1238 { 1239 delete fRunFitsFile; 1240 fRunFitsFile = NULL; 1241 } 1017 1242 #endif 1018 1243 return kSM_WaitingRun; … … 1046 1271 j->second.runFile.Close(); 1047 1272 } 1273 if (fRunFitsFile != NULL) 1274 { 1275 delete fRunFitsFile; 1276 fRunFitsFile = NULL; 1277 } 1048 1278 #endif 1049 1279 return kSM_Ready;
Note:
See TracChangeset
for help on using the changeset viewer.