Changeset 10529 for trunk/FACT++/src


Ignore:
Timestamp:
05/03/11 14:04:37 (13 years ago)
Author:
lyard
Message:
Various bug fixes and new commands added
Location:
trunk/FACT++/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/FACT++/src/Fits.cc

    r10489 r10529  
    143143                std::string factTableName = "FACT-" + tableName;
    144144                fTable = fFile->addTable(factTableName, 0, allNames, allDataTypes, allUnits);
     145                fTable->makeThisCurrent();
    145146                fCopyBuffer = new unsigned char[fTotalNumBytes];
    146147                fNumRows = fTable->rows();
    147148                if (fNumRows !=0)
    148149                {//If the file already existed, then we must load its data to memory before writing to it.
    149                         std::vector<std::string> tableNameString;
    150                         tableNameString.push_back(tableName);
    151                         fFile->read(tableNameString);   
     150                        BinTable* bTable = dynamic_cast<BinTable*>(fTable);
     151                        if (!bTable)
     152                        {
     153                                fMess->Error("The table " + factTableName + " could not be converted to a binary table. skipping");
     154                                return;
     155                        }       
     156                        //read the table binary data.
     157                        std::vector<string> colName;
     158                        bTable->readData(true, colName);
     159
     160                        //double check that the data was indeed read from the disk. Go through the fTable instead as colName is empty (yes, it is !)
    152161                        std::map<std::string, Column*> cMap = fTable->column();
    153162                        std::map<std::string, Column*>::iterator cMapIt;
     163
    154164                        for (cMapIt = cMap.begin(); cMapIt != cMap.end(); cMapIt++)
    155165                        {
    156                                 //TODO this only works for scalar columns I assume. upgrade it to fully read vector columns
    157                                 cMapIt->second->readData(1, fNumRows);         
    158                         }       
     166                                if (!cMapIt->second->isRead())
     167                                {
     168                                        fMess->Error("Column " + cMapIt->first + "Could not be read back from the disk");
     169                                        return;
     170                                }       
     171                        }
    159172                        updating = true;
    160173                }
     
    255268{
    256269
    257         fTable->makeThisCurrent();
    258270        try
    259271        {
     272                fTable->makeThisCurrent();
    260273                fTable->insertRows(fNumRows);
    261274        }
  • trunk/FACT++/src/dataLogger.cc

    r10499 r10529  
    1414        e [label="Error" color="red"];
    1515   r [label="Ready"]
    16    d [label="DailyOpen"]
     16   d [label="NightlyOpen"]
    1717   w [label="WaitingRun"]
    1818        l [label="Logging"]
    19    b [label="BadDailyconfig" color="red"]
     19   b [label="BadNightlyconfig" color="red"]
    2020   c [label="BadRunConfig" color="red"]
    2121 
     
    5555#include "Description.h"
    5656
     57#include "DimServiceInfoList.h"
     58
    5759//for getting stat of opened files
    5860#include <unistd.h>
     
    7678//Dim structures
    7779struct DataLoggerStats {
    78         long long sizeWritten;
    79         long long freeSpace;
     80        long sizeWritten;
     81        long freeSpace;
    8082        long writingRate;
    8183};
     
    8486        int numSubscriptions;
    8587        int numOpenFits;
     88};
     89
     90struct OpenFileToDim {
     91        int code;
     92        char fileName[FILENAME_MAX];
    8693};
    8794//For debugging DIM's services
     
    96103        void setQuality(int){};
    97104};
    98 class DataLogger : public StateMachineDim, DimInfoHandler
     105class DataLogger : public StateMachineDim, DimInfoHandler//, DimServiceInfoList //,DimInfoHandler
    99106{
    100107public:
     
    102109        enum
    103110        {
    104                 kSM_DailyOpen = 20, ///< Daily file openned and writing
     111                kSM_NightlyOpen = 20, ///< Nightly file openned and writing
    105112                kSM_WaitingRun = 30, ///< waiting for the run number to open the run file
    106113                kSM_Logging = 40, ///< both files openned and writing
    107                 kSM_BadDailyConfig = 0x101, ///< the folder specified for daily logging does not exist or has bad permissions
     114                kSM_BadNightlyConfig = 0x101, ///< the folder specified for Nightly logging does not exist or has bad permissions
    108115                kSM_BadRunConfig = 0x102, ///<  the folder specified for the run logging does not exist or has wrong permissions or no run number
    109116        } localstates_t;
    110117       
    111         DataLogger(std::ostream &out);
     118    DataLogger(std::ostream &out);
    112119        ~DataLogger();
    113120       
    114121private:
    115122        //Define all the data structure specific to the DataLogger here
    116         /// ofstream for the dailyLogfile
    117         std::ofstream fDailyLogFile;
     123        /// ofstream for the NightlyLogfile
     124        std::ofstream fNightlyLogFile;
    118125        /// ofstream for the run-specific Log file
    119126        std::ofstream fRunLogFile;
    120127
    121         /// ofstream for the daily report file
    122         std::ofstream fDailyReportFile;
     128        /// ofstream for the Nightly report file
     129        std::ofstream fNightlyReportFile;
    123130        /// ofstream for the run-specific report file
    124131        std::ofstream fRunReportFile;
    125         /// base path of the dailyfile
    126         std::string fDailyFileName;
     132        /// base path of the Nightlyfile
     133        std::string fNightlyFileName;
    127134        ///base path of the run file
    128135        std::string fRunFileName;
     
    146153        static const char* fTransWait;
    147154        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
    148        
     155        static const char* fPrintCommand;
     156        static const char* fDebugOnOff;
     157        static const char* fStatsPeriod;
     158        static const char* fStartStopOpenedFiles;
     159        static const char* fStartStopNumSubsAndFits;
    149160        //overloading of DIM's infoHandler function
    150161        void infoHandler();
     
    153164        ServiceList fServiceList;
    154165       
    155        
    156         ///A std pair to store both the DimInfo name and the actual DimInfo pointer
    157 //      typedef std::pair<std::string, DimStampedInfo*> subscriptionType;
    158         ///All the services to which we've subscribed to. Sorted by server name
    159 //      std::map<const std::string, std::vector<subscriptionType > > fServiceSubscriptions;
    160 
    161166        ///A std pair to store both the DimInfo pointer and the corresponding outputted fits file
    162167        struct SubscriptionType
    163168        {
    164169#ifdef HAS_FITS
    165                 ///daily FITS output file
    166                 Fits    dailyFile;
     170                ///Nightly FITS output file
     171                Fits    nightlyFile;
    167172                ///run-specific FITS output file
    168173                Fits    runFile;
     
    178183                {
    179184#ifdef HAS_FITS
    180                         dailyFile = other.dailyFile;
     185                        nightlyFile = other.nightlyFile;
    181186                        runFile = other.runFile;
    182187#endif
     
    189194                {
    190195#ifdef HAS_FITS
    191                         dailyFile = other.dailyFile;
     196                        nightlyFile = other.nightlyFile;
    192197                        runFile = other.runFile;
    193198#endif
     
    219224                                delete dimInfo;
    220225#ifdef HAS_FITS
    221                                 if (dailyFile.IsOpen())
    222                                         dailyFile.Close();
     226                                if (nightlyFile.IsOpen())
     227                                        nightlyFile.Close();
    223228                                if (runFile.IsOpen())
    224229                                        runFile.Close();
     
    237242        SubscriptionsListType fServiceSubscriptions;
    238243
    239 
    240244        ///Reporting method for the services info received
    241245        void ReportPlease(DimInfo* I, SubscriptionType& sub); 
    242246
    243         ///Configuration of the daily file path
    244         int ConfigureDailyFileName(const Event& evt);
     247        ///Configuration of the nightly file path
     248        int ConfigureNightlyFileName(const Event& evt);
    245249        ///Configuration fo the file name
    246250        int ConfigureRunFileName(const Event& evt);
     
    249253        ///logging method for the messages
    250254        int LogMessagePlease(const Event& evt);
     255        ///print the current state of the dataLogger
     256        int PrintStatePlease(const Event& evt);
    251257        ///checks whether or not the current info being treated is a run number
    252258        void CheckForRunNumber(DimInfo* I);
     
    259265        ///stop and reset transition
    260266        int GoToReadyPlease();
    261         ///from dailyOpen to waiting transition
    262         int DailyToWaitRunPlease();
     267        ///from NightlyOpen to waiting transition
     268        int NightlyToWaitRunPlease();
    263269#ifdef HAS_FITS
    264270        ///Open fits files
     
    286292        bool fContinueMonitoring;
    287293        ///required for accurate monitoring
    288         std::map<std::string, long long> fFileSizesMap;
    289         std::string fFullDailyLogFileName;
    290         std::string fFullDailyReportFileName;
     294        std::map<std::string, long> fFileSizesMap;
     295        std::string fFullNightlyLogFileName;
     296        std::string fFullNightlyReportFileName;
    291297        std::string fFullRunLogFileName;
    292298        std::string fFullRunReportFileName;
    293         long long fBaseSizeDaily;
    294         long long fPreviousSize;
    295         long long fBaseSizeRun;
     299        long fBaseSizeNightly;
     300        long fPreviousSize;
     301        long fBaseSizeRun;
    296302        ///Service for opened files
    297         DimDescribedService* fOpenedDailyFiles;
     303        DimDescribedService* fOpenedNightlyFiles;
    298304        DimDescribedService* fOpenedRunFiles;
    299305        DimDescribedService* fNumSubAndFits;
    300306        NumSubAndFitsType fNumSubAndFitsData;
    301 //      char* fDimBuffer;
    302         inline void NotifyOpenedFile(std::string name, int type, DimService* service);
    303         inline void NotifyOpenedFile(std::string , int , MyService* ){}
    304        
     307
     308        inline void NotifyOpenedFile(std::string name, int type, DimDescribedService* service);
     309public:
     310        void setBlackWhiteList(const std::string& , bool);
     311private:
     312        std::set<std::string> fGreyList;
     313        bool fIsBlackList;
     314        bool fDebugIsOn;
     315        float fStatsPeriodDuration;
     316        bool fOpenedFilesIsOn;
     317        bool fNumSubAndFitsIsOn;
     318        //functions for controlling the services behavior
     319        int SetDebugOnOff(const Event& evt);
     320        int SetStatsPeriod(const Event& evt);
     321        int SetOpenedFilesOnOff(const Event& evt);
     322        int SetNumSubsAndFitsOnOff(const Event& evt);
     323        bool getBooleanFromString(const std::string&);
     324        ///boolean to prevent DIM update while desctructing the dataLogger
     325        bool fDestructing;     
    305326}; //DataLogger
    306327
     
    318339const char* DataLogger::fTransWait = "WAIT_RUN_NUMBER";
    319340const char* DataLogger::fRunNumberInfo = "RUN_NUMBER";
    320 
     341const char* DataLogger::fPrintCommand = "PRINT";
     342const char* DataLogger::fDebugOnOff = "DEBUG";
     343const char* DataLogger::fStatsPeriod = "STATS_PERIOD";
     344const char* DataLogger::fStartStopOpenedFiles = "OPENED_FILES_SRVC";
     345const char* DataLogger::fStartStopNumSubsAndFits = "NUM_SUBS_SRVC";
    321346
    322347void DataLogger::ServicesMonitoring()
    323348{
    324349                //create the DIM service
    325                 int dataSize = 2*sizeof(long long) + sizeof(long);
     350                int dataSize = 2*sizeof(long) + sizeof(long);
    326351
    327352                DataLoggerStats statVar;
     
    331356
    332357                struct statvfs vfs;
    333                 if (!statvfs(fDailyFileName.c_str(), &vfs))
     358                if (!statvfs(fNightlyFileName.c_str(), &vfs))
    334359                        statVar.freeSpace = vfs.f_bsize*vfs.f_bavail;
    335360                else
    336361                        statVar.freeSpace = -1;
    337 //        DimDescribedService srvc((GetName()+"/STATS").c_str(), "x:2;l:1", &statVar, dataSize,//static_cast<void*>(data), dataSize,
    338 //                                        "Add description here");
    339                 DimDescribedService srvc ("DATA_LOGGER/STATS", "X:2;L:1", &statVar, dataSize, "Add description here");
    340                 double deltaT = 1;
     362
     363                DimDescribedService srvc ("DATA_LOGGER/STATS", "X:3", &statVar, dataSize, "Add description here");
    341364                fPreviousSize = 0;
    342365                bool statWarning = false;
     
    344367                while (fContinueMonitoring)
    345368                {
    346                         sleep(deltaT);
     369                        if (fStatsPeriodDuration == 0.0f)
     370                        {
     371                                sleep(0.1f);
     372                                continue;
     373                        }
     374                        else
     375                                sleep(fStatsPeriodDuration);
    347376                        //update the fits files sizes
    348377#ifdef HAS_FITS
     
    357386                                        {
    358387                                                        fFileSizesMap[y->second.runFile.fFileName] = y->second.runFile.GetWrittenSize();
     388#ifdef ONE_FITS_ONLY
    359389                                                        runFileDone = true;
     390#endif
    360391                                        }
    361                                         if (y->second.dailyFile.IsOpen())
    362                                                 fFileSizesMap[y->second.dailyFile.fFileName] = y->second.dailyFile.GetWrittenSize();
     392                                        if (y->second.nightlyFile.IsOpen())
     393                                                fFileSizesMap[y->second.nightlyFile.fFileName] = y->second.nightlyFile.GetWrittenSize();
    363394                                }
    364395                        }
     
    366397                        struct stat st;
    367398                        //gather log and report files sizes on disk
    368                         if (fDailyLogFile.is_open())
    369                         {
    370                                 stat(fFullDailyLogFileName.c_str(), &st);
    371                                 fFileSizesMap[fFullDailyLogFileName] = st.st_size;     
    372                         }
    373                         if (fDailyReportFile.is_open())
    374                         {
    375                                 stat(fFullDailyReportFileName.c_str(), &st);
    376                                 fFileSizesMap[fFullDailyReportFileName] = st.st_size;   
     399                        if (fNightlyLogFile.is_open())
     400                        {
     401                                stat(fFullNightlyLogFileName.c_str(), &st);
     402                                fFileSizesMap[fFullNightlyLogFileName] = st.st_size;   
     403                        }
     404                        if (fNightlyReportFile.is_open())
     405                        {
     406                                stat(fFullNightlyReportFileName.c_str(), &st);
     407                                fFileSizesMap[fFullNightlyReportFileName] = st.st_size;
    377408                        }
    378409                        if (fRunLogFile.is_open())
     
    387418                        }       
    388419
    389                         if (!statvfs(fDailyFileName.c_str(), &vfs))
     420                        if (!statvfs(fNightlyFileName.c_str(), &vfs))
    390421                        {
    391422                                statVar.freeSpace = vfs.f_bsize*vfs.f_bavail;
     
    395426                        {
    396427                                std::stringstream str;
    397                                 str << "Unable to retrieve stats for " << fDailyFileName << ". Reason: " << strerror(errno) << " [" << errno << "]";
     428                                str << "Unable to retrieve stats for " << fNightlyFileName << ". Reason: " << strerror(errno) << " [" << errno << "]";
    398429                                if (!statWarning)
    399430                                        Error(str);
     
    404435                        //sum up all the file sizes. past and present
    405436                        statVar.sizeWritten = 0;
    406                         for (std::map<std::string, long long>::iterator it=fFileSizesMap.begin(); it != fFileSizesMap.end();  it++)
     437                        for (std::map<std::string, long>::iterator it=fFileSizesMap.begin(); it != fFileSizesMap.end();  it++)
    407438                                statVar.sizeWritten += it->second;
    408                         statVar.sizeWritten -= fBaseSizeDaily;
     439                        statVar.sizeWritten -= fBaseSizeNightly;
    409440                        statVar.sizeWritten -= fBaseSizeRun;
    410                         //FIXME get the actual time elapsed
    411                         statVar.writingRate = (statVar.sizeWritten - fPreviousSize)/deltaT; 
     441                        if (fStatsPeriodDuration == 0.0f)
     442                                continue;
     443                        statVar.writingRate = (statVar.sizeWritten - fPreviousSize)/fStatsPeriodDuration; 
     444
    412445                        fPreviousSize = statVar.sizeWritten;
    413446                        if (statVar.writingRate != 0) //if data has been written
    414447                        {
    415 //std::cout << "rate: " << statVar.writingRate << std::endl;
    416                                 srvc.updateService(&statVar, dataSize);//static_cast<void*>(data), dataSize);
     448                                srvc.updateService();
     449                                if(fDebugIsOn)
     450                                {
     451                                        stringstream str;
     452                                        str << "Size written: " << statVar.sizeWritten/1024 << " KB; writting rate: ";
     453                                        str << statVar.writingRate/1024 << " KB/s; free space: ";
     454                                        str << statVar.freeSpace/(1024*1024) << " MB";
     455                                        Debug(str.str());
     456                                }
    417457                        }
    418458                }
     
    430470{       
    431471                //initialize member data
    432                 fDailyFileName = ".";//"/home/lyard/log";//
     472                fNightlyFileName = ".";//"/home/lyard/log";//
    433473                fRunFileName = ".";//"/home/lyard/log";
    434474                fRunNumber = 12345;
     
    440480
    441481                //Give a name to this machine's specific states
    442                 AddStateName(kSM_DailyOpen,      "DailyFileOpen",  "Add description here");
     482                AddStateName(kSM_NightlyOpen,      "NightlyFileOpen",  "Add description here");
    443483                AddStateName(kSM_WaitingRun,     "WaitForRun",     "Add description here");
    444484                AddStateName(kSM_Logging,        "Logging",        "Add description here");
    445                 AddStateName(kSM_BadDailyConfig, "ErrDailyFolder", "Add description here");
     485                AddStateName(kSM_BadNightlyConfig, "ErrNightlyFolder", "Add description here");
    446486                AddStateName(kSM_BadRunConfig,   "ErrRunFolder",   "Add description here");
    447487
    448488        /*Add the possible transitions for this machine*/
    449                 AddTransition(kSM_DailyOpen, fTransStart, kSM_Ready, kSM_BadDailyConfig)
    450                     (boost::bind(&DataLogger::StartPlease, this));
    451 //                    ("start the daily logging. daily file location must be specified already");
    452 
    453                 AddTransition(kSM_Ready, fTransStop, kSM_DailyOpen, kSM_WaitingRun, kSM_Logging)
    454                     (boost::bind(&DataLogger::GoToReadyPlease, this))
     489        AddTransition(kSM_NightlyOpen, fTransStart, kSM_Ready, kSM_BadNightlyConfig)
     490                    (boost::bind(&DataLogger::StartPlease, this))
     491                    ("start the Nightly logging. Nightly file location must be specified already");
     492
     493                AddTransition(kSM_Ready, fTransStop, kSM_NightlyOpen, kSM_WaitingRun, kSM_Logging)
     494                   (boost::bind(&DataLogger::GoToReadyPlease, this))
    455495                   ("stop the data logging");
    456496
    457                 AddTransition(kSM_Logging, fTransStartRun, kSM_WaitingRun, kSM_BadRunConfig)
    458                     (boost::bind(&DataLogger::StartRunPlease, this))
    459                     ("start the run logging. run file location must be specified already.");
    460 
    461                 AddTransition(kSM_WaitingRun, fTransStopRun, kSM_Logging)
    462                     (boost::bind(&DataLogger::StopRunPlease, this))
    463                     ("");
    464 
    465                 AddTransition(kSM_Ready, fTransReset, kSM_Error, kSM_BadDailyConfig, kSM_BadRunConfig, kSM_Error)
    466                     (boost::bind(&DataLogger::GoToReadyPlease, this))
    467                     ("transition to exit error states. dunno if required or not, would close the daily file if already openned.");
    468 
    469                 AddTransition(kSM_WaitingRun, fTransWait, kSM_DailyOpen)
    470                     (boost::bind(&DataLogger::DailyToWaitRunPlease, this));
    471 
    472         /*Add the possible configurations for this machine*/
    473        
    474                 AddConfiguration(fConfigDay, "C", kSM_Ready, kSM_BadDailyConfig)
    475                     (boost::bind(&DataLogger::ConfigureDailyFileName, this, _1))
    476                     ("configure the daily file location. cannot be done before the file is actually opened");
    477 
    478                 AddConfiguration(fConfigRun, "C", kSM_Ready, kSM_BadDailyConfig, kSM_DailyOpen, kSM_WaitingRun, kSM_BadRunConfig)
    479                     (boost::bind(&DataLogger::ConfigureRunFileName, this, _1))
    480                     ("configure the run file location. cannot be done before the file is actually opened, and not in a dailly related error.");
    481 
     497        AddTransition(kSM_Logging, fTransStartRun, kSM_WaitingRun, kSM_BadRunConfig)
     498                   (boost::bind(&DataLogger::StartRunPlease, this))
     499                   ("start the run logging. run file location must be specified already.");
     500
     501        AddTransition(kSM_WaitingRun, fTransStopRun, kSM_Logging)
     502                   (boost::bind(&DataLogger::StopRunPlease, this))
     503                   ("");
     504
     505        AddTransition(kSM_Ready, fTransReset, kSM_Error, kSM_BadNightlyConfig, kSM_BadRunConfig, kSM_Error)
     506                   (boost::bind(&DataLogger::GoToReadyPlease, this))
     507                   ("transition to exit error states. dunno if required or not, would close the Nightly file if already openned.");
     508
     509        AddTransition(kSM_WaitingRun, fTransWait, kSM_NightlyOpen)
     510                   (boost::bind(&DataLogger::NightlyToWaitRunPlease, this));
     511
     512        /*Add the possible configurations for this machine*/       
     513        AddConfiguration(fConfigDay, "C", kSM_Ready, kSM_BadNightlyConfig)
     514                   (boost::bind(&DataLogger::ConfigureNightlyFileName, this, _1))
     515                   ("configure the Nightly file location. cannot be done before the file is actually opened");
     516
     517        AddConfiguration(fConfigRun, "C", kSM_Ready, kSM_BadNightlyConfig, kSM_NightlyOpen, kSM_WaitingRun, kSM_BadRunConfig)
     518                   (boost::bind(&DataLogger::ConfigureRunFileName, this, _1))
     519                   ("configure the run file location. cannot be done before the file is actually opened, and not in a dailly related error.");
     520                AddConfiguration(fConfigRunNumber, "I", kSM_Ready, kSM_BadNightlyConfig, kSM_NightlyOpen, kSM_WaitingRun, kSM_BadRunConfig)
     521                                   (boost::bind(&DataLogger::ConfigureRunNumber, this, _1))
     522                                   ("configure the run number. cannot be done in logging state");
    482523                //Provide a logging command
    483524                //I get the feeling that I should be going through the EventImp
    484                 //instead of DimCommand directly, mainly because the commandHandler
    485                 //is already done in StateMachineImp.cc
    486                 //Thus I'll simply add a configuration, which I will treat as the logging command
    487                 AddConfiguration(fConfigLog, "C", kSM_DailyOpen, kSM_Logging, kSM_WaitingRun, kSM_BadRunConfig)
    488                     (boost::bind(&DataLogger::LogMessagePlease, this, _1));
    489 
     525        //instead of DimCommand directly, mainly because the commandHandler
     526        //is already done in StateMachineImp.cc
     527        //Thus I'll simply add a configuration, which I will treat as the logging command
     528        AddConfiguration(fConfigLog, "C", kSM_NightlyOpen, kSM_Logging, kSM_WaitingRun, kSM_BadRunConfig)
     529                   (boost::bind(&DataLogger::LogMessagePlease, this, _1));
     530               
     531                //Provide a print command
     532                AddConfiguration(fPrintCommand, "", kSM_NightlyOpen, kSM_Logging, kSM_WaitingRun, kSM_BadNightlyConfig, kSM_BadRunConfig)
     533                                  (boost::bind(&DataLogger::PrintStatePlease, this, _1));
     534               
    490535                fServiceList.SetHandler(this);
    491536                CheckForServicesUpdate();
     
    494539                fContinueMonitoring = true;
    495540                fMonitoringThread = boost::thread(boost::bind(&DataLogger::ServicesMonitoring, this));
    496                 fBaseSizeDaily = 0;
     541                fBaseSizeNightly = 0;
    497542                fBaseSizeRun = 0;
    498 
    499                 //gives the entire buffer size. Otherwise, dim overwrites memory at bizarre locations if smaller size is given at creation time.
    500 //        fOpenedFiles =        new DimDescribedService((GetName()+"/FILENAME").c_str(), "i:1;C", static_cast<void*>(fDimBuffer), 256, "Add description here");
    501                 fOpenedDailyFiles = new DimDescribedService((GetName() + "/FILENAME_DAILY").c_str(), const_cast<char*>(""), "Add description here");//"i:1;C", static_cast<void*>(fDimBuffer), 256);
    502                 fOpenedRunFiles = new DimDescribedService((GetName() + "/FILENAME_RUN").c_str(), const_cast<char*>(""), "Add description here");
    503                 fOpenedDailyFiles->setQuality(0);
    504                 fOpenedRunFiles->setQuality(0);
    505                 fOpenedDailyFiles->updateService();
    506                 fOpenedRunFiles->updateService();
     543                OpenFileToDim fToDim;
     544                fToDim.code = 0;
     545                fToDim.fileName[0] = '\0';
     546                fOpenedNightlyFiles = new DimDescribedService((GetName() + "/FILENAME_NIGHTLY").c_str(), "I:1;C", &fToDim, sizeof(int)+1, "Add description here");//"i:1;C", static_cast<void*>(fDimBuffer), 256);
     547                fOpenedRunFiles = new DimDescribedService((GetName() + "/FILENAME_RUN").c_str(), "I:1;C", &fToDim, sizeof(int)+1, "Add description here");
    507548                fNumSubAndFitsData.numSubscriptions = 0;
    508549                fNumSubAndFitsData.numOpenFits = 0;
    509550                fNumSubAndFits = new DimDescribedService((GetName() + "/NUM_SUBS").c_str(), "I:2", &fNumSubAndFitsData, sizeof(NumSubAndFitsType), "Add description here");
     551                //black/white list
     552                fIsBlackList = true;
     553                fGreyList.clear();
     554       
     555                //services parameters
     556                fDebugIsOn = false;
     557                fStatsPeriodDuration = 1.0f;
     558                fOpenedFilesIsOn = true;
     559                fNumSubAndFitsIsOn = true;
     560                //provide services control commands
     561                AddConfiguration(fDebugOnOff, "C", kSM_NightlyOpen, kSM_Logging, kSM_WaitingRun, kSM_Ready)
     562                                (boost::bind(&DataLogger::SetDebugOnOff, this, _1));
     563                AddConfiguration(fStatsPeriod, "F", kSM_NightlyOpen, kSM_Logging, kSM_WaitingRun, kSM_Ready)
     564                                (boost::bind(&DataLogger::SetStatsPeriod, this, _1));
     565                AddConfiguration(fStartStopOpenedFiles, "C", kSM_NightlyOpen, kSM_Logging, kSM_WaitingRun, kSM_Ready)
     566                                (boost::bind(&DataLogger::SetOpenedFilesOnOff ,this, _1));
     567                AddConfiguration(fStartStopNumSubsAndFits, "C", kSM_NightlyOpen, kSM_Logging, kSM_WaitingRun, kSM_Ready)
     568                                (boost::bind(&DataLogger::SetNumSubsAndFitsOnOff, this, _1));
     569                fDestructing = false;
     570                if(fDebugIsOn)
     571                {
     572                        Debug("DataLogger Init Done.");
     573                }
    510574}
    511575// --------------------------------------------------------------------------
     
    543607        for (std::vector<std::string>::const_iterator i=serverList.begin(); i!=serverList.end();i++)
    544608        {
    545                 //skip the two obvious excluded services
     609                //skip the two de-fact excluded services
     610                //Dim crashes if the publisher subscribes to its own service. This sounds weird, I agree.
    546611                if ((i->find("DIS_DNS") != std::string::npos) ||
    547612                    (i->find("DATA_LOGGER") != std::string::npos))
     613                        continue;
     614                if (fIsBlackList && (fGreyList.find(*i) != fGreyList.end()))
    548615                        continue;
    549616                //find the current server in our subscription list     
     
    575642                                if (*givenSubs == "SERVICE_LIST")
    576643                                        continue;
     644                                if (fIsBlackList && fGreyList.find(*givenSubs) != fGreyList.end())
     645                                        continue;
     646
     647                                if (fIsBlackList && fGreyList.find((*i) + "/" + (*givenSubs)) != fGreyList.end())
     648                                        continue;
     649                                else if (!fIsBlackList &&
     650                                        (fGreyList.find((*i) + "/" + (*givenSubs)) == fGreyList.end()) &&
     651                                        (fGreyList.find(*i) == fGreyList.end()) &&
     652                                        (fGreyList.find(*givenSubs) == fGreyList.end()))
     653                                                continue;
    577654                                if (cSubs->second.find(*givenSubs) == cSubs->second.end())
    578655                                {//service not found. Add it
    579656                                        cSubs->second[*givenSubs].dimInfo = new DimStampedInfo(((*i) + "/" + *givenSubs).c_str(), const_cast<char*>(""), this);
    580657                                        serviceUpdated = true;
     658                                        if(fDebugIsOn)
     659                                        {
     660                                                stringstream str;
     661                                                str << "Subscribing to service " << *i << "/" << *givenSubs;
     662                                                Debug(str.str());       
     663                                        }
    581664                                }       
    582665                        }
     
    590673                                if (*j == "SERVICE_LIST")
    591674                                        continue;
     675                                if (fIsBlackList && fGreyList.find(*j) != fGreyList.end())
     676                                        continue;
     677
     678                                if (fIsBlackList && fGreyList.find((*i) + "/" + (*j)) != fGreyList.end())
     679                                        continue;
     680                                else if (!fIsBlackList &&
     681                                        (fGreyList.find((*i) + "/" + (*j)) == fGreyList.end()) &&
     682                                        (fGreyList.find(*i) == fGreyList.end()) &&
     683                                        (fGreyList.find(*j) == fGreyList.end()))
     684                                                continue;
     685                                       
    592686                                liste[*j].dimInfo = new DimStampedInfo(((*i) + "/" + (*j)).c_str(), const_cast<char*>(""), this);
    593687                                serviceUpdated = true;
     688                                if(fDebugIsOn)
     689                                {
     690                                        stringstream str;
     691                                        str << "Subscribing to service " << *i << "/" << *j;
     692                                        Debug(str.str());       
     693                                }
    594694                        }
    595695                }       
     
    603703DataLogger::~DataLogger()
    604704{
     705        if (fDebugIsOn)
     706        {
     707                Debug("DataLogger destruction starts");
     708        }
     709        fDestructing = true;
     710        //first let's go to the ready state
     711        //TODO some closing done below has already been executed by GoToReady. figure out what should be removed.
     712        GoToReadyPlease();
    605713        //release the services subscriptions
    606714        fServiceSubscriptions.clear();
     
    610718        fMonitoringThread.join();
    611719        //close the files
    612         if (fDailyLogFile.is_open())
    613                 fDailyLogFile.close();
    614         if (fDailyReportFile.is_open())
    615                 fDailyReportFile.close();
     720        if (fNightlyLogFile.is_open())
     721                fNightlyLogFile.close();
     722        if (fNightlyReportFile.is_open())
     723                fNightlyReportFile.close();
    616724        if (fRunLogFile.is_open())
    617725                fRunLogFile.close();
    618726        if (fRunReportFile.is_open())
    619727                fRunReportFile.close();
    620         delete fOpenedDailyFiles;
     728        delete fOpenedNightlyFiles;
    621729        delete fOpenedRunFiles;
    622730        delete fNumSubAndFits;
     
    629737#endif
    630738#endif
     739        if (fDebugIsOn)
     740        {
     741                Debug("DataLogger desctruction ends"); 
     742        }
    631743}
    632744
     
    637749void DataLogger::infoHandler()
    638750{
     751        if (fDestructing)
     752                return;
    639753        DimInfo* I = getInfo();
    640754        SubscriptionsListType::iterator x;
     
    648762                        for (x=fServiceSubscriptions.begin(); x != fServiceSubscriptions.end(); x++)
    649763                                fNumSubAndFitsData.numSubscriptions += x->second.size();
    650                         fNumSubAndFits->updateService();
     764                        if (fNumSubAndFitsIsOn)
     765                        {
     766                                if (fDebugIsOn)
     767                                {
     768                                        stringstream str;
     769                                        str << "Updating number of subscriptions service: Num Subs=" << fNumSubAndFitsData.numSubscriptions << " Num open FITS=" << fNumSubAndFitsData.numOpenFits;
     770                                        Debug(str.str());       
     771                                }
     772                                fNumSubAndFits->updateService();
     773                        }
    651774                }
    652775                return;
     
    692815                //TODO check the format here
    693816                fRunNumber = I->getInt();       
     817                stringstream str;
     818                str << "New run number is " << fRunNumber;
     819                Message(str.str());
    694820        }
    695821}
     
    705831        //should we log or report this info ? (i.e. is it a message ?)
    706832        bool isItaReport = ((strstr(I->getName(), "Message") == NULL) && (strstr(I->getName(), "MESSAGE") == NULL));
    707        
     833        if (I->getFormat()[0] == 'C')
     834                isItaReport = false;
    708835        //TODO add service exclusion
    709836       
    710         if (!fDailyReportFile.is_open())
     837        if (!fNightlyReportFile.is_open())
    711838                return;
    712839
    713840        //create the converter for that service
    714         if (sub.fConv == NULL)
    715         {
     841        if (sub.fConv == NULL && isItaReport)
     842        {
     843                //trick the converter in case of 'C'. why do I do this ? well simple: the converter checks that the right number
     844                //of bytes was written. because I skip 'C' with fits, the bytes will not be allocated, hence the "size copied ckeck"
     845                //of the converter will fail, hence throwing an exception.
     846                std::string fakeFormat(I->getFormat());
     847                if (fakeFormat[fakeFormat.size()-1] == 'C')
     848                        fakeFormat = fakeFormat.substr(0, fakeFormat.size()-1);
    716849                sub.fConv = new Converter(Out(), I->getFormat());       
    717850                if (!sub.fConv)
     
    764897        replace_if(text.begin(), text.end(), std::ptr_fun<int, int>(&std::iscntrl), ' ');
    765898       
    766         //write entry to daily report
    767                 try
    768                 {
    769                         if (fDailyReportFile.is_open())
    770                                 fDailyReportFile << header.str() << text << std::endl;
    771                 }
    772                 catch (std::exception e)
    773                 {
    774                         std::stringstream str;
    775                         str << "Error while writing to daily report file: " << e.what();
    776                         Error(str);     
     899        //write entry to Nightly report
     900                if (fNightlyReportFile.is_open())
     901                {
     902                        if (fDebugIsOn)
     903                        {
     904                                stringstream str;
     905                                str << "Writing: \"" << header.str() << text << "\" to Nightly report file";
     906                                Debug(str.str());       
     907                        }
     908                        fNightlyReportFile << header.str() << text << std::endl;
     909                        //check if either eof, bailbit or batbit are set
     910                        if (!fNightlyReportFile.good())
     911                        {
     912                                Error("An error occured while writing to the nightly report file. Closing it");
     913                                if (fNightlyReportFile.is_open())
     914                                        fNightlyReportFile.close();
     915                        }
    777916                }
    778917                //write entry to run-report
    779                 try
    780                 {
    781                         if (fRunReportFile.is_open())
    782                                 fRunReportFile << header.str() << text << std::endl;
    783                 }
    784                 catch (std::exception e)
    785                 {
    786                         std::stringstream str;
    787                         str << "Error while writing to run report file: " << e.what();
    788                         Error(str);
     918                if (fRunReportFile.is_open())
     919                {
     920                        if (fDebugIsOn)
     921                        {
     922                                stringstream str;
     923                                str << "Writing: \"" << header.str() << text << "\" to Run report file";
     924                                Debug(str.str());       
     925                        }
     926                        fRunReportFile << header.str() << text << std::endl;
     927                        if (!fRunReportFile.good())
     928                        {
     929                                Error("An error occured while writing to the run report file. Closing it.");
     930                                if (fRunReportFile.is_open())
     931                                        fRunReportFile.close();
     932                        }
    789933                }
    790934        }
    791935        else
    792         {//write entry to both daily and run logs
     936        {//write entry to both Nightly and run logs
    793937                std::string n = I->getName();
    794938                std::stringstream msg;
    795939                msg << n.substr(0, n.find_first_of('/')) << ": " << I->getString();
    796                 try
    797                 {
    798                         MessageImp dailyMess(fDailyLogFile);
    799                         dailyMess.Write(cTime, msg.str().c_str(), fQuality);
    800                 }
    801                 catch (std::exception e)
    802                 {
    803                         std::stringstream str;
    804                         str << "Error while writing to daily log file: " << e.what();
    805                         Error(str);     
     940
     941                if (fNightlyLogFile.is_open())
     942                {
     943                        if (fDebugIsOn)
     944                        {
     945                                stringstream str;
     946                                str << "Writing: \"" << msg.str() << "\" to Nightly log file";
     947                                Debug(str.str());       
     948                        }
     949                        MessageImp nightlyMess(fNightlyLogFile);
     950                        nightlyMess.Write(cTime, msg.str().c_str(), fQuality);
     951                        if (!fNightlyLogFile.good())
     952                        {
     953                                Error("An error occured while writing to the nightly log file. Closing it.");
     954                                if (fNightlyLogFile.is_open())
     955                                        fNightlyLogFile.close();       
     956                        }
    806957                }
    807958                if (fRunLogFile.is_open())
    808959                {
    809                         try
    810                         {
    811                                 MessageImp runMess(fRunLogFile);
    812                                 runMess.Write(cTime, msg.str().c_str(), fQuality);
    813                         }
    814                         catch (std::exception e)
    815                         {
    816                                 std::stringstream str;
    817                                 str << "Error while writing to run log file: " << e.what();
    818                                 Error(str);     
     960                        if (fDebugIsOn)
     961                        {
     962                                stringstream str;
     963                                str << "Writing: \"" << msg.str() << "\" to Run log file";
     964                                Debug(str.str());       
     965                        }
     966                        MessageImp runMess(fRunLogFile);
     967                        runMess.Write(cTime, msg.str().c_str(), fQuality);
     968                        if (!fRunLogFile.good())
     969                        {
     970                                Error("An error occured while writing to the run log file. Closing it.");
     971                                if (fRunLogFile.is_open())
     972                                        fRunLogFile.close();   
    819973                        }
    820974                }
     
    822976
    823977#ifdef HAS_FITS
    824         if (!sub.dailyFile.IsOpen() || !sub.runFile.IsOpen())
    825                 OpenFITSFilesPlease(sub);       
    826         WriteToFITS(sub);
    827                
     978        if (isItaReport)
     979        {
     980                if (!sub.nightlyFile.IsOpen() || !sub.runFile.IsOpen())
     981                        OpenFITSFilesPlease(sub);       
     982                WriteToFITS(sub);
     983        }       
    828984#endif
    829985
     
    8451001int DataLogger::LogMessagePlease(const Event& evt)
    8461002{
    847         if (!fDailyLogFile.is_open())
     1003        if (!fNightlyLogFile.is_open())
    8481004                return GetCurrentState();
    8491005       
     
    8791035    replace(text.begin(), text.end(), '\n', '\\');
    8801036    replace_if(text.begin(), text.end(), std::ptr_fun<int, int>(&std::iscntrl), ' ');
    881 
    882         if (fDailyLogFile.is_open())
    883                 fDailyLogFile << header;
     1037        if (fDebugIsOn)
     1038        {
     1039                stringstream str;
     1040                str << "Logging: \"" << header << text << "\"";
     1041                Debug(str.str());       
     1042        }
     1043       
     1044        if (fNightlyLogFile.is_open())
     1045        {
     1046                fNightlyLogFile << header;
     1047                if (!fNightlyLogFile.good())
     1048                {
     1049                        Error("An error occured while writing to the run log file. Closing it.");
     1050                        if (fNightlyLogFile.is_open())
     1051                                fNightlyLogFile.close();       
     1052                }
     1053        }
    8841054        if (fRunLogFile.is_open())
     1055        {
    8851056                fRunLogFile << header;
    886 
    887         if (fDailyLogFile.is_open())
    888                 fDailyLogFile << text;
     1057                if (!fRunLogFile.good())
     1058                {
     1059                        Error("An error occured while writing to the run log file. Closing it.");
     1060                        if (fRunLogFile.is_open())
     1061                                fRunLogFile.close();   
     1062                }
     1063        }
     1064        if (fNightlyLogFile.is_open())
     1065        {
     1066                fNightlyLogFile << text;
     1067                if (!fNightlyLogFile.good())
     1068                {
     1069                        Error("An error occured while writing to the run log file. Closing it.");
     1070                        if (fNightlyLogFile.is_open())
     1071                                fNightlyLogFile.close();       
     1072                }
     1073        }
    8891074        if (fRunLogFile.is_open())
     1075        {
    8901076                fRunLogFile << text;
    891 
     1077                if (!fRunLogFile.good())
     1078                {
     1079                        Error("An error occured while writing to the run log file. Closing it.");
     1080                        if (fRunLogFile.is_open())
     1081                                fRunLogFile.close();   
     1082                }
     1083        }
    8921084        return GetCurrentState();
    8931085}
    8941086// --------------------------------------------------------------------------
    8951087//
    896 //!     Sets the path to use for the daily log file.
     1088//! print the dataLogger's current state. invoked by the PRINT command
     1089//! @param evt
     1090//!             the current event. Not used by the method
     1091//! @returns
     1092//!             the new state. Which, in that case, is the current state
     1093//!
     1094int DataLogger::PrintStatePlease(const Event& )
     1095{
     1096        Message("-----------------------------------------");
     1097        Message("------DATA LOGGER CURRENT STATE----------");
     1098        Message("-----------------------------------------");
     1099        //print the path configuration
     1100        std::string actualTargetDir;
     1101        if (fNightlyFileName == ".")
     1102        {
     1103                char currentPath[FILENAME_MAX];
     1104                getcwd(currentPath, sizeof(currentPath));
     1105                actualTargetDir = currentPath;
     1106        }
     1107        else
     1108                actualTargetDir = fNightlyFileName;
     1109        Message("Nightly Path: " + actualTargetDir);
     1110        if (fRunFileName == ".")
     1111        {
     1112                char currentPath[FILENAME_MAX];
     1113                getcwd(currentPath, sizeof(currentPath));
     1114                actualTargetDir = currentPath;
     1115        }
     1116        else
     1117                actualTargetDir = fRunFileName;
     1118        Message("Run Path: " + actualTargetDir);
     1119        stringstream str;
     1120        str << "Run Number: " << fRunFileName;
     1121        Message(str.str());
     1122        Message("-----------OPENED FILES------------------");
     1123        //print all the open files.
     1124        if (fNightlyLogFile.is_open())
     1125                Message("Nightly Log..........OPEN");
     1126        else
     1127                Message("Nightly log........CLOSED");
     1128        if (fNightlyReportFile.is_open())
     1129                Message("Nightly Report.......OPEN");
     1130        else
     1131                Message("Nightly Report.....CLOSED");
     1132        if (fRunLogFile.is_open())
     1133                Message("Run Log..............OPEN");
     1134        else
     1135                Message("Run Log............CLOSED");
     1136        if (fRunReportFile.is_open())
     1137                Message("Run Report...........OPEN");
     1138        else
     1139                Message("Run Report.........CLOSED");
     1140#ifdef HAS_FITS
     1141        str.str("");
     1142        str << "There are " << fNumSubAndFitsData.numOpenFits << " FITS files open:";
     1143        Message(str.str());
     1144        SubscriptionsListType::iterator x;
     1145        std::map<std::string, SubscriptionType>::iterator y;
     1146        bool runFileDone = false;
     1147        for (x=fServiceSubscriptions.begin(); x != fServiceSubscriptions.end(); x++)
     1148        {
     1149                for (y=x->second.begin(); y != x->second.end(); y++)
     1150                {
     1151                        if (y->second.runFile.IsOpen() && !runFileDone)
     1152                        {
     1153                                        fFileSizesMap[y->second.runFile.fFileName] = y->second.runFile.GetWrittenSize();
     1154                                        str.str("");
     1155                                        str << ">>>" << y->second.runFile.fFileName;
     1156                                        Message(str.str());
     1157#ifdef ONE_FITS_ONLY
     1158                                        runFileDone = true;
     1159#endif
     1160                        }
     1161                        if (y->second.nightlyFile.IsOpen())
     1162                        {
     1163                                fFileSizesMap[y->second.nightlyFile.fFileName] = y->second.nightlyFile.GetWrittenSize();
     1164                                str.str("");
     1165                                str << ">>>" << y->second.nightlyFile.fFileName;
     1166                                Message(str.str());
     1167                        }
     1168                }
     1169        }
     1170#else
     1171        Message("FITS output disabled at compilation");
     1172#endif
     1173        struct stat st;
     1174        DataLoggerStats statVar;
     1175        //gather log and report files sizes on disk
     1176        if (fNightlyLogFile.is_open())
     1177        {
     1178                stat(fFullNightlyLogFileName.c_str(), &st);
     1179                fFileSizesMap[fFullNightlyLogFileName] = st.st_size;   
     1180        }
     1181        if (fNightlyReportFile.is_open())
     1182        {
     1183                stat(fFullNightlyReportFileName.c_str(), &st);
     1184                fFileSizesMap[fFullNightlyReportFileName] = st.st_size;
     1185        }
     1186        if (fRunLogFile.is_open())
     1187        {
     1188                stat(fFullRunLogFileName.c_str(), &st);
     1189                fFileSizesMap[fFullRunLogFileName] = st.st_size;       
     1190        }
     1191        if (fRunReportFile.is_open())
     1192        {
     1193                stat(fFullRunReportFileName.c_str(), &st);
     1194                fFileSizesMap[fFullRunReportFileName] = st.st_size;
     1195        }       
     1196        struct statvfs vfs;
     1197        if (!statvfs(fNightlyFileName.c_str(), &vfs))
     1198        {
     1199                statVar.freeSpace = vfs.f_bsize*vfs.f_bavail;
     1200        }
     1201        else
     1202        {
     1203                str.str("");
     1204                str << "Unable to retrieve stats for " << fNightlyFileName << ". Reason: " << strerror(errno) << " [" << errno << "]";
     1205                Error(str);;
     1206                statVar.freeSpace = -1;
     1207        }
     1208       
     1209        //sum up all the file sizes. past and present
     1210        statVar.sizeWritten = 0;
     1211        for (std::map<std::string, long>::iterator it=fFileSizesMap.begin(); it != fFileSizesMap.end();  it++)
     1212                statVar.sizeWritten += it->second;
     1213        statVar.sizeWritten -= fBaseSizeNightly;
     1214        statVar.sizeWritten -= fBaseSizeRun;
     1215        str.str("");
     1216        str << "Total Size written: " << statVar.sizeWritten;
     1217        str << " Disk free space: " << statVar.freeSpace;
     1218        Message("-----------------STATS-------------------");
     1219        Message(str.str());
     1220        Message("------------DIM SUBSCRIPTIONS------------");
     1221        str.str("");
     1222        str << "There are " << fNumSubAndFitsData.numSubscriptions << " active DIM subscriptions:";
     1223        Message(str.str());
     1224        str.str("");
     1225        for (std::map<const std::string, std::map<std::string, SubscriptionType>>::const_iterator it=fServiceSubscriptions.begin(); it!= fServiceSubscriptions.end();it++)
     1226        {
     1227                str << "Server " << it->first;
     1228                Message(str.str());
     1229                for (std::map<std::string, SubscriptionType>::const_iterator it2=it->second.begin(); it2!=it->second.end(); it2++)
     1230                {
     1231                        str.str("");
     1232                        str << "     " << it2->first;
     1233                        Message(str.str());     
     1234                }       
     1235        }
     1236        Message("-----------------------------------------");
     1237       
     1238        return GetCurrentState();
     1239}
     1240// --------------------------------------------------------------------------
     1241//
     1242//! figure out whether the string means on or off
     1243//! @param evt
     1244//!             the current event. contains the instruction string: On, Off, on, off, ON, OFF, 0 or 1
     1245//! @returns
     1246//!             the equivalent boolean
     1247//!
     1248bool DataLogger::getBooleanFromString(const std::string& str)
     1249{
     1250        if (str == "On" || str == "ON" || str == "on" || str == "1")
     1251                return true;
     1252        if (str == "Off" || str == "OFF" || str == "off" || str == "0")
     1253                return false;
     1254        Error("Argument could not be converted to boolean. please use On/on/ON/1 or Off/off/OFF/0. defaulting to false.");
     1255        return false;
     1256}
     1257// --------------------------------------------------------------------------
     1258//
     1259//! turn debug mode on and off
     1260//! @param evt
     1261//!             the current event. contains the instruction string: On, Off, on, off, ON, OFF, 0 or 1
     1262//! @returns
     1263//!             the new state. Which, in that case, is the current state
     1264//!
     1265int DataLogger::SetDebugOnOff(const Event& evt)
     1266{
     1267        bool backupDebug = fDebugIsOn;
     1268        fDebugIsOn = getBooleanFromString(evt.GetText());
     1269        if (fDebugIsOn == backupDebug)
     1270                Warn("Warning: debug mode was already in the requested state");
     1271        else
     1272        {
     1273                stringstream str;
     1274                str << "Debug mode is now " << evt.GetText();
     1275                Message(str.str());
     1276        }
     1277        return GetCurrentState();
     1278}
     1279// --------------------------------------------------------------------------
     1280//
     1281//! set the statistics update period duration. 0 disables the statistics
     1282//! @param evt
     1283//!             the current event. contains the new duration.
     1284//! @returns
     1285//!             the new state. Which, in that case, is the current state
     1286//!
     1287int DataLogger::SetStatsPeriod(const Event& evt)
     1288{
     1289        float backupDuration = fStatsPeriodDuration;
     1290        fStatsPeriodDuration = evt.GetFloat();
     1291        if (fStatsPeriodDuration < 0)
     1292        {
     1293                Error("Statistics period duration should be greater than zero. Discarding provided value.");
     1294                fStatsPeriodDuration = backupDuration;
     1295                return GetCurrentState();       
     1296        }
     1297        if (fStatsPeriodDuration != fStatsPeriodDuration)
     1298        {
     1299                Error("Provided duration does not appear to be a valid float. discarding it.");
     1300                fStatsPeriodDuration = backupDuration;
     1301                return GetCurrentState();       
     1302        }
     1303        if (backupDuration == fStatsPeriodDuration)
     1304                Warn("Warning: statistics period was not modified: supplied value already in use");
     1305        else
     1306        {
     1307                if (fStatsPeriodDuration == 0.0f)
     1308                        Message("Statistics are now OFF");
     1309                else
     1310                {
     1311                        stringstream str;
     1312                        str << "Statistics period is now " << fStatsPeriodDuration << " seconds";
     1313                        Message(str.str());     
     1314                }       
     1315        }
     1316        return GetCurrentState();
     1317}
     1318// --------------------------------------------------------------------------
     1319//
     1320//! set the opened files service on or off.
     1321//! @param evt
     1322//!             the current event. contains the instruction string. similar to setdebugonoff
     1323//! @returns
     1324//!             the new state. Which, in that case, is the current state
     1325//!
     1326int DataLogger::SetOpenedFilesOnOff(const Event& evt)
     1327{
     1328        bool backupOpened = fOpenedFilesIsOn;
     1329        fOpenedFilesIsOn = getBooleanFromString(evt.GetText());
     1330        if (fOpenedFilesIsOn == backupOpened)
     1331                Warn("Warning: opened files service mode was already in the requested state");
     1332        else
     1333        {
     1334                stringstream str;
     1335                str << "Opened files service mode is now " << evt.GetText();
     1336                Message(str.str());
     1337        }
     1338        return GetCurrentState();
     1339       
     1340}
     1341// --------------------------------------------------------------------------
     1342//
     1343//! set the number of subscriptions and opened fits on and off
     1344//! @param evt
     1345//!             the current event. contains the instruction string. similar to setdebugonoff
     1346//! @returns
     1347//!             the new state. Which, in that case, is the current state
     1348//!
     1349int DataLogger::SetNumSubsAndFitsOnOff(const Event& evt)
     1350{
     1351        bool backupSubs = fNumSubAndFitsIsOn;
     1352        fNumSubAndFitsIsOn = getBooleanFromString(evt.GetText());
     1353        if (fNumSubAndFitsIsOn == backupSubs)
     1354                Warn("Warning: Number of subscriptions service mode was already in the requested state");
     1355        else
     1356        {
     1357                stringstream str;
     1358                str << "Number of subscriptions service mode is now " << evt.GetText();
     1359                Message(str.str());
     1360        }
     1361        return GetCurrentState();
     1362}
     1363// --------------------------------------------------------------------------
     1364//
     1365//!     Sets the path to use for the Nightly log file.
    8971366//! @param evt
    8981367//!     the event transporting the path
     
    9001369//!             currently only the current state.
    9011370//
    902 int DataLogger::ConfigureDailyFileName(const Event& evt)
     1371int DataLogger::ConfigureNightlyFileName(const Event& evt)
    9031372{
    9041373        if (evt.GetText() != NULL)
    9051374        {
    906                 fDailyFileName = std::string(evt.GetText());   
    907                 Message("New daily folder specified: " + fDailyFileName);
     1375                fNightlyFileName = std::string(evt.GetText()); 
     1376                Message("New Nightly folder specified: " + fNightlyFileName);
    9081377        }
    9091378        else
    910                 Error("Empty daily folder given. Please specify a valid path.");
     1379                Error("Empty Nightly folder given. Please specify a valid path.");
    9111380
    9121381        return GetCurrentState();
     
    9271396        }
    9281397        else
    929                 Error("Empty daily folder given. Please specify a valid path");
     1398                Error("Empty Nightly folder given. Please specify a valid path");
    9301399
    9311400        return GetCurrentState();
     
    9421411{
    9431412        fRunNumber = evt.GetInt();
     1413        std::stringstream str;
     1414        str << "The new run number is: " << fRunNumber;
     1415        Message(str.str());
    9441416        return GetCurrentState();
    9451417}
     
    9511423//!             this is not a problem though because file are not opened so often.
    9521424//! @ param type the type of the opened file. 0 = none open, 1 = log, 2 = text, 4 = fits
    953 inline void DataLogger::NotifyOpenedFile(std::string name, int type, DimService* service)
    954 {
    955         service->setQuality(type);
    956         service->updateService(const_cast<char*>(name.c_str()));
     1425inline void DataLogger::NotifyOpenedFile(std::string name, int type, DimDescribedService* service)
     1426{
     1427        if (fOpenedFilesIsOn)
     1428        {
     1429                if (fDebugIsOn)
     1430                {
     1431                        stringstream str;
     1432                        str << "Updating files service " << service->getName() << "with code: " << type << " and file: " << name;
     1433                        Debug(str.str());
     1434                        str.str("");
     1435                        str << "Num subs: " << fNumSubAndFitsData.numSubscriptions << " Num open FITS: " << fNumSubAndFitsData.numOpenFits;
     1436                        Debug(str.str());
     1437                }
     1438                OpenFileToDim fToDim;
     1439                fToDim.code = type;
     1440                memcpy(fToDim.fileName, name.c_str(), name.size()+1);
     1441                service->setData(reinterpret_cast<void*>(&fToDim), name.size()+1+sizeof(int));
     1442                service->setQuality(0);
     1443                service->updateService();
     1444        }
    9571445}
    9581446// --------------------------------------------------------------------------
    9591447//
    9601448//! Implements the Start transition.
    961 //! Concatenates the given path for the daily file and the filename itself (based on the day),
     1449//! Concatenates the given path for the Nightly file and the filename itself (based on the day),
    9621450//! and tries to open it.
    9631451//! @returns
    964 //!             kSM_DailyOpen if success, kSM_BadDailyConfig if failure
     1452//!             kSM_NightlyOpen if success, kSM_BadNightlyConfig if failure
    9651453int DataLogger::StartPlease()
    9661454{
    967         //TODO concatenate the dailyFileName and the formatted date and extension to obtain the full file name
     1455        if (fDebugIsOn)
     1456        {
     1457                Debug("Starting...");   
     1458        }
    9681459        Time time;
    9691460        std::stringstream sTime;
    9701461        sTime << time.Y() << "_" << time.M() << "_" << time.D();
    9711462
    972         fFullDailyLogFileName = fDailyFileName + '/' + sTime.str() + ".log";
    973         fDailyLogFile.open(fFullDailyLogFileName.c_str(), std::ios_base::out | std::ios_base::app);
     1463        fFullNightlyLogFileName = fNightlyFileName + '/' + sTime.str() + ".log";
     1464        fNightlyLogFile.open(fFullNightlyLogFileName.c_str(), std::ios_base::out | std::ios_base::app);
    9741465        if (errno != 0)
    9751466        {
    9761467                std::stringstream str;
    977                 str << "Unable to open daily Log " << fFullDailyLogFileName << ". Reason: " << strerror(errno) << " [" << errno << "]";
     1468                str << "Unable to open Nightly Log " << fFullNightlyLogFileName << ". Reason: " << strerror(errno) << " [" << errno << "]";
    9781469                Error(str);     
    9791470        }
    980         fFullDailyReportFileName = fDailyFileName + '/' + sTime.str() + ".rep";
    981         fDailyReportFile.open(fFullDailyReportFileName.c_str(), std::ios_base::out | std::ios_base::app);
     1471        fFullNightlyReportFileName = fNightlyFileName + '/' + sTime.str() + ".rep";
     1472        fNightlyReportFile.open(fFullNightlyReportFileName.c_str(), std::ios_base::out | std::ios_base::app);
    9821473        if (errno != 0)
    9831474        {
    9841475                std::stringstream str;
    985                 str << "Unable to open daily Report " << fFullDailyReportFileName << ". Reason: " << strerror(errno) << " [" << errno << "]";
     1476                str << "Unable to open Nightly Report " << fFullNightlyReportFileName << ". Reason: " << strerror(errno) << " [" << errno << "]";
    9861477                Error(str);     
    9871478        }
    9881479
    989         if (!fDailyLogFile.is_open() || !fDailyReportFile.is_open())
     1480        if (!fNightlyLogFile.is_open() || !fNightlyReportFile.is_open())
    9901481        {       
    9911482                //TODO send an error message   
    992             return kSM_BadDailyConfig;
     1483            return kSM_BadNightlyConfig;
    9931484        }
    9941485        //get the size of the newly opened file.
    9951486        struct stat st;
    996         stat(fFullDailyLogFileName.c_str(), &st);
    997         fBaseSizeDaily = st.st_size;   
    998         stat(fFullDailyReportFileName.c_str(), &st);
    999         fBaseSizeDaily += st.st_size;
     1487        stat(fFullNightlyLogFileName.c_str(), &st);
     1488        fBaseSizeNightly = st.st_size; 
     1489        stat(fFullNightlyReportFileName.c_str(), &st);
     1490        fBaseSizeNightly += st.st_size;
    10001491        fFileSizesMap.clear();
    10011492        fBaseSizeRun = 0;
     
    10031494        //notify that files were opened
    10041495        std::string actualTargetDir;
    1005         if (fDailyFileName == ".")
     1496        if (fNightlyFileName == ".")
    10061497        {
    10071498                char currentPath[FILENAME_MAX];
     
    10171508        else
    10181509        {
    1019                 actualTargetDir = fDailyFileName;       
    1020         }
    1021 
    1022         NotifyOpenedFile(actualTargetDir + '/' + sTime.str(), 3, fOpenedDailyFiles);
     1510                actualTargetDir = fNightlyFileName;     
     1511        }
     1512        //notify that a new file has been opened.
     1513        NotifyOpenedFile(actualTargetDir + '/' + sTime.str(), 3, fOpenedNightlyFiles);
    10231514       
    1024        
    1025         return kSM_DailyOpen;   
     1515        return kSM_NightlyOpen;         
    10261516}
    10271517
     
    10461536        std::stringstream sTime;
    10471537        sTime << time.Y() << "_" << time.M() << "_" << time.D();
    1048         //we open the dailyFile anyway, otherwise this function shouldn't have been called.
    1049         if (!sub.dailyFile.IsOpen())
    1050         {
    1051                 std::string partialName = fDailyFileName + '/' + sTime.str() + '_' + serviceName + ".fits";
     1538        //we open the NightlyFile anyway, otherwise this function shouldn't have been called.
     1539        if (!sub.nightlyFile.IsOpen())
     1540        {
     1541                std::string partialName = fNightlyFileName + '/' + sTime.str() + '_' + serviceName + ".fits";
    10521542                AllocateFITSBuffers(sub);
    10531543                //get the size of the file we're about to open
     
    10561546                        struct stat st;
    10571547                        if (!stat(partialName.c_str(), &st))
    1058                                 fBaseSizeDaily += st.st_size;
     1548                                fBaseSizeNightly += st.st_size;
    10591549                        fFileSizesMap[partialName] = 0;
    10601550                }
    1061                 sub.dailyFile.Open(partialName, serviceName, NULL, &fNumSubAndFitsData.numOpenFits, Out());
     1551                sub.nightlyFile.Open(partialName, serviceName, NULL, &fNumSubAndFitsData.numOpenFits, Out());
    10621552                //notify the opening
    10631553                std::string actualTargetDir;
    1064                 if (fDailyFileName == ".")
     1554                if (fNightlyFileName == ".")
    10651555                {
    10661556                        char currentPath[FILENAME_MAX];
     
    10701560                else
    10711561                {
    1072                         actualTargetDir = fDailyFileName;       
     1562                        actualTargetDir = fNightlyFileName;     
    10731563                }               
    1074                 NotifyOpenedFile(actualTargetDir + '/' + sTime.str(), 4, fOpenedDailyFiles);
    1075                 fNumSubAndFits->updateService();
     1564                NotifyOpenedFile(actualTargetDir + '/' + sTime.str(), 4, fOpenedNightlyFiles);
     1565                if (fNumSubAndFitsIsOn)
     1566                        fNumSubAndFits->updateService();
     1567                if (fDebugIsOn)
     1568                {
     1569                        stringstream str;
     1570                        str << "Opened Nightly FITS: " << partialName << " and table: FACT-" << serviceName << ".current number of opened FITS: " << fNumSubAndFitsData.numOpenFits;
     1571                        Debug(str.str());       
     1572                }
    10761573        }
    10771574        if (!sub.runFile.IsOpen() && (GetCurrentState() == kSM_Logging))
    1078         {//buffer for the run file have already been allocated when doing the daily file
     1575        {//buffer for the run file have already been allocated when doing the Nightly file
    10791576                std::stringstream sRun;
    10801577                sRun << fRunNumber;
    10811578#ifdef ONE_RUN_FITS_ONLY
    1082                 std::string partialName = fRunFileName + '/' + sRun.str() + ".fits";//'_' + serviceName + ".fits";
     1579                std::string partialName = fRunFileName + '/' + sRun.str() + ".fits";
    10831580                if (fRunFitsFile == NULL)
    10841581                {
     
    11281625                sub.runFile.Open(partialName, serviceName, NULL, &fNumSubAndFitsData.numOpenFits, Out());
    11291626#endif //one_run_fits_only
    1130            fNumSubAndFits->updateService();
    1131 
     1627           if (fNumSubAndFitsIsOn)
     1628                   fNumSubAndFits->updateService();
     1629                if (fDebugIsOn)
     1630                {
     1631                        stringstream str;
     1632                        str << "Opened Run FITS: " << partialName << " and table: FACT-" << serviceName << ".current number of opened FITS: " << fNumSubAndFitsData.numOpenFits;
     1633                        Debug(str.str());       
     1634                }
    11321635        }
    11331636}       
     
    11401643        //Init the time columns of the file
    11411644        Description dateDesc(std::string("Time"), std::string("Modified Julian Date"), std::string("MjD"));
    1142         sub.dailyFile.AddStandardColumn(dateDesc, "1D", &fMjD, sizeof(double));
     1645        sub.nightlyFile.AddStandardColumn(dateDesc, "1D", &fMjD, sizeof(double));
    11431646        sub.runFile.AddStandardColumn(dateDesc, "1D", &fMjD, sizeof(double));
    11441647
    11451648        Description QoSDesc("Qos", "Quality of service", "None");
    1146         sub.dailyFile.AddStandardColumn(QoSDesc, "1J", &fQuality, sizeof(int));
     1649        sub.nightlyFile.AddStandardColumn(QoSDesc, "1J", &fQuality, sizeof(int));
    11471650        sub.runFile.AddStandardColumn(QoSDesc, "1J", &fQuality, sizeof(int));
    11481651
     
    11661669                {//TODO handle all the data format cases
    11671670                        case 'c':
    1168                                 dataQualifier <<  "S";
     1671                        case 'C':
     1672                                dataQualifier.str("S");
    11691673                        break;
    11701674                        case 's':
     
    11721676                        break;
    11731677                        case 'i':
     1678                        case 'I':
    11741679                                dataQualifier << "J";
    11751680                        break;
    11761681                        case 'l':
     1682                        case 'L':
    11771683                                dataQualifier << "J";
    11781684                                //TODO triple check that in FITS, long = int
    11791685                        break;
    11801686                        case 'f':
     1687                        case 'F':
    11811688                                dataQualifier << "E";
    11821689                        break;
    11831690                        case 'd':
     1691                        case 'D':
    11841692                                dataQualifier << "D";
    11851693                        break;
     
    11961704                       
    11971705                        default:
    1198                                 Error("THIS SHOULD NEVER BE REACHED. dataLogger.cc ln 948.");
     1706                                Error("THIS SHOULD NEVER BE REACHED. dataLogger.cc ln 1198.");
    11991707                };
    1200                 dataFormatsLocal.push_back(dataQualifier.str());
     1708                //we skip the variable length strings for now (in fits only)
     1709                if (dataQualifier.str() != "S")
     1710                        dataFormatsLocal.push_back(dataQualifier.str());
    12011711         }
    1202 
    1203          sub.dailyFile.InitDataColumns(fServiceList.GetDescriptions(sub.dimInfo->getName()), dataFormatsLocal, sub.dimInfo->getData(), size);
     1712         sub.nightlyFile.InitDataColumns(fServiceList.GetDescriptions(sub.dimInfo->getName()), dataFormatsLocal, sub.dimInfo->getData(), size);
    12041713         sub.runFile.InitDataColumns(fServiceList.GetDescriptions(sub.dimInfo->getName()), dataFormatsLocal, sub.dimInfo->getData(), size);
    12051714}
     
    12101719void DataLogger::WriteToFITS(SubscriptionType& sub)
    12111720{
    1212                 //dailyFile status (open or not) already checked
    1213                 if (sub.dailyFile.IsOpen())
    1214                         sub.dailyFile.Write(sub.fConv);
     1721                //nightly File status (open or not) already checked
     1722                if (sub.nightlyFile.IsOpen())
     1723                {
     1724                        sub.nightlyFile.Write(sub.fConv);
     1725                        if (fDebugIsOn)
     1726                        {
     1727                                Debug("Writing to nightly FITS " + sub.nightlyFile.fFileName); 
     1728                        }
     1729                }
    12151730                if (sub.runFile.IsOpen())
     1731                {
    12161732                        sub.runFile.Write(sub.fConv);
     1733                        if (fDebugIsOn)
     1734                        {
     1735                                Debug("Writing to Run FITS " + sub.runFile.fFileName); 
     1736                        }
     1737                }
    12171738}
    12181739#endif //if has_fits
     
    12261747int DataLogger::StartRunPlease()
    12271748{
     1749        if (fDebugIsOn)
     1750        {
     1751                Debug("Starting Run Logging...");       
     1752        }
    12281753        //attempt to open run file with current parameters
    12291754        if (fRunNumber == -1)
     
    13111836int DataLogger::StopRunPlease()
    13121837{
     1838        if (fDebugIsOn)
     1839        {
     1840                Debug("Stopping Run Logging...");       
     1841        }
    13131842        if (!fRunLogFile.is_open() || !fRunReportFile.is_open())
    13141843                return kSM_FatalError;
     
    13321861#endif
    13331862#endif
    1334         NotifyOpenedFile("None", 0, fOpenedRunFiles);
    1335         fNumSubAndFits->updateService();
     1863        NotifyOpenedFile("", 0, fOpenedRunFiles);
     1864        if (fNumSubAndFitsIsOn)
     1865                fNumSubAndFits->updateService();
    13361866        return kSM_WaitingRun;
    13371867
     
    13451875int DataLogger::GoToReadyPlease()
    13461876{
    1347         if (fDailyLogFile.is_open())
    1348                 fDailyLogFile.close();
    1349         if (fDailyReportFile.is_open())
    1350                 fDailyReportFile.close();
     1877        if (fDebugIsOn)
     1878        {
     1879                Debug("Going to the Ready state...");
     1880        }       
     1881        if (fNightlyLogFile.is_open())
     1882                fNightlyLogFile.close();
     1883        if (fNightlyReportFile.is_open())
     1884                fNightlyReportFile.close();
    13511885
    13521886        if (fRunLogFile.is_open())
     
    13591893                for (std::map<std::string, SubscriptionType>::iterator j = i->second.begin(); j != i->second.end(); j++)
    13601894                {
    1361                                 if (j->second.dailyFile.IsOpen())
    1362                                         j->second.dailyFile.Close();
     1895                                if (j->second.nightlyFile.IsOpen())
     1896                                        j->second.nightlyFile.Close();
    13631897                                if (j->second.runFile.IsOpen())
    13641898                                        j->second.runFile.Close();     
     
    13741908#endif
    13751909        if (GetCurrentState() == kSM_Logging)
    1376                 NotifyOpenedFile("None", 0, fOpenedRunFiles);
     1910                NotifyOpenedFile("", 0, fOpenedRunFiles);
    13771911        if (GetCurrentState() == kSM_Logging ||
    13781912            GetCurrentState() == kSM_WaitingRun ||
    1379             GetCurrentState() == kSM_DailyOpen)
     1913            GetCurrentState() == kSM_NightlyOpen)
    13801914        {
    1381                 NotifyOpenedFile("None", 0, fOpenedDailyFiles);
    1382                 fNumSubAndFits->updateService();
     1915                NotifyOpenedFile("", 0, fOpenedNightlyFiles);
     1916                if (fNumSubAndFitsIsOn)
     1917                        fNumSubAndFits->updateService();
    13831918        }
    13841919        return kSM_Ready;
     
    13901925//!     @returns
    13911926//!             kSM_WaitingRun
    1392 int DataLogger::DailyToWaitRunPlease()
    1393 {
     1927int DataLogger::NightlyToWaitRunPlease()
     1928{
     1929        if (fDebugIsOn)
     1930        {
     1931                Debug("Going to Wait Run Number state...");     
     1932        }
    13941933        return kSM_WaitingRun; 
     1934}
     1935
     1936void DataLogger::setBlackWhiteList(const std::string& black, bool isBlack)
     1937{
     1938        if (fDebugIsOn)
     1939        {
     1940                if (isBlack)
     1941                        Debug("Setting BLACK list: " + black); 
     1942                else
     1943                        Debug("Setting WHITE list: " + black);
     1944        }
     1945        fGreyList.clear();
     1946        stringstream stream(black);
     1947
     1948        string buffer;
     1949        while (getline(stream, buffer, '|')) {
     1950                fGreyList.insert(buffer);       
     1951        }
     1952        fIsBlackList = isBlack;
    13951953}
    13961954
     
    14361994    DataLogger logger(wout);
    14371995   
    1438 //    if (conf.Has("black-list"))
    1439 //      logger.setBlackList(conf.Get<std::string>("black-list"));
    1440 //    else if (conf.Has("white-list"))
    1441 //      logger.setWhiteList(conf.Get<std::string>("white-list"));
    1442 
     1996    if (conf.Has("black-list"))
     1997    {   if (conf.Get<std::string>("black-list") != "")
     1998                logger.setBlackWhiteList(conf.Get<std::string>("black-list"), true);
     1999            else if (conf.Has("white-list"))
     2000                {
     2001                        if (conf.Get<std::string>("white-list") != "")
     2002                                logger.setBlackWhiteList(conf.Get<std::string>("white-list"), false);
     2003                }
     2004    }
    14432005    shell.SetReceiver(logger);
    14442006
Note: See TracChangeset for help on using the changeset viewer.