FACT++  1.0
void DataLogger::Report ( const EventImp evt,
SubscriptionType sub 
)
private

Reporting method for the services info received.

Get SunRise. Copied from drivectrl.cc Used to know when to close and reopen fileswrite infos to log files.

Parameters
IThe current DimInfo
subThe dataLogger's subscription corresponding to this DimInfo

Definition at line 1319 of file datalogger.cc.

References CheckForOfstreamError(), CompileFileNameWithPath(), MessageImp::Debug(), MessageImp::Error(), SubscriptionType::fConv, fCurrentDay, fQuality, StateMachineImp::GetCurrentState(), EventImp::GetData(), EventImp::GetFormat(), EventImp::GetName(), Time::GetNextSunRise(), EventImp::GetQoS(), EventImp::GetSize(), EventImp::GetTime(), GoToReady(), MessageImp::Info(), MessageImp::kAlarm, MessageImp::kInfo, MessageImp::kMessage, kSM_BadFolder, StateMachineImp::kSM_Ready, lastFlush, SubscriptionType::lastReceivedEvent, OpenTextFile(), MessageImp::Out(), RemoveService(), SubscriptionType::server, SubscriptionType::service, StateMachineDim::SetCurrentState(), str, updateSubscriptionList(), and MessageImp::Write().

Referenced by infoCallback().

