- Timestamp:
- 03/30/11 10:56:42 (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/dataLogger.cc
r10183 r10264 1 1 //**************************************************************** 2 /** @class DataLogger 3 4 @brief Logs all message and infos between the services 5 6 This is the main logging class facility. 7 It derives from StateMachineDim and DimInfoHandler. the first parent is here to enforce 8 a state machine behaviour, while the second one is meant to make the dataLogger receive 9 dim services to which it subscribed from. 10 The possible states and transitions of the machine are: 11 \dot 12 digraph datalogger { 13 node [shape=record, fontname=Helvetica, fontsize=10]; 14 e [label="Error" color="red"]; 15 r [label="Ready"] 16 d [label="DailyOpen"] 17 w [label="WaitingRun"] 18 l [label="Logging"] 19 b [label="BadDailyconfig" color="red"] 20 c [label="BadRunConfig" color="red"] 21 22 e -> r 23 r -> e 24 r -> d 25 r -> b 26 d -> w 27 d -> r 28 w -> r 29 l -> r 30 l -> w 31 b -> d 32 w -> c 33 w -> l 34 b -> r 35 c -> r 36 c -> l 37 } 38 \enddot 39 40 @todo 41 - Retrieve also the messages, not only the infos 42 */ 43 //**************************************************************** 2 44 #include "Event.h" 3 45 #include "Time.h" 4 46 #include "StateMachineDim.h" 5 47 #include "ServiceList.h" 48 #include "Converter.h" 49 #include "MessageImp.h" 50 6 51 #include <fstream> 7 52 8 53 #include <boost/bind.hpp> 9 54 10 //**************************************************************** 11 /** @class DataLogger 12 * 13 * @brief Logs all message and infos between the services 14 * 15 * This is the main logging class facility. 16 * It derives from StateMachineDim and DimInfoHandler. the first parent is here to enforce 17 * a state machine behaviour, while the second one is meant to make the dataLogger receive 18 * dim services to which it subscribed from. 19 * The possible states and transitions of the machine are: 20 * \dot 21 * digraph datalogger { 22 * node [shape=record, fontname=Helvetica, fontsize=10]; 23 * e [label="Error" color="red"]; 24 * r [label="Ready"] 25 * d [label="DailyOpen"] 26 * w [label="WaitingRun"] 27 * l [label="Logging"] 28 * b [label="BadDailyconfig" color="red"] 29 * c [label="BadRunConfig" color="red"] 30 * 31 * e -> r 32 * r -> e 33 * r -> d 34 * r -> b 35 * d -> w 36 * d -> r 37 * w -> r 38 * l -> r 39 * l -> w 40 * b -> d 41 * w -> c 42 * w -> l 43 * b -> r 44 * c -> r 45 * c -> l 46 * } 47 * \enddot 48 * 49 * @todo 50 * - A lot 51 ****************************************************************/ 55 #include <astroroot.h> 56 52 57 class DataLogger : public StateMachineDim, DimInfoHandler 53 58 { … … 68 73 private: 69 74 //Define all the data structure specific to the DataLogger here 70 std::ofstream fDailyFile; /// ofstream for the dailyfile 71 std::ofstream fRunFile; /// ofstream for the run-specific file 72 std::string fDailyFileName; /// base path of the dailyfile 73 std::string fRunFileName; ///base path of the run file 74 int runNumber; ///run number (-1 means no run number specified) 75 /// ofstream for the dailyLogfile 76 std::ofstream fDailyLogFile; 77 /// ofstream for the run-specific Log file 78 std::ofstream fRunLogFile; 79 80 /// ofstream for the daily report file 81 std::ofstream fDailyReportFile; 82 /// ofstream for the run-specific report file 83 std::ofstream fRunReportFile; 84 /// base path of the dailyfile 85 std::string fDailyFileName; 86 ///base path of the run file 87 std::string fRunFileName; 88 ///run number (-1 means no run number specified) 89 int fRunNumber; 90 ///Current year 91 short fYear; 92 ///Current Month 93 short fMonth; 94 ///Current Day 95 short fDay; 96 ///Current Hour 97 short fHour; 98 ///Current Minute 99 short fMin; 100 ///Current Second 101 short fSec; 102 ///Current Milliseconds 103 int fMs; 104 ///Current Service Quality 105 int fQuality; 106 ///Modified Julian Date 107 double fMjD; 75 108 76 109 ///Define all the static names 77 static const char* configDay; 78 static const char* configRun; 79 static const char* configRunNumber; 80 static const char* configLog; 81 static const char* transStart; 82 static const char* transStop; 83 static const char* transStartRun; 84 static const char* transStopRun; 85 static const char* transReset; 86 static const char* transWait; 87 static const char* runNumberInfo; ///< This is the name of the dimInfo received to specify the run number. It must be updated once the final name will be defined 88 89 int Execute(); ///Inherited from state machine impl 90 91 int Transition(const Event& evt); ///Inherited from state machine impl 92 93 int Configure(const Event& evt); ///Inherited from state machine impl 110 static const char* fConfigDay; 111 static const char* fConfigRun; 112 static const char* fConfigRunNumber; 113 static const char* fConfigLog; 114 static const char* fTransStart; 115 static const char* fTransStop; 116 static const char* fTransStartRun; 117 static const char* fTransStopRun; 118 static const char* fTransReset; 119 static const char* fTransWait; 120 static const char* fRunNumberInfo; ///< This is the name of the dimInfo received to specify the run number. It must be updated once the final name will be defined 121 ///Inherited from state machine impl 122 int Execute(); 123 124 ///Inherited from state machine impl 125 int Transition(const Event& evt); 126 127 ///Inherited from state machine impl 128 int Configure(const Event& evt); 94 129 95 130 //overloading of DIM's infoHandler function 96 void infoHandler(); ///Inherited from DimInfoHandler 97 98 ServiceList fServiceList;///for obtaining the name of the existing services 99 100 std::map<std::string, std::vector<DimStampedInfo> > fServiceSubscriptions; ///All the services to which we've subscribed to. Sorted by server name 101 102 //internal methods 103 void LogPlease(DimInfo* I); ///Logging method for the services info received 104 std::string ToString(const char *format, const void *data, int size); ///Convertion from raw format to human-readable string 105 //configure methods 106 int ConfigureDailyFileName(const Event& evt); ///Configuration of the daily file path 107 int ConfigureRunFileName(const Event& evt); ///Configuration fo the file name 108 //TODO this will be given by an info, not a command. 109 int ConfigureRunNumber(const Event& evt); ///DEPREC - configuration of the run number 110 int LogMessagePlease(const Event& evt); ///logging method for the messages 111 void CheckForServicesUpdate(); ///checks with fServiceList whether or not the services got updated 112 void CheckForRunNumber(DimInfo* I); ///checks whether or not the current info being treated is a run number 113 //transitions methods 114 int StartPlease(); /// start transition 115 int StopPlease(); ///stop transition 116 int StartRunPlease(); ///from waiting to logging transition 117 int StopRunPlease(); /// from logging to waiting transition 118 int ResetPlease(); ///reset transition 119 int DailyToWaitRunPlease(); ///from dailyOpen to waiting transition 120 121 void InitServiceSubscription(); ///first subscription to the dim services. 122 123 131 void infoHandler(); 132 133 ///for obtaining the name of the existing services 134 ServiceList fServiceList; 135 136 137 ///A std pair to store both the DimInfo name and the actual DimInfo pointer 138 // typedef std::pair<std::string, DimStampedInfo*> subscriptionType; 139 ///All the services to which we've subscribed to. Sorted by server name 140 // std::map<const std::string, std::vector<subscriptionType > > fServiceSubscriptions; 141 142 ///A std pair to store both the DimInfo pointer and the corresponding outputted fits file 143 struct SubscriptionType 144 { 145 ///daily FITS output file 146 AstroRootIo dailyFile; 147 ///run-specific FITS output file 148 AstroRootIo runFile; 149 ///the actual dimInfo pointer 150 DimStampedInfo* dimInfo; 151 ///the number of existing handlers to this structure. 152 ///This is required otherwise I MUST handle the deleting of dimInfo outside from the destructor 153 int* numCopies; 154 void operator = (const SubscriptionType& other) 155 { 156 dailyFile = other.dailyFile; 157 runFile = other.runFile; 158 dimInfo = other.dimInfo; 159 numCopies = other.numCopies; 160 (*numCopies)++; 161 } 162 SubscriptionType(const SubscriptionType& other) 163 { 164 dailyFile = other.dailyFile; 165 runFile = other.runFile; 166 dimInfo = other.dimInfo; 167 numCopies = other.numCopies; 168 (*numCopies)++; 169 } 170 SubscriptionType(DimStampedInfo* info) 171 { 172 dimInfo = info; 173 numCopies = new int(1); 174 } 175 SubscriptionType() 176 { 177 dimInfo = NULL; 178 numCopies = new int(1); 179 } 180 ~SubscriptionType() 181 { 182 if (numCopies) 183 (*numCopies)--; 184 if (numCopies) 185 if (*numCopies < 1) 186 { 187 if (dailyFile.IsOpen()) 188 dailyFile.Close(); 189 if (runFile.IsOpen()) 190 runFile.Close(); 191 if (dimInfo) 192 delete dimInfo; 193 if (numCopies) 194 delete numCopies; 195 dimInfo = NULL; 196 numCopies = NULL; 197 } 198 } 199 }; 200 typedef std::map<const std::string, std::map<std::string, SubscriptionType>> SubscriptionsListType; 201 ///All the services to which we have subscribed to, sorted by server name. 202 SubscriptionsListType fServiceSubscriptions; 203 204 205 ///Reporting method for the services info received 206 void ReportPlease(DimInfo* I, SubscriptionType& sub); 207 208 ///Configuration of the daily file path 209 int ConfigureDailyFileName(const Event& evt); 210 ///Configuration fo the file name 211 int ConfigureRunFileName(const Event& evt); 212 ///DEPREC - configuration of the run number 213 int ConfigureRunNumber(const Event& evt); 214 ///logging method for the messages 215 int LogMessagePlease(const Event& evt); 216 ///checks whether or not the current info being treated is a run number 217 void CheckForRunNumber(DimInfo* I); 218 219 /// start transition 220 int StartPlease(); 221 ///from waiting to logging transition 222 int StartRunPlease(); 223 /// from logging to waiting transition 224 int StopRunPlease(); 225 ///stop and reset transition 226 int GoToReadyPlease(); 227 ///from dailyOpen to waiting transition 228 int DailyToWaitRunPlease(); 229 ///Open fits files 230 void OpenFITSFilesPlease(SubscriptionType& sub); 231 ///Write data to FITS files 232 void WriteToFITS(SubscriptionType& sub); 233 ///Allocate the buffers required for fits 234 void AllocateFITSBuffers(SubscriptionType& sub); 235 public: 236 ///checks with fServiceList whether or not the services got updated 237 void CheckForServicesUpdate(); 124 238 125 239 }; //DataLogger … … 127 241 //static members initialization 128 242 //since I do not check the transition/config names any longer, indeed maybe these could be hard-coded... but who knows what will happen in the future ? 129 const char* DataLogger::configDay = "CONFIG_DAY"; 130 const char* DataLogger::configRun = "CONFIG_RUN"; 131 const char* DataLogger::configRunNumber = "CONFIG_RUN_NUMBER"; 132 const char* DataLogger::configLog = "LOG"; 133 const char* DataLogger::transStart = "START"; 134 const char* DataLogger::transStop = "STOP"; 135 const char* DataLogger::transStartRun = "START_RUN"; 136 const char* DataLogger::transStopRun = "STOP_RUN"; 137 const char* DataLogger::transReset = "RESET"; 138 const char* DataLogger::transWait = "WAIT_RUN_NUMBER"; 139 const char* DataLogger::runNumberInfo = "RUN_NUMBER"; 140 141 /**************************************************************** 142 * 143 * DATA LOGGER CONSTRUCTOR 144 * 145 ****************************************************************/ 146 //! Default constructor 243 const char* DataLogger::fConfigDay = "CONFIG_DAY"; 244 const char* DataLogger::fConfigRun = "CONFIG_RUN"; 245 const char* DataLogger::fConfigRunNumber = "CONFIG_RUN_NUMBER"; 246 const char* DataLogger::fConfigLog = "LOG"; 247 const char* DataLogger::fTransStart = "START"; 248 const char* DataLogger::fTransStop = "STOP"; 249 const char* DataLogger::fTransStartRun = "START_RUN"; 250 const char* DataLogger::fTransStopRun = "STOP_RUN"; 251 const char* DataLogger::fTransReset = "RESET"; 252 const char* DataLogger::fTransWait = "WAIT_RUN_NUMBER"; 253 const char* DataLogger::fRunNumberInfo = "RUN_NUMBER"; 254 255 // -------------------------------------------------------------------------- 256 // 257 //! Default constructor. The name of the machine is given DATA_LOGGER 258 //! and the state is set to kSM_Ready at the end of the function. 259 // 260 //!Setup the allows states, configs and transitions for the data logger 261 // 147 262 DataLogger::DataLogger() : StateMachineDim(std::cout, "DATA_LOGGER") 148 263 { 149 264 //initialize member data 150 fDailyFileName = " ";151 fRunFileName = " ";152 runNumber = -1;265 fDailyFileName = "/home/lyard/log"; 266 fRunFileName = "/home/lyard/log"; 267 fRunNumber = 12345; 153 268 //Give a name to this machine's specific states 154 269 AddStateName(kSM_DailyOpen, "Daily_File_Openened"); … … 159 274 160 275 /*Add the possible transitions for this machine*/ 161 AddTransition(kSM_DailyOpen, transStart, kSM_Ready, kSM_BadDailyConfig) //start the daily logging. daily file location must be specified already276 AddTransition(kSM_DailyOpen, fTransStart, kSM_Ready, kSM_BadDailyConfig) //start the daily logging. daily file location must be specified already 162 277 ->AssignFunction(boost::bind(&DataLogger::StartPlease, this)); 163 AddTransition(kSM_Ready, transStop, kSM_DailyOpen, kSM_WaitingRun, kSM_Logging) //stop the data logging164 ->AssignFunction(boost::bind(&DataLogger:: StopPlease, this));165 AddTransition(kSM_Logging, transStartRun, kSM_WaitingRun, kSM_BadRunConfig) //start the run logging. run file location must be specified already.278 AddTransition(kSM_Ready, fTransStop, kSM_DailyOpen, kSM_WaitingRun, kSM_Logging) //stop the data logging 279 ->AssignFunction(boost::bind(&DataLogger::GoToReadyPlease, this)); 280 AddTransition(kSM_Logging, fTransStartRun, kSM_WaitingRun, kSM_BadRunConfig) //start the run logging. run file location must be specified already. 166 281 ->AssignFunction(boost::bind(&DataLogger::StartRunPlease, this)); 167 AddTransition(kSM_WaitingRun, transStopRun, kSM_Logging)282 AddTransition(kSM_WaitingRun, fTransStopRun, kSM_Logging) 168 283 ->AssignFunction(boost::bind(&DataLogger::StopRunPlease, this)); 169 AddTransition(kSM_Ready, transReset, kSM_Error, kSM_BadDailyConfig, kSM_BadRunConfig, kSM_Error) //transition to exit error states. dunno if required or not, would close the daily file if already openned.170 ->AssignFunction(boost::bind(&DataLogger:: ResetPlease, this));171 AddTransition(kSM_WaitingRun, transWait, kSM_DailyOpen)284 AddTransition(kSM_Ready, fTransReset, kSM_Error, kSM_BadDailyConfig, kSM_BadRunConfig, kSM_Error) //transition to exit error states. dunno if required or not, would close the daily file if already openned. 285 ->AssignFunction(boost::bind(&DataLogger::GoToReadyPlease, this)); 286 AddTransition(kSM_WaitingRun, fTransWait, kSM_DailyOpen) 172 287 ->AssignFunction(boost::bind(&DataLogger::DailyToWaitRunPlease, this)); 173 288 /*Add the possible configurations for this machine*/ 174 AddConfiguration( configDay, kSM_Ready, kSM_BadDailyConfig) //configure the daily file location. cannot be done before the file is actually opened289 AddConfiguration(fConfigDay, "C", kSM_Ready, kSM_BadDailyConfig) //configure the daily file location. cannot be done before the file is actually opened 175 290 ->AssignFunction(boost::bind(&DataLogger::ConfigureDailyFileName, this, _1)); 176 AddConfiguration( configRun, kSM_Ready, kSM_BadDailyConfig, kSM_DailyOpen, kSM_WaitingRun, kSM_BadRunConfig) //configure the run file location. cannot be done before the file is actually opened, and not in a dailly related error.291 AddConfiguration(fConfigRun, "C", kSM_Ready, kSM_BadDailyConfig, kSM_DailyOpen, kSM_WaitingRun, kSM_BadRunConfig) //configure the run file location. cannot be done before the file is actually opened, and not in a dailly related error. 177 292 ->AssignFunction(boost::bind(&DataLogger::ConfigureRunFileName, this, _1)); 178 /*wait for Dim to finish initializing*/179 /*just a sleep for now. */180 /*TODO: add a better way to wait: poll DIM for something I guess. Maybe get the configuration from conf server ? */181 182 usleep(1000000); //10ms183 293 184 294 //Provide a logging command … … 187 297 //is already done in StateMachineImp.cc 188 298 //Thus I'll simply add a configuration, which I will treat as the logging command 189 AddConfiguration( configRun, kSM_DailyOpen, kSM_Logging, kSM_WaitingRun, kSM_BadRunConfig)299 AddConfiguration(fConfigLog, "C", kSM_DailyOpen, kSM_Logging, kSM_WaitingRun, kSM_BadRunConfig) 190 300 ->AssignFunction(boost::bind(&DataLogger::LogMessagePlease, this, _1)); 191 192 InitServiceSubscription(); 301 302 fServiceList.SetHandler(this); 303 CheckForServicesUpdate(); 193 304 194 305 //All configuration done, callback funtions set, go to ready state and thus prevent the run loop from being executed 195 306 SetReady(); 196 307 } 197 //! Initialization of the subscription to the services. 198 void DataLogger::InitServiceSubscription() 199 { 200 //assign myself as the info handler 201 fServiceList.SetHandler(this); 202 203 //crawl through the list of services and subscribe to all of them 204 //TODO I still haven't figured out how the update of services shouldbe performed 205 //TODO: I don't think that the reference would work in this case because what is returned is a temporary. but should try anyway in case this works... 308 // -------------------------------------------------------------------------- 309 // 310 //! Checks for changes in the existing services. 311 //! Any new service will be added to the service list, while the ones which disappeared are removed. 312 //! @todo 313 //! add the configuration (using the conf class ?) 314 // 315 void DataLogger::CheckForServicesUpdate() 316 { 317 318 //get the current server list 206 319 const std::vector<std::string> serverList = fServiceList.GetServerList(); 207 for (unsigned int i=0;i<serverList.size();i++) 208 {//get the service list associated with each server 209 if (strstr(serverList[i].c_str(), "DIS_DNS") || strstr(serverList[i].c_str(), "DATA_LOGGER")) 320 //first let's remove the servers that may have disapeared 321 //can't treat the erase on maps the same way as for vectors. Do it the safe way instead 322 std::vector<std::string> toBeDeleted; 323 for (SubscriptionsListType::iterator cListe = fServiceSubscriptions.begin(); cListe != fServiceSubscriptions.end(); cListe++) 324 { 325 std::vector<std::string>::const_iterator givenServers; 326 for (givenServers=serverList.begin(); givenServers!= serverList.end(); givenServers++) 327 if (cListe->first == *givenServers) 328 break; 329 if (givenServers == serverList.end())//server vanished. Remove it 330 toBeDeleted.push_back(cListe->first); 331 } 332 for (std::vector<std::string>::const_iterator it = toBeDeleted.begin(); it != toBeDeleted.end(); it++) 333 fServiceSubscriptions.erase(*it); 334 335 //now crawl through the list of servers, and see if there was some updates 336 for (std::vector<std::string>::const_iterator i=serverList.begin(); i!=serverList.end();i++) 337 { 338 //skip the two obvious excluded services 339 if ((i->find("DIS_DNS") != std::string::npos) || 340 (i->find("DATA_LOGGER") != std::string::npos)) 210 341 continue; 211 for (std::vector<std::string>::const_iterator j=fServiceList.begin(serverList[i]); j != fServiceList.end(serverList[i]); j++) 212 {//and subscribe to each service ! 213 fServiceSubscriptions[serverList[i]].push_back(DimStampedInfo(j->c_str(), const_cast<char*>(""), this)); 214 } 215 } 216 } 217 //! destructor 342 //find the current server in our subscription list 343 SubscriptionsListType::iterator cSubs = fServiceSubscriptions.find(*i); 344 //get the service list of the current server 345 std::vector<std::string> cServicesList = fServiceList.GetServiceList(*i); 346 if (cSubs != fServiceSubscriptions.end())//if the current server already is in our subscriptions 347 { //then check and update our list of subscriptions 348 //first, remove the services that may have dissapeared. 349 std::map<std::string, SubscriptionType>::iterator serverSubs; 350 std::vector<std::string>::const_iterator givenSubs; 351 toBeDeleted.clear(); 352 for (serverSubs=cSubs->second.begin(); serverSubs != cSubs->second.end(); serverSubs++) 353 { 354 for (givenSubs = cServicesList.begin(); givenSubs != cServicesList.end(); givenSubs++) 355 if (serverSubs->first == *givenSubs) 356 break; 357 if (givenSubs == cServicesList.end()) 358 { 359 toBeDeleted.push_back(serverSubs->first); 360 } 361 } 362 for (std::vector<std::string>::const_iterator it = toBeDeleted.begin(); it != toBeDeleted.end(); it++) 363 cSubs->second.erase(*it); 364 //now check for new services 365 for (givenSubs = cServicesList.begin(); givenSubs != cServicesList.end(); givenSubs++) 366 { 367 if (*givenSubs == "SERVICE_LIST") 368 continue; 369 if (cSubs->second.find(*givenSubs) == cSubs->second.end()) 370 {//service not found. Add it 371 cSubs->second[*givenSubs].dimInfo = new DimStampedInfo(((*i) + "/" + *givenSubs).c_str(), const_cast<char*>(""), this); 372 } 373 } 374 } 375 else //server not found in our list. Create its entry 376 { 377 fServiceSubscriptions[*i] = std::map<std::string, SubscriptionType>(); 378 std::map<std::string, SubscriptionType>& liste = fServiceSubscriptions[*i]; 379 for (std::vector<std::string>::const_iterator j = cServicesList.begin(); j!= cServicesList.end(); j++) 380 { 381 if (*j == "SERVICE_LIST") 382 continue; 383 liste[*j].dimInfo = new DimStampedInfo(((*i) + "/" + (*j)).c_str(), const_cast<char*>(""), this); 384 } 385 } 386 } 387 } 388 // -------------------------------------------------------------------------- 389 // 390 //! Destructor 391 // 218 392 DataLogger::~DataLogger() 219 393 { 220 if (fDailyFile.is_open()) 221 fDailyFile.close(); 222 if (fRunFile.is_open()) 223 fRunFile.close(); 224 ; 225 } 226 /**************************************************************** 227 * 228 * DATA LOGGER'S EXECUTE 229 * 230 ****************************************************************/ 231 //! Execute 232 //! Shouldn't be run as we use callbacks instead 394 //close the files 395 if (fDailyLogFile.is_open()) 396 fDailyLogFile.close(); 397 if (fDailyReportFile.is_open()) 398 fDailyReportFile.close(); 399 if (fRunLogFile.is_open()) 400 fRunLogFile.close(); 401 if (fRunReportFile.is_open()) 402 fRunReportFile.close(); 403 //release the services subscriptions 404 fServiceSubscriptions.clear(); 405 } 406 // -------------------------------------------------------------------------- 407 // 408 //! Execute 409 //! Shouldn't be run as we use callbacks instead 410 // 233 411 int DataLogger::Execute() 234 412 { … … 246 424 case kSM_BadRunConfig: 247 425 return GetCurrentState(); 248 249 426 } 250 427 //this line below should never be hit. It here mainly to remove warnings at compilation 251 428 return kSM_FatalError; 252 429 } 253 /**************************************************************** 254 * 255 * DATA LOGGER'S TRANSITION 256 * 257 ****************************************************************/ 258 259 //! Shouldn't be run as we use callbacks instead 430 // -------------------------------------------------------------------------- 431 // 432 //! Shouldn't be run as we use callbacks instead 433 // 260 434 int DataLogger::Transition(const Event& evt) 261 435 { … … 273 447 case kSM_BadRunConfig: 274 448 case kSM_Error: 275 return ResetPlease();449 return GoToReadyPlease(); 276 450 277 451 case kSM_Logging: 278 452 case kSM_WaitingRun: 279 453 case kSM_DailyOpen: 280 return StopPlease();454 return GoToReadyPlease(); 281 455 } 282 456 break; … … 319 493 return kSM_FatalError; 320 494 } 321 /**************************************************************** 322 * 323 * DATA LOGGER'S CONFIGURE 324 * 325 ****************************************************************/ 495 // -------------------------------------------------------------------------- 496 // 326 497 //! Shouldn't be run as we use callbacks instead 498 // 327 499 int DataLogger::Configure(const Event& evt) 328 500 { … … 344 516 case kSM_Logging: 345 517 case kSM_DailyOpen: 346 return LogMessagePlease(evt); 518 //TODO check that this is indeed correct 519 return 0;//LogMessagePlease(evt); 347 520 break; 348 521 … … 353 526 return kSM_FatalError; 354 527 } 355 /**************************************************************** 356 * 357 * DATA LOGGER'S INFOHANDLER 358 * 359 ****************************************************************/ 528 // -------------------------------------------------------------------------- 529 // 530 //! Inherited from DimInfo. Handles all the Infos to which we subscribed, and log them 531 // 360 532 void DataLogger::infoHandler() 361 533 { 362 534 DimInfo* I = getInfo(); 363 //there I should get the services updates. It remains unclear whether I will be getting the new services or not through here 364 // CheckForServicesUpdate(); //in this function I will add/remove services subscription 535 if (I==NULL) 536 { 537 CheckForServicesUpdate(); 538 return; 539 } 540 //check if the service pointer corresponds to something that we subscribed to 541 //this is a fix for a bug that provides bad Infos when a server starts 542 bool found = false; 543 SubscriptionsListType::iterator x; 544 std::map<std::string, SubscriptionType>::iterator y; 545 for (x=fServiceSubscriptions.begin(); x != fServiceSubscriptions.end(); x++) 546 {//instead of extracting the server and service names, I crawl through my records. dunno what's faster, but both should work 547 for (y=x->second.begin(); y!=x->second.end();y++) 548 if (y->second.dimInfo == I) 549 { 550 found = true; 551 break; 552 } 553 if (found) 554 break; 555 } 556 if (!found) 557 return; 558 if (I->getSize() <= 0) 559 return; 560 //check that the message has been updated by something, i.e. must be different from its initial value 561 if (I->getTimestamp() == 0) 562 return; 563 365 564 CheckForRunNumber(I); 366 LogPlease(I); 367 } 368 //! Checks for changes in the existingn services 369 //! @todo finish this function as most of it is still missing (plus what is already there isn't great) 370 void DataLogger::CheckForServicesUpdate() 371 {//TODO well... do it... 372 //TODO handle the cases were one server/service was removed and one was added 373 const std::vector<std::string> serverList = fServiceList.GetServerList(); 374 if (serverList.size() != fServiceSubscriptions.size()) 375 {//some servers were added/deleted. Rebuild the list entirely 376 std::cout << "Redoing the server list entirely " << serverList.size() << " " << fServiceSubscriptions.size() << std::endl; 377 std::map<std::string, std::vector<DimStampedInfo> >::iterator it; 378 for (it=fServiceSubscriptions.begin(); it != fServiceSubscriptions.end(); it++) 379 (*it).second.clear(); 380 fServiceSubscriptions.clear(); 381 InitServiceSubscription(); 382 return; 383 } 384 //TODO crawl the list to see if any of the servers has updated its service list 385 386 } 387 //! Looks whether the currently being processed DimInfo indeed is a run number or not 565 ReportPlease(I, y->second); 566 } 567 568 // -------------------------------------------------------------------------- 569 // 570 //! Checks whether or not the current info is a run number. 571 //! If so, then remember it. A run number is required to open the run-log file 572 //! @param I 573 //! the current DimInfo 574 // 388 575 void DataLogger::CheckForRunNumber(DimInfo* I) 389 576 { 390 577 return; 391 if (strstr(I->getName(), runNumberInfo) != NULL)578 if (strstr(I->getName(), fRunNumberInfo) != NULL) 392 579 {//assumes that the run number is an integer 393 580 //TODO check the format here 394 runNumber = I->getInt(); 395 } 396 } 397 /**************************************************************** 398 * 399 * DATA LOGGER'S RUN LOG 400 * 401 * write info to run log. Go to error if anything goes wrong 402 * 403 ****************************************************************/ 404 //! write info to logs. Go to error if anything goes wrong 405 void DataLogger::LogPlease(DimInfo* I) 406 { 407 if (I->getSize() == 0) 581 fRunNumber = I->getInt(); 582 } 583 } 584 // -------------------------------------------------------------------------- 585 // 586 //! write infos to log files. 587 //! @param I 588 //! The current DimInfo 589 // 590 void DataLogger::ReportPlease(DimInfo* I, SubscriptionType& sub) 591 { 592 //should we log or report this info ? (i.e. is it a message ?) 593 bool isItaReport = ((strstr(I->getName(), "Message") == NULL) && (strstr(I->getName(), "MESSAGE") == NULL)); 594 595 // std::ofstream & dailyFile = fDailyReportFile;//isItaReport? fDailyReportFile : fDailyLogFile; 596 // std::ofstream & runFile = fRunReportFile;//isItaReport? fRunReportFile : fRunLogFile; 597 598 //TODO add service exclusion 599 if (!fDailyReportFile.is_open()) 408 600 return; 409 //TODO add service exclusion 410 411 if (!fDailyFile.is_open()) 412 return; 601 413 602 //construct the header 414 603 std::stringstream header; 415 Time cTime((time_t)(I->getTimestamp()), 0); 416 header << I->getName() << " " << cTime.Y() << " " << cTime.M() << " " << cTime.D() << " "; 417 header << cTime.h() << " " << cTime.m() << " " << cTime.s() << " "; 418 header << cTime.ms() << " " << I->getQuality() << " "; 419 420 if (fDailyFile.is_open()) 421 fDailyFile << header; 422 if (fRunFile.is_open()) 423 fRunFile << header; 424 425 426 std::string text = ToString(I->getFormat(), I->getData(), I->getSize()); 427 428 if (!text.empty()) 429 {//replace bizarre characters by white space 604 605 Time cTime((time_t)(I->getTimestamp()), I->getTimestampMillisecs()); 606 607 //Buffer them for FITS write 608 //TODO this has been replaced by MjD. So I guess that these member variables can go. 609 fYear = cTime.Y(); fMonth = cTime.M(); fDay = cTime.D(); 610 fHour = cTime.h(); fMin = cTime.m(); fSec = cTime.s(); 611 fMs = cTime.ms(); fQuality = I->getQuality(); 612 613 fMjD = cTime.Mjd(); 614 615 if (isItaReport) 616 { 617 //write text header 618 header << I->getName() << " " << fQuality << " "; 619 header << fYear << " " << fMonth << " " << fDay << " "; 620 header << fHour << " " << fMin << " " << fSec << " "; 621 header << fMs << " " << I->getTimestamp() << " "; 622 623 Converter conv(std::cout, I->getFormat(), I->getData(), I->getSize()); 624 625 if (conv.Ptr() == NULL) 626 return; 627 628 std::string text(conv.Ptr()); 629 630 if (text.empty()) 631 return; 632 633 if (fDailyReportFile.is_open()) 634 fDailyReportFile << header.str(); 635 if (fRunReportFile.is_open()) 636 fRunReportFile << header.str(); 637 638 //replace bizarre characters by white space 430 639 for (unsigned int i=0; i<text.size(); i++) 431 640 { … … 436 645 text[i] = ' '; 437 646 } 438 if (fDaily File.is_open())439 fDaily File << text;440 if (fRun File.is_open())441 fRun File << text;647 if (fDailyReportFile.is_open()) 648 fDailyReportFile << text << std::endl; 649 if (fRunReportFile.is_open()) 650 fRunReportFile << text << std::endl; 442 651 } 443 652 else 444 653 { 445 if (fDailyFile.is_open()) 446 fDailyFile << "Cannot interpret service format" << std::endl; 447 if (fRunFile.is_open()) 448 fRunFile << "Cannot interpret service format" << std::endl; 449 } 450 } 451 //! Translates DIM data safely to string (assures no invalid memory accesses are made) 452 //! Was mostly copied from DColl.cc 453 std::string DataLogger::ToString(const char *format, const void *data, int size) { 454 455 std::ostringstream Text; 456 457 // Structure: print hex representation 458 if (strlen(format) != 1) { 459 for (int i=0; i<size; i++) { 460 Text << std::setw(2) << std::hex << *((char *) data + i) << " "; 461 } 462 return Text.str(); 463 } 464 465 // String if format "C" and terminated with \0 466 if (strcmp(format, "C") == 0 && size > 0 && *((char *) data+size-1)=='\0') { 467 return std::string((char *) data); 468 } 469 470 // Number array 471 int ElementSize; 472 switch (*format) { 473 case 'C': ElementSize = sizeof(char); break; 474 case 'I': 475 case 'L': ElementSize = sizeof(int); break; 476 case 'S': ElementSize = sizeof(short); break; 477 case 'F': ElementSize = sizeof(float); break; 478 case 'D': ElementSize = sizeof(double); break; 479 case 'X': ElementSize = sizeof(long long); break; 480 default: return std::string(); 481 } 482 483 for (int i=0; i<size/ElementSize; i++) { 484 // Space between entries 485 if (i != 0) Text << " "; 486 487 // Translate data 488 switch (*format) { 489 case 'C': Text << *((char *) data + i); break; 490 case 'I': 491 case 'L': Text << *((int *) data + i); break; 492 case 'S': Text << *((short *) data + i); break; 493 case 'F': Text << *((float *) data + i); break; 494 case 'D': Text << *((double *) data + i); break; 495 case 'X': Text << *((long long *) data + i); break; 496 } 497 } 498 499 return Text.str(); 500 } 501 //! write messages to logs. Go to error if anything goes wrong 654 std::string n = I->getName(); 655 std::stringstream msg; 656 msg << n.substr(0, n.find_first_of('/')) << ": " << I->getString(); 657 MessageImp dailyMess(fDailyLogFile); 658 dailyMess.Write(cTime, msg.str().c_str(), fQuality); 659 if (fRunLogFile.is_open()) 660 { 661 MessageImp runMess(fRunLogFile); 662 runMess.Write(cTime, msg.str().c_str(), fQuality); 663 } 664 } 665 666 if (!sub.dailyFile.IsOpen() || !sub.runFile.IsOpen()) 667 OpenFITSFilesPlease(sub); 668 WriteToFITS(sub); 669 670 671 } 672 // -------------------------------------------------------------------------- 673 // 674 //! write messages to logs. 675 //! @param evt 676 //! the current event to log 677 //! @returns 678 //! the new state. Currently, always the current state 679 // 680 //DEPREC I guess that this function should not be any longer 502 681 int DataLogger::LogMessagePlease(const Event& evt) 503 682 { 504 if (!fDaily File.is_open())683 if (!fDailyLogFile.is_open()) 505 684 return GetCurrentState(); 506 685 … … 510 689 header << cTime.h() << " " << cTime.m() << " " << cTime.s() << " "; 511 690 header << cTime.ms() << " "; 512 513 if (fDailyFile.is_open()) 514 fDailyFile << header;515 if ( fRunFile.is_open())516 fRunFile << header;517 518 std::string text = ToString(evt.GetFormat().c_str(), evt.GetData(), evt.GetSize());691 692 // std::string text = ToString(evt.GetFormat().c_str(), evt.GetData(), evt.GetSize()); 693 Converter conv(std::cout, evt.GetFormat().c_str(), evt.GetData(), evt.GetSize()); 694 if (conv.Ptr() == NULL) 695 return GetCurrentState(); 696 697 std::string text(conv.Ptr()); 519 698 520 699 if (!text.empty()) 521 {//replace bizarre characters by white space 700 { 701 if (fDailyLogFile.is_open()) 702 fDailyLogFile << header; 703 if (fRunLogFile.is_open()) 704 fRunLogFile << header; 705 706 //replace bizarre characters by white space 522 707 for (unsigned int i=0; i<text.size(); i++) 523 708 { … … 528 713 text[i] = ' '; 529 714 } 530 if (fDailyFile.is_open()) 531 fDailyFile << text; 532 if (fRunFile.is_open()) 533 fRunFile << text; 534 } 715 if (fDailyLogFile.is_open()) 716 fDailyLogFile << text; 717 if (fRunLogFile.is_open()) 718 fRunLogFile << text; 719 } 720 721 return GetCurrentState(); 722 } 723 // -------------------------------------------------------------------------- 724 // 725 //! Sets the path to use for the daily log file. 726 //! @param evt 727 //! the event transporting the path 728 //! @returns 729 //! currently only the current state. 730 // 731 int DataLogger::ConfigureDailyFileName(const Event& evt) 732 { 733 if (evt.GetText() != NULL) 734 fDailyFileName = std::string(evt.GetText()); 535 735 else 536 { 537 if (fDailyFile.is_open()) 538 fDailyFile << "Cannot interpret log message format" << std::endl; 539 if (fRunFile.is_open()) 540 fRunFile << "Cannot interpret log message format" << std::endl; 541 } 542 543 return GetCurrentState(); 544 } 545 /**************************************************************** 546 * 547 * DATA LOGGER'S RUN LOG 548 */ 549 //!Set the current daily file name. This will NOT close any file 550 /* 551 ****************************************************************/ 552 int DataLogger::ConfigureDailyFileName(const Event& evt) 553 { 554 fDailyFileName = std::string(evt.GetText()); 736 Error("Empty daily folder"); 737 555 738 return GetCurrentState(); 556 739 } 557 /**************************************************************** 558 * 559 * DATA LOGGER'S CONFIGURE RUN FILE NAME 560 * 561 */ 562 //! Set the current run folder name. This will NOT close any file 563 /* 564 ****************************************************************/ 740 // -------------------------------------------------------------------------- 741 // 742 //! Sets the path to use for the run log file. 743 //! @param evt 744 //! the event transporting the path 745 //! @returns 746 //! currently only the current state 565 747 int DataLogger::ConfigureRunFileName(const Event& evt) 566 748 { 567 fRunFileName = std::string(evt.GetText()); 749 if (evt.GetText() != NULL) 750 fRunFileName = std::string(evt.GetText()); 751 else 752 Error("Empty daily folder"); 753 568 754 return GetCurrentState(); 569 755 } 570 /**************************************************************** 571 * 572 * DATA LOGGER'S CONFIGURE RUN NUMBER 573 * 574 */ 575 //! set the current run number. This will NOT close any file. 576 /* 577 ****************************************************************/ 756 // -------------------------------------------------------------------------- 757 // 758 //! Sets the run number. 759 //! @param evt 760 //! the event transporting the run number 761 //! @returns 762 //! currently only the current state 578 763 int DataLogger::ConfigureRunNumber(const Event& evt) 579 764 { 580 runNumber = evt.GetInt();581 //TODO replace the run number in the filename if already exist. Otherwise just append it 765 fRunNumber = evt.GetInt(); 766 582 767 return GetCurrentState(); 583 768 } 584 /**************************************************************** 585 * 586 * DATA LOGGER'S START PLEASE 587 * 588 */ 589 //! Implements the start transition 590 /* 591 ****************************************************************/ 769 // -------------------------------------------------------------------------- 770 // 771 //! Implements the Start transition. 772 //! Concatenates the given path for the daily file and the filename itself (based on the day), 773 //! and tries to open it. 774 //! @returns 775 //! kSM_DailyOpen if success, kSM_BadDailyConfig if failure 592 776 int DataLogger::StartPlease() 593 777 { … … 598 782 std::string fullName = fDailyFileName + '/' + sTime.str() + ".log"; 599 783 600 fDailyFile.open(fullName.c_str(), std::ios_base::out | std::ios_base::ate); //maybe should be "app" instead of "ate" ?? 601 if (!fDailyFile.is_open()) 784 fDailyLogFile.open(fullName.c_str(), std::ios_base::out | std::ios_base::app); //maybe should be "app" instead of "ate" ?? 785 fullName = fDailyFileName + '/' + sTime.str() + ".rep"; 786 fDailyReportFile.open(fullName.c_str(), std::ios_base::out | std::ios_base::app); 787 if (!fDailyLogFile.is_open() || !fDailyReportFile.is_open()) 602 788 { 603 789 //TODO send an error message … … 606 792 return kSM_DailyOpen; 607 793 } 608 /**************************************************************** 609 * 610 * DATA LOGGER'S STOP PLEASE 611 * 612 */ 613 //! Implements the stop transition 614 /* 615 ****************************************************************/ 616 int DataLogger::StopPlease() 617 { 618 if (fDailyFile.is_open()) 619 fDailyFile.close(); 620 621 if (fRunFile.is_open()) 622 fRunFile.close(); 623 624 return kSM_Ready; 625 626 } 627 /**************************************************************** 628 * 629 * DATA LOGGER'S START RUN PLEASE 630 * 631 */ 632 //! Implements the start run transtition 633 /* 634 ****************************************************************/ 794 // -------------------------------------------------------------------------- 795 // 796 //! open if required a the FITS files corresponding to a given subscription 797 //! @param sub 798 //! the current DimInfo subscription being examined 799 void DataLogger::OpenFITSFilesPlease(SubscriptionType& sub) 800 { 801 std::string serviceName(sub.dimInfo->getName()); 802 for (unsigned int i=0;i<serviceName.size(); i++) 803 { 804 if (serviceName[i] == '/') 805 { 806 serviceName[i] = '_'; 807 break; 808 } 809 } 810 Time time; 811 std::stringstream sTime; 812 sTime << time.Y() << "_" << time.M() << "_" << time.D(); 813 //we open the dailyFile anyway, otherwise this function shouldn't have been called. 814 if (!sub.dailyFile.IsOpen()) 815 { 816 std::string partialName = fDailyFileName + '/' + sTime.str() + '_' + serviceName + ".fits"; 817 std::string fullName = fDailyFileName + '/' + sTime.str() + '_' + serviceName + ".fits[" + serviceName + "]"; 818 819 AllocateFITSBuffers(sub); 820 //currently, the FITS are written in the same directory as the text files. 821 //thus the write permissions have already been checked by the text files. 822 //if the target folder changes, then I should check the write permissions here 823 //now we only check whether the target file exists or not 824 std::ifstream readTest(partialName.c_str()); 825 if (readTest.is_open()) 826 { 827 readTest.close(); 828 sub.dailyFile.Open(fullName.c_str(), "UPDATE"); 829 } 830 else { 831 sub.dailyFile.Open(fullName.c_str(), "CREATE"); 832 } 833 834 //TODO Write the header's attributes 835 } 836 if (!sub.runFile.IsOpen() && (GetCurrentState() == kSM_Logging)) 837 {//buffer for the run file have already been allocated when doing the daily file 838 std::stringstream sRun; 839 sRun << fRunNumber; 840 std::string partialName = fRunFileName + '/' + sRun.str() + '_' + serviceName + ".fits"; 841 std::string fullName = fRunFileName + '/' + sRun.str() + '_' + serviceName + ".fits[" + serviceName + "]"; 842 843 std::ifstream readTest(partialName.c_str()); 844 if (readTest.is_open()) 845 { 846 readTest.close(); 847 sub.runFile.Open(fullName.c_str(), "UPDATE"); 848 } 849 else 850 sub.runFile.Open(fullName.c_str(), "CREATE"); 851 //TODO Write the header's attributes 852 } 853 } 854 // -------------------------------------------------------------------------- 855 // 856 void DataLogger::AllocateFITSBuffers(SubscriptionType& sub) 857 { 858 const char* format = sub.dimInfo->getFormat(); 859 const int size = sub.dimInfo->getSize(); 860 861 //Init the time columns of the file 862 sub.dailyFile.InitCol("Date", "double", &fMjD); 863 sub.runFile.InitCol("Date", "double", &fMjD); 864 865 // sub.dailyFile.InitCol("Year", "short", &fYear); 866 // sub.dailyFile.InitCol("Month", "short", &fMonth); 867 // sub.dailyFile.InitCol("Day", "short", &fDay); 868 // sub.dailyFile.InitCol("Hour", "short", &fHour); 869 // sub.dailyFile.InitCol("Minute", "short", &fMin); 870 // sub.dailyFile.InitCol("Second", "short", &fSec); 871 // sub.dailyFile.InitCol("MilliSec", "int", &fMs); 872 sub.dailyFile.InitCol("QoS", "int", &fQuality); 873 874 // sub.runFile.InitCol("Year", "short", &fYear); 875 // sub.runFile.InitCol("Month", "short", &fMonth); 876 // sub.runFile.InitCol("Day", "short", &fDay); 877 // sub.runFile.InitCol("Hour", "short", &fHour); 878 // sub.runFile.InitCol("Minute", "short", &fMin); 879 // sub.runFile.InitCol("Second", "short", &fSec); 880 // sub.runFile.InitCol("MilliSec", "int", &fMs); 881 sub.runFile.InitCol("QoS", "int", &fQuality); 882 883 Converter::FormatList flist = Converter::Convert(std::cout, std::string(format)); 884 885 //we've got a nice structure describing the format of this service's messages. 886 //Let's create the appropriate FITS columns 887 for (unsigned int i=0;i<flist.size();i++) 888 { 889 std::stringstream colName; 890 std::stringstream dataQualifier; 891 void * dataPointer = static_cast<char*>(sub.dimInfo->getData()) + flist[i].second.second; 892 colName << "Data" << i; 893 dataQualifier << flist[i].second.first; 894 switch (flist[i].first.first) 895 { 896 case 'c': 897 dataQualifier << "S"; 898 break; 899 case 's': 900 dataQualifier << "I"; 901 break; 902 case 'i': 903 dataQualifier << "J"; 904 break; 905 case 'l': 906 dataQualifier << "J"; 907 //TODO triple check that in FITS, long = int 908 break; 909 case 'f': 910 dataQualifier << "E"; 911 break; 912 case 'd': 913 dataQualifier << "D"; 914 break; 915 case 'x': 916 dataQualifier << "K"; 917 break; 918 case 'S': 919 //for strings, the number of elements I get is wrong. Correct it 920 dataQualifier.str(""); //clear 921 dataQualifier << size-1 << "A"; 922 break; 923 924 default: 925 Error("THIS SHOULD NEVER BE REACHED. dataLogger.cc ln 962."); 926 }; 927 sub.dailyFile.InitCol(colName.str().c_str(), dataQualifier.str().c_str(), dataPointer); 928 sub.runFile.InitCol(colName.str().c_str(), dataQualifier.str().c_str(), dataPointer); 929 } 930 931 //TODO init the attributes 932 } 933 // -------------------------------------------------------------------------- 934 // 935 //! write a dimInfo data to its corresponding FITS files 936 // 937 void DataLogger::WriteToFITS(SubscriptionType& sub) 938 { 939 //dailyFile status (open or not) already checked 940 if (sub.dailyFile.IsOpen()) 941 sub.dailyFile.Write(); 942 if (sub.runFile.IsOpen()) 943 sub.runFile.Write(); 944 } 945 // -------------------------------------------------------------------------- 946 // 947 //! Implements the StartRun transition. 948 //! Concatenates the given path for the run file and the filename itself (based on the run number), 949 //! and tries to open it. 950 //! @returns 951 //! kSM_Logging if success, kSM_BadRunConfig if failure. 635 952 int DataLogger::StartRunPlease() 636 953 { 637 954 //attempt to open run file with current parameters 638 if ( runNumber == -1)955 if (fRunNumber == -1) 639 956 return kSM_BadRunConfig; 640 957 std::stringstream sRun; 641 sRun << runNumber;958 sRun << fRunNumber; 642 959 std::string fullName = fRunFileName + '/' + sRun.str() + ".log"; 643 644 fRunFile.open(fullName.c_str(), std::ios_base::out | std::ios_base::ate); //maybe should be app instead of ate 645 if (!fRunFile.is_open()) 960 fRunLogFile.open(fullName.c_str(), std::ios_base::out | std::ios_base::app); //maybe should be app instead of ate 961 962 fullName = fRunFileName + '/' + sRun.str() + ".rep"; 963 fRunReportFile.open(fullName.c_str(), std::ios_base::out | std::ios_base::app); 964 965 if (!fRunLogFile.is_open() || !fRunReportFile.is_open()) 646 966 { 647 967 //TODO send an error message … … 651 971 return kSM_Logging; 652 972 } 653 /**************************************************************** 654 * 655 * DATA LOGGER'S STOP RUN PLEASE 656 * 657 */ 658 //! Implements the stop run transition 659 /* 660 ****************************************************************/ 973 // -------------------------------------------------------------------------- 974 // 975 //! Implements the StopRun transition. 976 //! Attempts to close the run file. 977 //! @returns 978 //! kSM_WaitingRun if success, kSM_FatalError otherwise 661 979 int DataLogger::StopRunPlease() 662 980 { 663 if (!fRun File.is_open())981 if (!fRunLogFile.is_open() || !fRunReportFile.is_open()) 664 982 return kSM_FatalError; 665 983 666 fRunFile.close(); 667 984 fRunLogFile.close(); 985 fRunReportFile.close(); 986 for (SubscriptionsListType::iterator i = fServiceSubscriptions.begin(); i != fServiceSubscriptions.end(); i++) 987 for (std::map<std::string, SubscriptionType>::iterator j = i->second.begin(); j != i->second.end(); j++) 988 { 989 if (j->second.runFile.IsOpen()) 990 j->second.runFile.Close(); 991 } 668 992 return kSM_WaitingRun; 669 993 670 994 } 671 /**************************************************************** 672 * 673 * DATA LOGGER'S RESET PLEASE 674 * 675 */ 676 //! Implements the reset transition 677 /* 678 ****************************************************************/ 679 int DataLogger::ResetPlease() 680 { 681 if (fDailyFile.is_open()) 682 fDailyFile.close(); 683 684 if (fRunFile.is_open()) 685 fRunFile.close(); 686 995 // -------------------------------------------------------------------------- 996 // 997 //! Implements the Stop and Reset transitions. 998 //! Attempts to close any openned file. 999 //! @returns 1000 //! kSM_Ready 1001 int DataLogger::GoToReadyPlease() 1002 { 1003 if (fDailyLogFile.is_open()) 1004 fDailyLogFile.close(); 1005 if (fDailyReportFile.is_open()) 1006 fDailyReportFile.close(); 1007 1008 if (fRunLogFile.is_open()) 1009 fRunLogFile.close(); 1010 if (fRunReportFile.is_open()) 1011 fRunReportFile.close(); 1012 1013 for (SubscriptionsListType::iterator i = fServiceSubscriptions.begin(); i != fServiceSubscriptions.end(); i++) 1014 for (std::map<std::string, SubscriptionType>::iterator j = i->second.begin(); j != i->second.end(); j++) 1015 { 1016 if (j->second.dailyFile.IsOpen()) 1017 j->second.dailyFile.Close(); 1018 if (j->second.runFile.IsOpen()) 1019 j->second.runFile.Close(); 1020 } 687 1021 return kSM_Ready; 688 1022 } 689 //! Implements the Daily to WaitRun transition 1023 // -------------------------------------------------------------------------- 1024 // 1025 //! Implements the transition towards kSM_WaitingRun 1026 //! Does nothing really. 1027 //! @returns 1028 //! kSM_WaitingRun 690 1029 int DataLogger::DailyToWaitRunPlease() 691 1030 { 692 1031 return kSM_WaitingRun; 693 1032 } 694 /* 695 bool DataLogger::ServiceOk(DimInfo* item) 696 { 697 return !((item->getSize() == strlen(NO_LINK)+1) && (memcmp(item->getData(), NO_LINK, item->getSize()) == 0)); 698 }*/ 699 /**************************************************************** 700 * 701 * MAIN 702 * 703 ****************************************************************/ 704 extern bool CheckDim(bool=true); 705 1033 1034 // -------------------------------------------------------------------------- 1035 // 706 1036 int main() 707 1037 { 708 std::cout << "Data Logger Starting" << std::endl; 709 710 if (!CheckDim()) 711 return -1; 712 713 std::cout << "Continuing" << std::endl; 1038 //No more Dim Checking ?? 1039 // if (!CheckDim()) 1040 // return -1; 1041 714 1042 DataLogger log; 715 std::cout << "DataLogger created. Starting main loop" << std::endl; 716 while (!log.IsRExitRequested()) 717 { 718 usleep(1); 1043 while (!log.fExitRequested) 1044 { 1045 usleep(10); 719 1046 } 720 1047 return 0;
Note:
See TracChangeset
for help on using the changeset viewer.