Changeset 10898 for trunk/FACT++/src
- Timestamp:
- 06/01/11 11:01:11 (13 years ago)
- Location:
- trunk/FACT++/src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/Fits.cc
r10814 r10898 82 82 //! @param fitsCounter a pointer to the integer keeping track of the opened FITS files 83 83 //! @param out a pointer to the MessageImp that should be used to log errors 84 //! @param runNumber the runNumber for which this file is opened. -1means nightly file.84 //! @param runNumber the runNumber for which this file is opened. 0 means nightly file. 85 85 // 86 86 void Fits::Open(const string& fileName, const string& tableName, FITS* file, int* fitsCounter, MessageImp* out, int runNumber) -
trunk/FACT++/src/Fits.h
r10814 r10898 61 61 public: 62 62 ///current run number being logged 63 int fRunNumber;63 uint32_t fRunNumber; 64 64 65 65 Fits() : fFile(NULL), … … 76 76 fNumOpenFitsFiles(NULL), 77 77 fMess(NULL), 78 fRunNumber( -1)78 fRunNumber(0) 79 79 {} 80 80 -
trunk/FACT++/src/dataLogger.cc
r10897 r10898 53 53 #include "Description.h" 54 54 55 #include "DimServiceInfoList.h"56 55 //#include "DimServiceInfoList.h" 56 #include "DimNetwork.h" 57 57 //for getting stat of opened files 58 58 #include <unistd.h> … … 109 109 string reportName; 110 110 ///the actual run number 111 int runNumber;111 uint32_t runNumber; 112 112 ///the time at which the run number was received 113 113 Time time; … … 124 124 runFitsFile = NULL; 125 125 #endif 126 runNumber = -1;126 runNumber = 0; 127 127 //give it a meaningless, 0 time to distinguish with actual, valid times 128 128 time = Time(0,0); … … 221 221 ///the actual dimInfo pointer 222 222 DimStampedInfo* dimInfo; 223 ///the server 224 string server; 225 ///the service 226 string service; 223 227 ///the converter for outputting the data according to the format 224 228 Converter* fConv; … … 226 230 int* numCopies; 227 231 ///the current run number used by this subscription 228 int runNumber;232 uint32_t runNumber; 229 233 ///copy operator 230 234 void operator = (const SubscriptionType& other) … … 235 239 #endif 236 240 dimInfo = other.dimInfo; 241 server = other.server; 242 service = other.service; 237 243 numCopies = other.numCopies; 238 244 fConv = other.fConv; … … 248 254 #endif 249 255 dimInfo = other.dimInfo; 256 server = other.server; 257 service = other.service; 250 258 numCopies = other.numCopies; 251 259 fConv = other.fConv; … … 258 266 dimInfo = info; 259 267 fConv = NULL; 260 runNumber = -1;268 runNumber = 0; 261 269 numCopies = new int(1); 262 270 } … … 266 274 dimInfo = NULL; 267 275 fConv = NULL; 268 runNumber = -1;276 runNumber = 0; 269 277 numCopies = new int(1); 270 278 } … … 295 303 }; 296 304 297 class DataLogger : public StateMachineDim, Dim InfoHandler305 class DataLogger : public StateMachineDim, DimServiceInfoList 298 306 { 299 307 public: … … 334 342 double fMjD; 335 343 ///for obtaining the name of the existing services 336 ServiceList fServiceList;344 // ServiceList fServiceList; 337 345 typedef map<const string, map<string, SubscriptionType> > SubscriptionsListType; 338 346 ///All the services to which we have subscribed to, sorted by server name. … … 382 390 ///DEPREC - configuration of the run number 383 391 int ConfigureRunNumber(const Event& evt); 384 ///logging method for the messages385 // int LogMessagePlease(const Event& evt);386 392 ///print the current state of the dataLogger 387 393 int PrintStatePlease(const Event& evt); 388 394 ///checks whether or not the current info being treated is a run number 389 void CheckForRunNumber(DimInfo* I); 395 void CheckForRunNumber(DimInfo* I); 390 396 /// start transition 391 397 int StartPlease(); … … 462 468 int OpenRunFile(RunNumberType& run); 463 469 ///add a new run number 464 void AddNewRunNumber(int newRun, Time time);470 void AddNewRunNumber(int64_t newRun, Time time); 465 471 ///removes the oldest run number, and close the relevant files. 466 472 void RemoveOldestRunNumber(); 467 ///checks with fServiceList whether or not the services got updated468 bool CheckForServicesUpdate();469 473 ///retrieves the size of a file 470 474 off_t GetFileSize(string&); … … 497 501 ///Checks if the input osftream is in error state, and if so close it. 498 502 void CheckForOfstreamError(ofstream& out); 503 /*************************************************** 504 * INHERITED FROM DIMSERVICEINFOLIST 505 ***************************************************/ 506 ///Add a new service subscription 507 void AddService(const string&, const string&, const string&, bool); 508 ///Remove a given service subscription 509 void RemoveService(const string&, const string&, bool); 510 ///Remove all the services associated with a given server 511 void RemoveAllServices(const string&); 499 512 }; //DataLogger 500 513 514 // -------------------------------------------------------------------------- 515 // 516 //! Add a new service subscription 517 //! @param server the server for which the subscription should be created 518 //! @param service the service for which the subscription should be created 519 //! @param isCmd whether this is a Dim Command or not. Commands are not logged 520 //TODO maybe commands should indeed be logged ? 521 // 522 void DataLogger::AddService(const string& server, const string& service, const string&, bool isCmd) 523 { 524 //check the given subscription against black and white lists 525 if (!ShouldSubscribe(server, service)) 526 return; 527 //dataLogger does not subscribe to commands 528 if (isCmd) 529 return; 530 //do we already have an entry for that server ? 531 SubscriptionsListType::iterator cSubs = fServiceSubscriptions.find(server); 532 if (cSubs != fServiceSubscriptions.end()) 533 {//server already here. check its services 534 if (cSubs->second.find(service) == cSubs->second.end()) 535 {//service not found. Add it 536 cSubs->second[service].dimInfo = SubscribeToPlease(server, service); 537 cSubs->second[service].server = server; 538 cSubs->second[service].service = service; 539 } 540 else 541 { 542 MessageImp::Error("Service " + server + "/" + service + " is already in the dataLogger's list. ignoring its update."); 543 return; 544 } 545 } 546 else 547 {//server not yet in our list. add it 548 fServiceSubscriptions[server] = map<string, SubscriptionType>(); 549 map<string, SubscriptionType>& liste = fServiceSubscriptions[server]; 550 liste[service].dimInfo = SubscribeToPlease(server, service); 551 liste[service].server = server; 552 liste[service].service = service; 553 } 554 if (fDebugIsOn) 555 { 556 Debug("Added subscription to " + server + "/" + service); 557 } 558 } 559 // -------------------------------------------------------------------------- 560 // 561 //! Remove a given service subscription 562 //! @param server the server for which the subscription should be removed 563 //! @param service the service that should be removed 564 //! @param isCmd whether or not this is a command 565 // 566 void DataLogger::RemoveService(const string& server, const string& service, bool isCmd) 567 { 568 if (isCmd) 569 return; 570 571 fServiceSubscriptions[server].erase(service); 572 if (fDebugIsOn) 573 { 574 Debug("Removed subscription to " + server + "/" + service); 575 } 576 } 577 // -------------------------------------------------------------------------- 578 // 579 //! Remove all the services associated with a given server 580 //! @param server the server for which all the services should be removed 581 // 582 void DataLogger::RemoveAllServices(const string& server) 583 { 584 fServiceSubscriptions[server].clear(); 585 if (fDebugIsOn) 586 { 587 Debug("Removed all subscriptions to " + server + "/"); 588 } 589 } 501 590 // -------------------------------------------------------------------------- 502 591 // … … 627 716 fileNameWithPath = fRunFilePath + '/' + fileName; 628 717 } 718 629 719 // -------------------------------------------------------------------------- 630 720 // … … 637 727 { 638 728 ostringstream groupName; 639 if (runNumber != -1)729 if (runNumber != 0) 640 730 { 641 731 groupName << fRunFilePath << '/' << runNumber << ".fits"; … … 750 840 return st.st_size; 751 841 752 if (errno != 0 )842 if (errno != 0 && errno != 2)//ignoring error #2: no such file or directory is not an error for new files 753 843 { 754 844 ostringstream str; … … 1002 1092 "|Path[string]:Absolute or relative path name where the run files should be stored."); 1003 1093 1004 AddEvent(fConfigRunNumber, " I", kSM_Ready, kSM_NightlyOpen, kSM_WaitingRun, kSM_BadRunConfig, kSM_Logging)1094 AddEvent(fConfigRunNumber, "X", kSM_Ready, kSM_NightlyOpen, kSM_WaitingRun, kSM_BadRunConfig, kSM_Logging) 1005 1095 (boost::bind(&DataLogger::ConfigureRunNumber, this, _1)) 1006 1096 ("Configure the run number. Cannot be done in logging state"); 1007 1097 1008 //Provide a logging command1009 //I get the feeling that I should be going through the EventImp1010 //instead of DimCommand directly, mainly because the commandHandler1011 //is already done in StateMachineImp.cc1012 //Thus I'll simply add a configuration, which I will treat as the logging command1013 // AddEvent(fConfigLog, "C", kSM_NightlyOpen, kSM_Logging, kSM_WaitingRun, kSM_BadRunConfig)1014 // (boost::bind(&DataLogger::LogMessagePlease, this, _1))1015 // ("Log a single message to the log-files."1016 // "|Message[string]:Message to be logged.");1017 1018 1098 //Provide a print command 1019 1099 ostringstream str; … … 1023 1103 (boost::bind(&DataLogger::PrintStatePlease, this, _1)) 1024 1104 ("Print information about the internal status of the data logger."); 1025 1026 fServiceList.SetHandler(this);1027 CheckForServicesUpdate();1028 1105 1029 1106 //start the monitoring service … … 1087 1164 } 1088 1165 } 1089 // -------------------------------------------------------------------------- 1090 // 1091 //! Checks for changes in the existing services. 1092 //! Any new service will be added to the service list, while the ones which disappeared are removed. 1093 // 1094 //FIXME The service must be udpated so that I get the first notification. This should not be 1095 bool DataLogger::CheckForServicesUpdate() 1096 { 1097 bool serviceUpdated = false; 1098 //get the current server list 1099 const vector<string> serverList = fServiceList.GetServerList(); 1100 //first let's remove the servers that may have disapeared 1101 //can't treat the erase on maps the same way as for vectors. Do it the safe way instead 1102 vector<string> toBeDeleted; 1103 for (SubscriptionsListType::iterator cListe = fServiceSubscriptions.begin(); cListe != fServiceSubscriptions.end(); cListe++) 1104 { 1105 vector<string>::const_iterator givenServers; 1106 for (givenServers=serverList.begin(); givenServers!= serverList.end(); givenServers++) 1107 if (cListe->first == *givenServers) 1108 break; 1109 if (givenServers == serverList.end())//server vanished. Remove it 1110 { 1111 toBeDeleted.push_back(cListe->first); 1112 serviceUpdated = true; 1113 } 1114 } 1115 for (vector<string>::const_iterator it = toBeDeleted.begin(); it != toBeDeleted.end(); it++) 1116 fServiceSubscriptions.erase(*it); 1117 //now crawl through the list of servers, and see if there was some updates 1118 for (vector<string>::const_iterator i=serverList.begin(); i!=serverList.end();i++) 1119 { 1120 //skip the two de-fact excluded services 1121 //Dim crashes if the publisher subscribes to its own service. This sounds weird, I agree. 1122 //I agree: hard coded values are bad, but in this case these two entries should always be here otherwise Dim crashes. 1123 if ((i->find("DIS_DNS") != string::npos) || 1124 (i->find("DATA_LOGGER") != string::npos)) 1125 continue; 1126 //find the current server in our subscription list 1127 SubscriptionsListType::iterator cSubs = fServiceSubscriptions.find(*i); 1128 //get the service list of the current server 1129 vector<string> cServicesList = fServiceList.GetServiceList(*i); 1130 if (cSubs != fServiceSubscriptions.end())//if the current server already is in our subscriptions 1131 { //then check and update our list of subscriptions 1132 //first, remove the services that may have disapeared. 1133 map<string, SubscriptionType>::iterator serverSubs; 1134 vector<string>::const_iterator givenSubs; 1135 toBeDeleted.clear(); 1136 for (serverSubs=cSubs->second.begin(); serverSubs != cSubs->second.end(); serverSubs++) 1137 { 1138 for (givenSubs = cServicesList.begin(); givenSubs != cServicesList.end(); givenSubs++) 1139 if (serverSubs->first == *givenSubs) 1140 break; 1141 if (givenSubs == cServicesList.end()) 1142 { 1143 toBeDeleted.push_back(serverSubs->first); 1144 serviceUpdated = true; 1145 } 1146 } 1147 for (vector<string>::const_iterator it = toBeDeleted.begin(); it != toBeDeleted.end(); it++) 1148 cSubs->second.erase(*it); 1149 //now check for new services 1150 for (givenSubs = cServicesList.begin(); givenSubs != cServicesList.end(); givenSubs++) 1151 { 1152 if (!ShouldSubscribe(*i, *givenSubs)) 1153 continue; 1154 if (cSubs->second.find(*givenSubs) == cSubs->second.end()) 1155 {//service not found. Add it 1156 cSubs->second[*givenSubs].dimInfo = SubscribeToPlease(*i, *givenSubs); 1157 serviceUpdated = true; 1158 } 1159 } 1160 } 1161 else //server not found in our list. Create its entry 1162 { 1163 fServiceSubscriptions[*i] = map<string, SubscriptionType>(); 1164 map<string, SubscriptionType>& liste = fServiceSubscriptions[*i]; 1165 for (vector<string>::const_iterator j = cServicesList.begin(); j!= cServicesList.end(); j++) 1166 { 1167 if (!ShouldSubscribe(*i, *j)) 1168 continue; 1169 liste[*j].dimInfo = SubscribeToPlease(*i, *j); 1170 serviceUpdated = true; 1171 } 1172 } 1173 } 1174 return serviceUpdated; 1175 } 1166 1176 1167 // -------------------------------------------------------------------------- 1177 1168 // … … 1220 1211 1221 1212 DimInfo* I = getInfo(); 1222 SubscriptionsListType::iterator x; 1223 map<string, SubscriptionType>::iterator y; 1213 1224 1214 if (I==NULL) 1225 {1226 if (CheckForServicesUpdate())1227 {1228 //services were updated. Notify1229 fNumSubAndFitsData.numSubscriptions = 0;1230 for (x=fServiceSubscriptions.begin(); x != fServiceSubscriptions.end(); x++)1231 fNumSubAndFitsData.numSubscriptions += x->second.size();1232 if (fNumSubAndFitsIsOn)1233 {1234 if (fDebugIsOn)1235 {1236 ostringstream str;1237 str << "Updating number of subscriptions service: Num Subs=" << fNumSubAndFitsData.numSubscriptions << " Num open FITS=" << fNumSubAndFitsData.numOpenFits;1238 Debug(str);1239 }1240 fNumSubAndFits->updateService();1241 }1242 }1243 1215 return; 1244 }1245 1216 //check if the service pointer corresponds to something that we subscribed to 1246 1217 //this is a fix for a bug that provides bad Infos when a server starts 1247 1218 bool found = false; 1248 for (x=fServiceSubscriptions.begin(); x != fServiceSubscriptions.end(); x++) 1219 SubscriptionsListType::iterator x; 1220 map<string, SubscriptionType>::iterator y; 1221 for (x=fServiceSubscriptions.begin(); x != fServiceSubscriptions.end(); x++) 1249 1222 {//find current service is subscriptions 1250 1223 for (y=x->second.begin(); y!=x->second.end();y++) … … 1258 1231 } 1259 1232 if (!found) 1233 { 1234 DimServiceInfoList::infoHandler(); 1260 1235 return; 1236 } 1261 1237 if (I->getSize() <= 0) 1262 1238 return; … … 1336 1312 //! @param time the time at which the new run number was issued 1337 1313 // 1338 void DataLogger::AddNewRunNumber(int newRun, Time time) 1339 { 1314 void DataLogger::AddNewRunNumber(int64_t newRun, Time time) 1315 { 1316 1317 if (newRun > 0xffffffff) 1318 { 1319 Error("New run number too large, out of range. Ignoring."); 1320 return; 1321 } 1340 1322 if (fDebugIsOn) 1341 1323 { … … 1346 1328 //Add new run number to run number list 1347 1329 fRunNumber.push_back(RunNumberType()); 1348 fRunNumber.back().runNumber = newRun;1330 fRunNumber.back().runNumber = uint32_t(newRun); 1349 1331 fRunNumber.back().time = time; 1332 1333 ostringstream str; 1334 str << "The new run number is: " << fRunNumber.back().runNumber; 1335 Message(str); 1336 1350 1337 if (GetCurrentState() != kSM_Logging) 1351 1338 return; … … 1364 1351 if (strstr(I->getName(), fRunNumberInfo) != NULL) 1365 1352 {//assumes that the run number is an integer 1366 AddNewRunNumber(I->getInt(), Time(I->getTimestamp(), I->getTimestampMillisecs()*1000)); 1367 ostringstream str; 1368 str << "New run number is " << fRunNumber.back().runNumber; 1369 Message(str); 1353 AddNewRunNumber(I->getLonglong(), Time(I->getTimestamp(), I->getTimestampMillisecs()*1000)); 1370 1354 } 1371 1355 } … … 1523 1507 } 1524 1508 1525 // --------------------------------------------------------------------------1526 //1527 //! write messages to logs.1528 /*1529 //! @param evt1530 //! the current event to log1531 //! @returns1532 //! the new state. Currently, always the current state1533 //!1534 //! @deprecated1535 //! I guess that this function should not be any longer1536 //1537 //Otherwise re-write it properly with the MessageImp class1538 int DataLogger::LogMessagePlease(const Event& evt)1539 {1540 if (!fNightlyLogFile.is_open())1541 return GetCurrentState();1542 Warn("LogMessagePlease has not been checked nor updated since a long while. Undefined behavior to be expected");1543 ostringstream header;1544 const Time& cTime = evt.GetTime();1545 header << evt.GetName() << " " << cTime.Y() << " " << cTime.M() << " " << cTime.D() << " ";1546 header << cTime.h() << " " << cTime.m() << " " << cTime.s() << " ";1547 header << cTime.ms() << " ";1548 1549 const Converter conv(Out(), evt.GetFormat());1550 if (!conv)1551 {1552 Error("Couldn't properly parse the format... ignored.");1553 return GetCurrentState();1554 }1555 1556 string text;1557 try1558 {1559 text = conv.GetString(evt.GetData(), evt.GetSize());1560 }1561 catch (const runtime_error &e)1562 {1563 Out() << kRed << e.what() << endl;1564 Error("Couldn't properly parse the data... ignored.");1565 return GetCurrentState();1566 }1567 1568 if (text.empty())1569 return GetCurrentState();1570 1571 //replace bizarre characters by white space1572 replace(text.begin(), text.end(), '\n', '\\');1573 replace_if(text.begin(), text.end(), ptr_fun<int, int>(&iscntrl), ' ');1574 if (fDebugIsOn)1575 {1576 ostringstream str;1577 str << "Logging: \"" << header << text << "\"";1578 Debug(str.str());1579 }1580 1581 if (fNightlyLogFile.is_open())1582 {1583 fNightlyLogFile << header;1584 if (!fNightlyLogFile.good())1585 {1586 Error("An error occured while writing to the run log file. Closing it.");1587 if (fNightlyLogFile.is_open())1588 fNightlyLogFile.close();1589 }1590 }1591 if (fRunLogFile.is_open())1592 {1593 fRunLogFile << header;1594 if (!fRunLogFile.good())1595 {1596 Error("An error occured while writing to the run log file. Closing it.");1597 if (fRunLogFile.is_open())1598 fRunLogFile.close();1599 }1600 }1601 if (fNightlyLogFile.is_open())1602 {1603 fNightlyLogFile << text;1604 if (!fNightlyLogFile.good())1605 {1606 Error("An error occured while writing to the run log file. Closing it.");1607 if (fNightlyLogFile.is_open())1608 fNightlyLogFile.close();1609 }1610 }1611 if (fRunLogFile.is_open())1612 {1613 fRunLogFile << text;1614 if (!fRunLogFile.good())1615 {1616 Error("An error occured while writing to the run log file. Closing it.");1617 if (fRunLogFile.is_open())1618 fRunLogFile.close();1619 }1620 }1621 return GetCurrentState();1622 }*/1623 1509 // -------------------------------------------------------------------------- 1624 1510 // … … 1878 1764 int DataLogger::ConfigureRunNumber(const Event& evt) 1879 1765 { 1880 AddNewRunNumber(evt.Get Int(), evt.GetTime());1766 AddNewRunNumber(evt.GetXtra(), evt.GetTime()); 1881 1767 // fRunNumber = evt.GetInt(); 1882 ostringstream str;1883 str << "The new run number is: " << fRunNumber.back().runNumber;1884 Message(str);1885 1768 return GetCurrentState(); 1886 1769 } … … 2009 1892 fOpenedNightlyFits[fileNameOnly].push_back(serviceName); 2010 1893 2011 sub.nightlyFile.Open(partialName, serviceName, NULL, &fNumSubAndFitsData.numOpenFits, this, -1);//Out());1894 sub.nightlyFile.Open(partialName, serviceName, NULL, &fNumSubAndFitsData.numOpenFits, this, 0);//Out()); 2012 1895 2013 1896 //notify the opening … … 2025 1908 } 2026 1909 //do the actual file open 2027 if (!sub.runFile.IsOpen() && (GetCurrentState() == kSM_Logging) && sub.runNumber != -1)1910 if (!sub.runFile.IsOpen() && (GetCurrentState() == kSM_Logging) && sub.runNumber != 0) 2028 1911 {//buffer for the run file have already been allocated when doing the Nightly file 2029 1912 string fileNameOnly; … … 2156 2039 dataFormatsLocal.push_back(dataQualifier.str()); 2157 2040 } 2158 sub.nightlyFile.InitDataColumns( fServiceList.GetDescriptions(sub.dimInfo->getName()), dataFormatsLocal, sub.dimInfo->getData(), size);2159 sub.runFile.InitDataColumns( fServiceList.GetDescriptions(sub.dimInfo->getName()), dataFormatsLocal, sub.dimInfo->getData(), size);2041 sub.nightlyFile.InitDataColumns(GetDescription(sub.server, sub.service), dataFormatsLocal, sub.dimInfo->getData(), size); 2042 sub.runFile.InitDataColumns(GetDescription(sub.server, sub.service), dataFormatsLocal, sub.dimInfo->getData(), size); 2160 2043 } 2161 2044 // -------------------------------------------------------------------------- … … 2210 2093 //! @param filesToGroup a map of filenames mapping to table names to be grouped (i.e. a 2211 2094 //! single file can contain several tables to group 2212 //! @param runNumber the run number that should be used for grouping. -1means nightly group2095 //! @param runNumber the run number that should be used for grouping. 0 means nightly group 2213 2096 // 2214 2097 void DataLogger::CreateFitsGrouping(map<string, vector<string> > & filesToGroup, int runNumber) … … 2218 2101 ostringstream str; 2219 2102 str << "Creating fits group for "; 2220 if (runNumber != -1)2103 if (runNumber != 0) 2221 2104 str << "run files"; 2222 2105 else … … 2397 2280 } 2398 2281 #ifdef HAVE_FITS 2399 CreateFitsGrouping(fOpenedNightlyFits, -1);2282 CreateFitsGrouping(fOpenedNightlyFits, 0); 2400 2283 #endif 2401 2284 return kSM_Ready;
Note:
See TracChangeset
for help on using the changeset viewer.