1320 {
1321  const string fmt(evt.GetFormat());
1322 
1323  const bool isItaReport = fmt!="C";
1324 
1325  if (!fNightlyLogFile.is_open())
1326  return;
1327 
1328  if (fDebugIsOn && string(evt.GetName())!="DATA_LOGGER/MESSAGE")
1329  {
1330  ostringstream str;
1331  str << "Logging " << evt.GetName() << " [" << evt.GetFormat() << "] (" << evt.GetSize() << ")";
1332  Debug(str);
1333  }
1334 
1335  //
1336  // Check whether we should close and reopen daily text files or not
1337  // calculate time "centered" around noon instead of midnight
1338  // if number of days has changed, then files should be closed and reopenned.
1339  const Time timeNow;
1340 // const Time nowMinusTwelve = timeNow-boost::posix_time::hours(12);
1341 // int newDayNumber = (int)(nowMinusTwelve.Mjd());
1342 
1343  //also check if we should flush the nightly files
1344  if (lastFlush < timeNow-boost::posix_time::minutes(1))
1345  {
1346  lastFlush = timeNow;
1347  SubscriptionsListType::iterator x;
1348  map<string, SubscriptionType>::iterator y;
1349  for (x=fServiceSubscriptions.begin(); x != fServiceSubscriptions.end(); x++)
1350  {//find current service is subscriptions
1351  for (y=x->second.begin(); y!=x->second.end();y++)
1352  if (y->second.nightlyFile.IsOpen())
1353  {
1354  y->second.nightlyFile.Flush();
1355  }
1356  }
1357  if (fDebugIsOn)
1358  Debug("Just flushed nightly fits files to the disk");
1359  }
1360  //check if we should close and reopen the nightly files
1361  if (timeNow > fCurrentDay)//GetSunRise(fCurrentDay)+boost::posix_time::minutes(30)) //if we went past 30 minutes after sunrise
1362  {
1363  //set the next closing time. If we are here, we have passed 30 minutes after sunrise.
1364  fCurrentDay = timeNow.GetNextSunRise();//GetSunRise(timeNow-boost::posix_time::minutes(30))+boost::posix_time::minutes(30);
1365  //crawl through the subcriptions and close any open nightly file
1366  SubscriptionsListType::iterator x;
1367  map<string, SubscriptionType>::iterator y;
1368  for (x=fServiceSubscriptions.begin(); x != fServiceSubscriptions.end(); x++)
1369  {//find current service is subscriptions
1370  for (y=x->second.begin(); y!=x->second.end();y++)
1371  {
1372  if (y->second.nightlyFile.IsOpen())
1373  {
1374  y->second.nightlyFile.Close();
1375  }
1376  y->second.increment = 0;
1377  }
1378  }
1379 
1380  if (fDebugIsOn)
1381  Debug("Day have changed! Closing and reopening nightly files");
1382 
1383  fNightlyLogFile << endl;
1384  fNightlyLogFile.close();
1385 // fNightlyReportFile.close();
1386 
1387  Info("Closed: "+fFullNightlyLogFileName);
1388 // Info("Closed: "+fFullNightlyReportFileName);
1389 
1392  {
1393  GoToReady();
1394  SetCurrentState(kSM_BadFolder, "Report");
1395  return;
1396  }
1397  fNightlyLogFile << endl;
1398 
1399 // fFullNightlyReportFileName = CompileFileNameWithPath(fFilePath, "", "rep");
1400 // if (!OpenTextFile(fNightlyReportFile, fFullNightlyReportFileName))
1401 // {
1402 // GoToReady();
1403 // SetCurrentState(kSM_BadFolder, "Report");
1404 // return;
1405 // }
1406  }
1407  //create the converter for that service
1408  if (!sub.fConv)
1409  {
1410  sub.fConv = shared_ptr<Converter>(new Converter(Out(), evt.GetFormat()));
1411  if (!sub.fConv->valid())
1412  {
1413  ostringstream str;
1414  str << "Couldn't properly parse the format... service " << evt.GetName() << " ignored.";
1415  Error(str);
1416  return;
1417  }
1418  }
1419  //construct the header
1420  ostringstream header;
1421  const Time cTime(evt.GetTime());
1422  fQuality = evt.GetQoS();
1423 
1424  //update subscription last received time
1425  sub.lastReceivedEvent = cTime;
1426  //update subscription list service if required
1428 
1429  fMjD = cTime.Mjd() ? cTime.Mjd()-40587 : 0;
1430 
1431  if (isItaReport)
1432  {
1433 //DISABLED REPORT WRITING BY THOMAS REQUEST
1434  //write text header
1435 /* string serviceName = (sub.service == "MESSAGE") ? "" : "_"+sub.service;
1436  header << sub.server << serviceName << " " << fQuality << " ";
1437  header << evt.GetTime() << " ";
1438 
1439  string text;
1440  try
1441  {
1442  text = sub.fConv->GetString(evt.GetData(), evt.GetSize());
1443  }
1444  catch (const runtime_error &e)
1445  {
1446  ostringstream str;
1447  str << "Parsing service " << evt.GetName();
1448  str << " failed: " << e.what() << " removing the subscription to " << sub.server << "/" << sub.service;
1449  Warn(str);
1450  //remove this subscription from the list.
1451  //because these operators use references to elements, and because they're supposed here to erase these objects on the way, I'm not too sure... so duplicate the names !
1452  RemoveService(sub.server, sub.service, false);
1453  return;
1454  }
1455 
1456  if (text.empty())
1457  {
1458  ostringstream str;
1459  str << "Service " << evt.GetName() << " sent an empty string";
1460  Info(str);
1461  return;
1462  }
1463  //replace bizarre characters by white space
1464  replace(text.begin(), text.end(), '\n', '\\');
1465  replace_if(text.begin(), text.end(), ptr_fun<int, int>(&iscntrl), ' ');
1466 
1467  //write entry to Nightly report
1468  if (fNightlyReportFile.is_open())
1469  {
1470  fNightlyReportFile << header.str() << text << endl;
1471  if (!CheckForOfstreamError(fNightlyReportFile, true))
1472  return;
1473  }
1474 */
1475 #ifdef HAVE_FITS
1476  //check if the last received event was before noon and if current one is after noon.
1477  //if so, close the file so that it gets reopened.
1478 // sub.lastReceivedEvent = cTime;
1479  if (!sub.nightlyFile.IsOpen())
1480  if (GetCurrentState() != kSM_Ready)
1481  OpenFITSFiles(sub);
1482  WriteToFITS(sub, evt.GetData());
1483 #endif
1484  }
1485  else
1486  {//write entry to Nightly log
1487  vector<string> strings;
1488  try
1489  {
1490  strings = sub.fConv->ToStrings(evt.GetData());
1491  }
1492  catch (const runtime_error &e)
1493  {
1494  ostringstream str;
1495  str << "Parsing service " << evt.GetName();
1496  str << " failed: " << e.what() << " removing the subscription for now.";
1497  Error(str);
1498  //remove this subscription from the list.
1499  //because these operators use references to elements, and because they're supposed here to erase these objects on the way, I'm not too sure... so duplicate the names !
1500  RemoveService(sub.server, sub.service, false);
1501  return;
1502  }
1503  if (strings.size() > 1)
1504  {
1505  ostringstream err;
1506  err << "There was more than one string message in service " << evt.GetName() << " going to fatal error state";
1507  Error(err.str());
1508  }
1509 
1510  bool isMessage = (sub.service == "MESSAGE");
1511  ostringstream msg;
1512  string serviceName = isMessage ? "" : "_"+sub.service;
1513  msg << sub.server << serviceName;
1514 
1515 
1516  //in case of non messages message (i.e. binary data written to logs)
1517  //we override the quality before writing to .log, otherwise it will wrongly decorate the log entry
1518  //because fQuality is really the system state in some cases.
1519  //so save a backup of the original value before writing to fits
1520  int backup_quality = fQuality;
1521 
1522  //fix the quality of non message "messages"
1523  if (!isMessage)
1524  {
1525  msg << "[" << fQuality << "]";
1526  fQuality = kMessage;
1527  }
1528 
1529  //special case for alarm reset
1530  if (isMessage && (fQuality == kAlarm) && (strings[0] == ""))
1531  {
1532  fQuality = kInfo;
1533  strings[0] = "Alarm reset";
1534  }
1535  msg << ": " << strings[0];
1536 
1537  if (fNightlyLogFile.is_open())
1538  {
1539  fNightlyLogImp.Write(cTime, msg.str().c_str(), fQuality);
1541  return;
1542  }
1543 
1544  //in case we have overriden the fQuality before writing to log, restore the original value before writing to FITS
1545  if (!isMessage)
1546  fQuality = backup_quality;
1547 
1548 // sub.lastReceivedEvent = cTime;
1549  if (!sub.nightlyFile.IsOpen())
1550  if (GetCurrentState() != kSM_Ready)
1551  OpenFITSFiles(sub);
1552  WriteToFITS(sub, evt.GetData());
1553  }
1554 }
the folder specified for Nightly logging does not exist or has bad permissions
Definition: datalogger.cc:188
void updateSubscriptionList()
update the service
Definition: datalogger.cc:433
Mainloop running, state machine in operation.
int GetCurrentState() const
return the current state of the machine
int Debug(const std::string &str)
Definition: MessageImp.h:45
ofstream fNightlyLogFile
ofstream for the NightlyLogfile
Definition: datalogger.cc:203
Adds some functionality to boost::posix_time::ptime for our needs.
Definition: Time.h:30
char str[80]
Definition: test_client.c:7
Time GetNextSunRise(double horizon) const
Definition: Time.cc:346
bool fDebugIsOn
configuration flags
Definition: datalogger.cc:315
bool CheckForOfstreamError(ofstream &out, bool isDailyStream)
Checks if the input osftream is in error state, and if so close it.
Definition: datalogger.cc:725
Time lastReceivedEvent
time of the latest received event
Definition: datalogger.cc:143
string fFilePath
ofstream for the Nightly report file
Definition: datalogger.cc:209
std::ostream & Out() const
Definition: MessageImp.h:73
An info telling something which can be interesting to know.
Definition: MessageImp.h:17
Just a message, usually obsolete.
Definition: MessageImp.h:16
int GoToReady()
stop and reset transition
Definition: datalogger.cc:2151
virtual int Write(const Time &time, const std::string &txt, int qos=kMessage)
Definition: MessageImp.cc:133
Time fCurrentDay
Definition: datalogger.cc:397
virtual Time GetTime() const
Definition: EventImp.h:57
virtual std::string GetFormat() const
Definition: EventImp.h:52
int Error(const std::string &str)
Definition: MessageImp.h:49
virtual int GetQoS() const
Definition: EventImp.h:58
string server
the server
Definition: datalogger.cc:133
bool OpenTextFile(ofstream &stream, const string &name)
Subscribe to a given server and service.
Definition: datalogger.cc:782
int fQuality
Current Service Quality.
Definition: datalogger.cc:217
SubscriptionsListType fServiceSubscriptions
All the services to which we have subscribed to, sorted by server name.
Definition: datalogger.cc:224
shared_ptr< Converter > fConv
the converter for outputting the data according to the format
Definition: datalogger.cc:137
virtual std::string GetName() const
Definition: EventImp.h:51
Error, something unexpected happened, but needs user intervention (i.e. it needs a signal to the user...
Definition: MessageImp.h:20
void RemoveService(const string, const string, bool)
Remove a given service subscription.
Definition: datalogger.cc:659
double fMjD
Modified Julian Date.
Definition: datalogger.cc:219
int Info(const std::string &str)
Definition: MessageImp.h:47
string fFullNightlyLogFileName
full name of the nightly log file
Definition: datalogger.cc:226
MessageImp fNightlyLogImp
Log stream to fNightlyLogFile.
Definition: datalogger.cc:205
virtual const void * GetData() const
Definition: EventImp.h:54
A compiler for the DIM data format string.
Definition: Converter.h:16
Time lastFlush
Definition: datalogger.cc:398
string service
the service
Definition: datalogger.cc:135
string CompileFileNameWithPath(const string &path, const string &service, const string &extension)
Get the digits of year, month and day for filenames and paths.
Definition: datalogger.cc:851
virtual size_t GetSize() const
Definition: EventImp.h:55
std::string SetCurrentState(int state, const char *txt="", const std::string &cmd="")

+ Here is the call graph for this function:

+ Here is the caller graph for this function: