LCOV - code coverage report
Current view: top level - libMagAOX/logger - logMap.hpp (source / functions) Coverage Total Hit
Test: MagAOX Lines: 41.9 % 296 124
Test Date: 2026-01-03 21:03:39 Functions: 40.0 % 5 2

            Line data    Source code
       1              : /** \file logMap.hpp
       2              :  * \brief Declares and defines the logMap class and related classes.
       3              :  * \author Jared R. Males (jaredmales@gmail.com)
       4              :  *
       5              :  * \ingroup logger_files
       6              :  *
       7              :  * History:
       8              :  * - 2020-01-02 created by JRM
       9              :  */
      10              : 
      11              : #ifndef logger_logMap_hpp
      12              : #define logger_logMap_hpp
      13              : 
      14              : #include <mx/sys/timeUtils.hpp>
      15              : using namespace mx::sys::tscomp;
      16              : 
      17              : #include <mx/ioutils/fileUtils.hpp>
      18              : 
      19              : #include <vector>
      20              : #include <map>
      21              : 
      22              : #include <flatlogs/flatlogs.hpp>
      23              : #include "../file/stdFileName.hpp"
      24              : 
      25              : #ifndef DEBUG_CRUMB
      26              : #define DEBUG_CRUMB(msg) {std::cerr << msg << '(' << __FILE__ << ' ' << __LINE__ << "\n";}
      27              : #endif
      28              : 
      29              : namespace MagAOX
      30              : {
      31              : namespace logger
      32              : {
      33              : 
      34              : #ifdef XWCTEST_NAMESPACE
      35              : namespace XWCTEST_NAMESPACE
      36              : {
      37              : #endif
      38              : 
      39              : /// Structure to hold a log file in memory, tracking when a new file needs to be opened.
      40              : struct logInMemory
      41              : {
      42              :     typedef XWC_DEFAULT_VERBOSITY verboseT;
      43              : 
      44              :     std::vector<char> m_memory; ///< The buffer holding the log data.
      45              : 
      46              :     flatlogs::timespecX m_startTime{ 0, 0 };
      47              :     flatlogs::timespecX m_endTime{ 0, 0 };
      48              : 
      49              :     int loadFile( file::stdFileName<verboseT> const &lfn );
      50              : };
      51              : 
      52              : /// Map of log entries by application name, mapping both to files and to loaded buffers.
      53              : template <class verboseT = XWC_DEFAULT_VERBOSITY>
      54              : struct logMap
      55              : {
      56              : 
      57              :     typedef file::stdSubDir<verboseT>   stdSubDirT;
      58              :     typedef file::stdFileName<verboseT> stdFileNameT;
      59              : 
      60              :     /// The app-name to file-name map type, for sorting the input files by application
      61              :     typedef std::map<std::string, std::set<stdFileNameT, file::compStdFileName<stdFileNameT>>> appToFileMapT;
      62              : 
      63              :     /// The app-name to buffer map type, for looking up the currently loaded logs for a given app.
      64              :     typedef std::map<std::string, logInMemory> appToBufferMapT;
      65              : 
      66              :     int m_searchDaySpan {100}; ///< Maximum number of days to search for files in the past/future.
      67              : 
      68              :     appToFileMapT m_appToFileMap;
      69              : 
      70              :     appToBufferMapT m_appToBufferMap;
      71              : 
      72              :     /// Add a list of files to the file map
      73              :     /** This is a worker function for loadAppToFileMap
      74              :      *
      75              :      * \returns mx::error_t::noerror on success
      76              :      * \returns mx::error_t::std_exception if a std::exception is thrown
      77              :      */
      78              :     mx::error_t addFileListToFileMap( const std::string              &dev,   /**< [in] the device name to add*/
      79              :                                       const std::vector<std::string> &flist, /**< [in] the file list from which to
      80              :                                                                                        add files*/
      81              :                                       size_t n0,                             /**< [in] the first entry in the file list
      82              :                                                                                        to add*/
      83              :                                       size_t nf                              /**< [in] one past the last entry in the
      84              :                                                                                        file list to add, e.g. flist.size()*/
      85              :     );
      86              : 
      87              :     /// Get log file names in a directory and distribute them into the map by app-name
      88              :     /** Finding no logs is not reported as an error (no exception is thrown).  You must check
      89              :      *  the size of m_appToFileMap to check if any files were found.
      90              :      *
      91              :      */
      92              :     mx::error_t loadAppToFileMap( const std::string &dir,        /**< [in] the directory to search for files
      93              :                                                                            (contains the dev/YYYY_MM_DD subdirs)*/
      94              :                                   const std::string  &dev,       ///< [in] the device name to search for logs of
      95              :                                   const std::string  &ext,       ///< [in] the extension to search for
      96              :                                   const stdFileNameT &firstFile, ///< [in] the first file that needs coverage
      97              :                                   const stdFileNameT &lastFile   ///< [in] the last file that needs coverage
      98              :     );
      99              : 
     100              :     /// Get the log for an event code which is the first prior to the supplied time
     101              :     int getPriorLog( char                      *&logBefore, ///< [out] pointer to the first byte of the prior log entry
     102              :                      const std::string          &appName,   ///< [in] the name of the app specifying which log to search
     103              :                      const flatlogs::eventCodeT &ev,        ///< [in] the event code to search for
     104              :                      const flatlogs::timespecX  &ts,        ///< [in] the timestamp to be prior to
     105              :                      char                       *hint = 0   /**< [in] [optional] a hint specifying
     106              :                                                                       where to start searching.  If null
     107              :                                                                       search starts at beginning.*/
     108              :     );
     109              : 
     110              :     /// Get the next log with the same event code which is after the supplied time
     111              :     int getNextLog( char             *&logAfter,   ///< [out] pointer to the first byte of the prior log entry
     112              :                     char              *logCurrent, ///< [in] The log to start from
     113              :                     const std::string &appName     ///< [in] the name of the app specifying which log to search
     114              :     );
     115              : 
     116              :     int getNearestLogs( flatlogs::bufferPtrT &logBefore, flatlogs::bufferPtrT &logAfter, const std::string &appName );
     117              : 
     118              :     int loadFiles( const std::string         &appName,  ///< MagAO-X app name for which to load files
     119              :                    const flatlogs::timespecX &startTime ///<
     120              :     );
     121              : };
     122              : 
     123              : template <class verboseT>
     124            9 : mx::error_t logMap<verboseT>::addFileListToFileMap( const std::string              &dev,
     125              :                                                     const std::vector<std::string> &flist,
     126              :                                                     size_t                          n0,
     127              :                                                     size_t                          nf )
     128              : {
     129              :     try
     130              :     {
     131              :         // clang-format off
     132              :         #ifdef XWCTEST_LOGMAP_AFLTFM_XWCE
     133              :             throw xwcException("std::bad_alloc"); // LCOV_EXCL_LINE
     134              :         #endif
     135              : 
     136              :         #ifdef XWCTEST_LOGMAP_AFLTFM_BADALL
     137              :             throw std::bad_alloc; // LCOV_EXCL_LINE
     138              :         #endif
     139              : 
     140              :         #ifdef XWCTEST_LOGMAP_AFLTFM_EXCEPTION
     141              :             throw std::exception; // LCOV_EXCL_LINE
     142              :         #endif
     143              :         // clang-format on
     144              : 
     145           51 :         for( size_t n = n0; n < nf; ++n )
     146              :         {
     147           21 :             file::stdFileName<verboseT> sfn( flist[n] );
     148              : 
     149           21 :             if( !sfn.valid() ) // this is just not a standard file name.
     150              :             {
     151            0 :                 continue;
     152              :             }
     153              : 
     154           21 :             if( sfn.appName() != dev ) // this is just a different app
     155              :             {
     156            0 :                 continue;
     157              :             }
     158              : 
     159           21 :             m_appToFileMap[dev].insert( sfn );
     160              :         }
     161              : 
     162            9 :         return mx::error_t::noerror;
     163              :     }
     164            0 :     catch( const xwcException &e )
     165              :     {
     166            0 :         std::throw_with_nested( xwcException( "adding file to map" ) );
     167              :     }
     168            0 :     catch( const std::bad_alloc &e )
     169              :     {
     170            0 :         std::throw_with_nested( xwcException( "adding file to map" ) );
     171              :     }
     172            0 :     catch( const std::exception &e )
     173              :     {
     174            0 :         return mx::error_report<verboseT>( mx::error_t::std_exception,
     175            0 :                                            std::string( "adding file to map:" ) + e.what() );
     176              :     }
     177              : }
     178              : 
     179              : template <class verboseT>
     180           12 : mx::error_t logMap<verboseT>::loadAppToFileMap( const std::string                 &dir,
     181              :                                                 const std::string                 &dev,
     182              :                                                 const std::string                 &ext,
     183              :                                                 const file::stdFileName<verboseT> &firstFile,
     184              :                                                 const file::stdFileName<verboseT> &lastFile )
     185              : {
     186              :     mx::error_t errc;
     187              : 
     188           12 :     bool isdir = mx::ioutils::dir_exists_is( dir, errc );
     189              : 
     190           12 :     mx_error_check_code( errc );
     191              : 
     192           11 :     if( !isdir )
     193              :     {
     194            1 :         return mx::error_report<verboseT>( mx::error_t::dirnotfound, dir + " does not exist" );
     195              :     }
     196              : 
     197              :     // Timestamps for defining the previous log and the following log
     198           10 :     flatlogs::timespecX prevts = firstFile.timestamp( &errc );
     199           10 :     mx_error_check_code( errc );
     200              : 
     201            9 :     prevts.time_s -= 60; // Move 60 seconds in future.  This is a config setting
     202              : 
     203            9 :     flatlogs::timespecX follts = lastFile.timestamp( &errc );
     204            9 :     mx_error_check_code( errc );
     205              : 
     206            8 :     follts.time_s += 3600; // Move 3600 seconds in future.  This is a config setting
     207              : 
     208              :     // Coordinates of the previous log, after it's found
     209            8 :     bool            prevLogFound = false;
     210            8 :     file::stdSubDir prevLogSubDir;
     211            8 :     size_t          prevLogFile_n = 0;
     212              : 
     213              :     // Coordinates of the following log, after it's found
     214            8 :     bool            follLogFound = false;
     215            8 :     file::stdSubDir follLogSubDir;
     216              :     size_t          follLogFile_n;
     217              : 
     218            8 :     std::string basedir = dir + '/' + dev + '/';
     219              : 
     220            8 :     file::stdSubDir subdir = firstFile.subDir( &errc );
     221            8 :     mx_error_check_code( errc );
     222              : 
     223            8 :     int ndays = 0;
     224              : 
     225          622 :     while( prevLogFound == false && ndays < m_searchDaySpan )
     226              :     {
     227          307 :         ++ndays;
     228              : 
     229          307 :         std::vector<std::string> tmp_flist;
     230              : 
     231          307 :         isdir = mx::ioutils::dir_exists_is( basedir + subdir.path(), errc );
     232          307 :         mx_error_check_code( errc );
     233              : 
     234          307 :         if( !isdir ) // this subdir doesn't exist so go around
     235              :         {
     236          301 :             mx_error_check( subdir.subDay() );
     237          301 :             continue;
     238          301 :         }
     239              : 
     240           12 :         mx_error_check( mx::ioutils::getFileNames( tmp_flist, basedir + subdir.path(), dev, "", ext ) );
     241              : 
     242            6 :         if( tmp_flist.size() == 0 ) // this subdir has no files in it so go around
     243              :         {
     244            0 :             mx_error_check( subdir.subDay() );
     245            0 :             continue;
     246            0 :         }
     247              : 
     248              :         // Start from last file and move backwards
     249           35 :         for( size_t n = tmp_flist.size() - 1; n != static_cast<size_t>( -1 ); --n )
     250              :         {
     251           17 :             file::stdFileName<verboseT> sfn;
     252              : 
     253              :             try
     254              :             {
     255              :                 // clang-format off
     256              :                 #ifdef XWCTEST_LOGMAP_LATFM_BADALL1
     257              :                     throw xwcException("std::bad_alloc"); // LCOV_EXCL_LINE
     258              :                 #endif
     259              :                 // clang-format on
     260              : 
     261           17 :                 sfn.fullName( tmp_flist[n] );
     262              :             }
     263            0 :             catch( ... )
     264              :             {
     265            0 :                 std::throw_with_nested( xwcException( "parsing filename" ) );
     266              :             }
     267              : 
     268           17 :             if( !sfn.valid() ) // on any other errors we assume it's not a valid log file and just go around
     269              :             {
     270            0 :                 continue;
     271              :             }
     272              : 
     273           17 :             if( sfn.timestamp() <= prevts )
     274              :             {
     275            5 :                 prevLogFound  = true;
     276            5 :                 prevLogSubDir = subdir;
     277            5 :                 prevLogFile_n = n;
     278              : 
     279            5 :                 std::cerr << "found previous log: " << tmp_flist[n] << '\n';
     280            5 :                 break;
     281              :             }
     282              :         } // iteration over tmp_flist
     283              : 
     284            6 :         if( !prevLogFound )
     285              :         {
     286            1 :             mx_error_check( subdir.subDay() );
     287              :         }
     288              :     }
     289              : 
     290            8 :     if( !prevLogFound )
     291              :     {
     292            3 :         return mx::error_t::noerror; // this is not an error...yet.  one must check the map to see if 0 files found.
     293              :     }
     294              : 
     295            5 :     subdir = lastFile.subDir( &errc );
     296            5 :     mx_error_check_code( errc );
     297              : 
     298            5 :     ndays = 0;
     299              : 
     300          111 :     while( follLogFound == false && ndays < m_searchDaySpan )
     301              :     {
     302              :         try
     303              :         {
     304              :             // clang-format off
     305              :             #ifdef XWCTEST_LOGMAP_LATFM_BADALL2
     306              :                 throw xwcException("std::bad_alloc"); // LCOV_EXCL_LINE
     307              :             #endif
     308              :             // clang-format on
     309              : 
     310          106 :             ++ndays;
     311              : 
     312          106 :             std::vector<std::string> tmp_flist;
     313              : 
     314          106 :             isdir = mx::ioutils::dir_exists_is( basedir + subdir.path(), errc );
     315              : 
     316          106 :             if( errc != mx::error_t::noerror )
     317              :             {
     318            0 :                 return mx::error_report<verboseT>( errc, "error from std::filesystem" );
     319              :             }
     320              : 
     321          106 :             if( !isdir ) // this subdir doesn't exist so go around
     322              :             {
     323          100 :                 mx_error_check( subdir.addDay() );
     324          100 :                 continue;
     325          100 :             }
     326              : 
     327           12 :             mx_error_check( mx::ioutils::getFileNames( tmp_flist, basedir + subdir.path(), dev, "", ext ) );
     328              : 
     329            6 :             if( tmp_flist.size() == 0 ) // this subdir has no files so go ahead
     330              :             {
     331            0 :                 mx_error_check( subdir.addDay() );
     332            0 :                 continue;
     333            0 :             }
     334              : 
     335              :             // Start from first file and move forward
     336           34 :             for( size_t n = 0; n < tmp_flist.size(); ++n )
     337              :             {
     338           16 :                 file::stdFileName<verboseT> sfn;
     339              : 
     340           16 :                 sfn.fullName( tmp_flist[n] );
     341              : 
     342           16 :                 if( !sfn.valid() ) // any other errors just means it's not a standard file
     343              :                 {
     344            0 :                     continue;
     345              :                 }
     346              : 
     347           16 :                 if( sfn.timestamp() >= follts )
     348              :                 {
     349            4 :                     follLogFound  = true;
     350            4 :                     follLogSubDir = subdir;
     351            4 :                     follLogFile_n = n;
     352            4 :                     break;
     353              :                 }
     354              : 
     355              :             } // iteration over tmp_flist
     356              : 
     357            6 :             if( !follLogFound )
     358              :             {
     359            2 :                 mx_error_check( subdir.addDay() );
     360              :             }
     361          106 :         }
     362            0 :         catch( ... )
     363              :         {
     364            0 :             std::throw_with_nested( xwcException( "parsing filename" ) );
     365              :         }
     366              :     }
     367              : 
     368              :     // In this case we use the last log available and hope for the best
     369            5 :     if( !follLogFound )
     370              :     {
     371            1 :         follLogSubDir = lastFile.subDir( &errc );
     372            1 :         mx_error_check_code( errc );
     373              : 
     374            1 :         DEBUG_CRUMB("checking for: " + basedir + follLogSubDir.path());
     375              : 
     376            1 :         bool exists = mx::ioutils::dir_exists_is(basedir + follLogSubDir.path(), errc);
     377              : 
     378            1 :         int n =0;
     379            1 :         while(!exists && n < m_searchDaySpan)
     380              :         {
     381            0 :             follLogSubDir.subDay();
     382              : 
     383            0 :             DEBUG_CRUMB("checking for: " + basedir + follLogSubDir.path());
     384              : 
     385            0 :             exists = mx::ioutils::dir_exists_is(basedir + follLogSubDir.path(), errc);
     386            0 :             ++n;
     387              :         }
     388              : 
     389            1 :         follLogFile_n = static_cast<size_t>( -1 );
     390              :     }
     391              : 
     392            5 :     if( prevLogSubDir == follLogSubDir ) // special case, probably most common
     393              :     {
     394            2 :         DEBUG_CRUMB("prevLogSubDir == follLogSubDir");
     395              : 
     396              :         try
     397              :         {
     398              :             #ifdef XWCTEST_LOGMAP_LATFM_BADALL3
     399              :                 throw xwcException("std::bad_alloc"); // LCOV_EXCL_LINE
     400              :             #endif
     401              :             // clang-format on
     402              : 
     403            2 :             subdir = prevLogSubDir;
     404              : 
     405            2 :             std::vector<std::string> tmp_flist;
     406              : 
     407            4 :             mx_error_check( mx::ioutils::getFileNames( tmp_flist, basedir + subdir.path(), dev, "", ext ) );
     408              : 
     409            2 :             if( follLogFile_n == static_cast<size_t>( -1 ) )
     410              :             {
     411            0 :                 follLogFile_n = tmp_flist.size();
     412              :             }
     413              :             else
     414              :             {
     415            2 :                 ++follLogFile_n;
     416            2 :                 if( follLogFile_n > tmp_flist.size() )
     417              :                 {
     418            0 :                     return mx::error_report<verboseT>( mx::error_t::sizeerr,
     419            0 :                                                        "miscounted the number of files somewhere" );
     420              :                 }
     421              :             }
     422              : 
     423            2 :             mx_error_check( addFileListToFileMap( dev, tmp_flist, prevLogFile_n, follLogFile_n ) );
     424            2 :         }
     425            0 :         catch( ... )
     426              :         {
     427            0 :             std::throw_with_nested( xwcException( "adding file list to map" ) );
     428              :         }
     429              :     }
     430              :     else
     431              :     {
     432            3 :         std::cerr << "prevLogSubDir != follLogSubDir\n";
     433              :         try
     434              :         {
     435              :             // clang-format off
     436              :             #ifdef XWCTEST_LOGMAP_LATFM_XWCE4
     437              :                 throw xwcException("std::bad_alloc"); // LCOV_EXCL_LINE
     438              :             #endif
     439              : 
     440              :             #ifdef XWCTEST_LOGMAP_LATFM_BADALL4
     441              :                 throw xwcException("std::bad_alloc"); // LCOV_EXCL_LINE
     442              :             #endif
     443              :             // clang-format on
     444              : 
     445            3 :             subdir = prevLogSubDir;
     446              : 
     447            3 :             std::vector<std::string> tmp_flist;
     448              : 
     449            6 :             mx_error_check( mx::ioutils::getFileNames( tmp_flist, basedir + subdir.path(), dev, "", ext ) );
     450              : 
     451            3 :             mx_error_check( addFileListToFileMap( dev, tmp_flist, prevLogFile_n, tmp_flist.size() ) );
     452            3 :         }
     453            0 :         catch( ... )
     454              :         {
     455            0 :             std::throw_with_nested( xwcException( "adding file list to map" ) );
     456              :         }
     457              : 
     458            3 :         mx_error_check( subdir.addDay() );
     459              : 
     460            8 :         while( subdir < follLogSubDir )
     461              :         {
     462              :             try
     463              :             {
     464              :                 // clang-format off
     465              :                 #ifdef XWCTEST_LOGMAP_LATFM_XWCE5
     466              :                     throw xwcException("std::bad_alloc"); // LCOV_EXCL_LINE
     467              :                 #endif
     468              : 
     469              :                 #ifdef XWCTEST_LOGMAP_LATFM_BADALL5
     470              :                     throw xwcException("std::bad_alloc"); // LCOV_EXCL_LINE
     471              :                 #endif
     472              :                 // clang-format on
     473              : 
     474            5 :                 if( !std::filesystem::exists( basedir + subdir.path() ) )
     475              :                 {
     476            4 :                     mx_error_check( subdir.addDay() );
     477            4 :                     continue;
     478            4 :                 }
     479              : 
     480            1 :                 std::vector<std::string> tmp_flist;
     481              : 
     482            2 :                 mx_error_check( mx::ioutils::getFileNames( tmp_flist, basedir + subdir.path(), dev, "", ext ) );
     483              : 
     484            1 :                 mx_error_check( addFileListToFileMap( dev, tmp_flist, 0, tmp_flist.size() ) );
     485              : 
     486            1 :                 mx_error_check( subdir.addDay() );
     487            1 :             }
     488            0 :             catch( ... )
     489              :             {
     490            0 :                 std::throw_with_nested( xwcException( "adding file list to map" ) );
     491              :             }
     492              :         }
     493              : 
     494              :         try
     495              :         {
     496              :             // clang-format off
     497              :             #ifdef XWCTEST_LOGMAP_LATFM_XWCE6
     498              :                 throw xwcException("std::bad_alloc"); // LCOV_EXCL_LINE
     499              :             #endif
     500              : 
     501              :             #ifdef XWCTEST_LOGMAP_LATFM_BADALL6
     502              :                 throw xwcException("std::bad_alloc"); // LCOV_EXCL_LINE
     503              :             #endif
     504              :             // clang-format on
     505              : 
     506            3 :             std::vector<std::string> tmp_flist;
     507              : 
     508              :             /*mx::error_t errc = mx::ioutils::getFileNames( tmp_flist, basedir + subdir.path(), dev, "", ext );
     509              :             if(errc != mx::error_t::dirnotfound)
     510              :             {
     511              :                 return mx::error_report<verboseT>(errc);
     512              :             }*/
     513              : 
     514            6 :             mx_error_check( mx::ioutils::getFileNames( tmp_flist, basedir + subdir.path(), dev, "", ext ) );
     515              : 
     516              : 
     517            3 :             if(errc == mx::error_t::noerror)
     518              :             {
     519              : 
     520            3 :                 if( follLogFile_n == static_cast<size_t>( -1 ) )
     521              :                 {
     522            1 :                     follLogFile_n = tmp_flist.size();
     523              :                 }
     524              :                 else
     525              :                 {
     526            2 :                     ++follLogFile_n;
     527            2 :                     if( follLogFile_n > tmp_flist.size() )
     528              :                     {
     529            0 :                         return mx::error_report<verboseT>( mx::error_t::sizeerr,
     530            0 :                                                        "miscounted the number of files somewhere" );
     531              :                     }
     532              :                 }
     533              : 
     534            3 :                 mx_error_check( addFileListToFileMap( dev, tmp_flist, 0, follLogFile_n ) );
     535              :             }
     536            3 :         }
     537            0 :         catch( ... )
     538              :         {
     539            0 :             std::throw_with_nested( xwcException( "adding file list to map" ) );
     540              :         }
     541              :     }
     542              : 
     543            5 :     return mx::error_t::noerror;
     544            8 : }
     545              : 
     546              : template <class verboseT>
     547            0 : int logMap<verboseT>::getPriorLog( char                      *&logBefore,
     548              :                                    const std::string          &appName,
     549              :                                    const flatlogs::eventCodeT &ev,
     550              :                                    const flatlogs::timespecX  &ts,
     551              :                                    char                       *hint )
     552              : {
     553              :     flatlogs::eventCodeT evL;
     554              : 
     555            0 :     DEBUG_CRUMB("");
     556              : 
     557            0 :     if( m_appToFileMap[appName].size() == 0 )
     558              :     {
     559            0 :         std::cerr << __FILE__ << " " << __LINE__ << " getPriorLog empty map\n";
     560            0 :         return -1;
     561              :     }
     562              : 
     563            0 :     DEBUG_CRUMB("");
     564              : 
     565            0 :     logInMemory &lim = m_appToBufferMap[appName];
     566              : 
     567            0 :     flatlogs::timespecX et = lim.m_endTime;
     568            0 :     et.time_s += 30;
     569            0 :     if( lim.m_startTime > ts || et < ts )
     570              :     {
     571            0 :         DEBUG_CRUMB("");
     572              : 
     573            0 :         if( loadFiles( appName, ts ) < 0 )
     574              :         {
     575            0 :             std::cerr << __FILE__ << " " << __LINE__ << " error returned from loadfiles\n";
     576            0 :             return -1;
     577              :         }
     578              :     }
     579              : 
     580              :     char *buffer, *priorBuffer;
     581              : 
     582            0 :     if( hint )
     583              :     {
     584            0 :         if( flatlogs::logHeader::timespec( hint ) <= ts )
     585              :         {
     586            0 :             buffer = hint;
     587              :         }
     588              :         else
     589              :         {
     590            0 :             buffer = lim.m_memory.data();
     591              :         }
     592              :     }
     593              :     else
     594              :     {
     595            0 :         buffer = lim.m_memory.data();
     596              :     }
     597              : 
     598            0 :     priorBuffer = buffer;
     599            0 :     evL         = flatlogs::logHeader::eventCode( buffer );
     600              : 
     601            0 :     while( evL != ev )
     602              :     {
     603            0 :         priorBuffer = buffer;
     604            0 :         buffer += flatlogs::logHeader::totalSize( buffer );
     605            0 :         if( buffer >= lim.m_memory.data() + lim.m_memory.size() )
     606            0 :             break;
     607            0 :         evL = flatlogs::logHeader::eventCode( buffer );
     608              :     }
     609              : 
     610            0 :     if( evL != ev )
     611              :     {
     612            0 :         std::cerr << __FILE__ << " " << __LINE__ << " Event code not found.\n";
     613            0 :         return -1;
     614              :     }
     615              : 
     616            0 :     if( flatlogs::logHeader::timespec( buffer ) < ts )
     617              :     {
     618            0 :         while( flatlogs::logHeader::timespec( buffer ) < ts ) // Loop until buffer is after the timestamp we want
     619              :         {
     620            0 :             if( buffer > lim.m_memory.data() + lim.m_memory.size() )
     621              :             {
     622            0 :                 std::cerr << __FILE__ << " " << __LINE__
     623            0 :                           << " attempt to read too mach data, possible log corruption.\n";
     624            0 :                 return -1;
     625              :             }
     626              : 
     627            0 :             if( buffer == lim.m_memory.data() + lim.m_memory.size() )
     628              :             {
     629            0 :                 std::cerr << __FILE__ << " " << __LINE__ << " did not find following log for " << appName
     630            0 :                           << " -- need to load more data.\n";
     631              :                 // Proper action here is to load the next file if possible...
     632            0 :                 return 1;
     633              :             }
     634              : 
     635            0 :             priorBuffer = buffer;
     636              : 
     637            0 :             buffer += flatlogs::logHeader::totalSize( buffer );
     638              : 
     639            0 :             evL = flatlogs::logHeader::eventCode( buffer );
     640              : 
     641            0 :             while( evL != ev ) // Find the next log with the event code we want.
     642              :             {
     643            0 :                 if( buffer > lim.m_memory.data() + lim.m_memory.size() )
     644              :                 {
     645            0 :                     std::cerr << __FILE__ << " " << __LINE__
     646            0 :                               << " attempt to read too mach data, possible log corruption.\n";
     647            0 :                     return -1;
     648              :                 }
     649              : 
     650            0 :                 if( buffer == lim.m_memory.data() + lim.m_memory.size() )
     651              :                 {
     652            0 :                     std::cerr << __FILE__ << " " << __LINE__ << " did not find following log for " << appName
     653            0 :                               << " -- need to load more data.\n";
     654              :                     // Proper action here is to load the next file if possible...
     655            0 :                     return 1;
     656              :                 }
     657              : 
     658            0 :                 buffer += flatlogs::logHeader::totalSize( buffer );
     659            0 :                 evL = flatlogs::logHeader::eventCode( buffer );
     660              :             }
     661              :         }
     662              :     }
     663              : 
     664            0 :     logBefore = priorBuffer;
     665              : 
     666            0 :     return 0;
     667              : } // getPriorLog
     668              : 
     669              : template <class verboseT>
     670            0 : int logMap<verboseT>::getNextLog( char *&logAfter, char *logCurrent, const std::string &appName )
     671              : {
     672              :     flatlogs::eventCodeT ev, evL;
     673              : 
     674            0 :     logInMemory &lim = m_appToBufferMap[appName];
     675              : 
     676              :     char *buffer;
     677              : 
     678            0 :     ev = flatlogs::logHeader::eventCode( logCurrent );
     679              : 
     680            0 :     buffer = logCurrent;
     681              : 
     682            0 :     buffer += flatlogs::logHeader::totalSize( buffer );
     683            0 :     if( buffer >= lim.m_memory.data() + lim.m_memory.size() )
     684              :     {
     685            0 :         std::cerr << __FILE__ << " " << __LINE__ << " Reached end of data for " << appName
     686            0 :                   << " -- need to load more data\n";
     687              :         // propoer action is to load the next file if possible.
     688            0 :         return 1;
     689              :     }
     690              : 
     691            0 :     evL = flatlogs::logHeader::eventCode( buffer );
     692              : 
     693            0 :     while( evL != ev )
     694              :     {
     695            0 :         buffer += flatlogs::logHeader::totalSize( buffer );
     696            0 :         if( buffer >= lim.m_memory.data() + lim.m_memory.size() )
     697              :         {
     698            0 :             std::cerr << __FILE__ << " " << __LINE__ << " Reached end of data for " << appName
     699            0 :                       << "-- need to load more data\n";
     700              :             // propoer action is to load the next file if possible.
     701            0 :             return 1;
     702              :         }
     703            0 :         evL = flatlogs::logHeader::eventCode( buffer );
     704              :     }
     705              : 
     706            0 :     if( evL != ev )
     707              :     {
     708            0 :         std::cerr << "Event code not found.\n";
     709            0 :         return -1;
     710              :     }
     711              : 
     712            0 :     logAfter = buffer;
     713              : 
     714            0 :     return 0;
     715              : }
     716              : 
     717              : template <class verboseT>
     718            0 : int logMap<verboseT>::loadFiles( const std::string &appName, const flatlogs::timespecX &startTime )
     719              : {
     720            0 :     if( m_appToFileMap[appName].size() == 0 )
     721              :     {
     722            0 :         std::cerr << "*************************************\n\n";
     723            0 :         std::cerr << "No files for " << appName << "\n";
     724            0 :         std::cerr << "*************************************\n\n";
     725            0 :         return -1;
     726              :     }
     727              : 
     728              : #ifdef DEBUG
     729              :     std::cerr << __FILE__ << " " << __LINE__ << "\n";
     730              : #endif
     731              : 
     732              :     // First check if already loaded files cover this time
     733            0 :     if( m_appToBufferMap[appName].m_memory.size() > 0 )
     734              :     {
     735            0 :         if( m_appToBufferMap[appName].m_startTime <= startTime && m_appToBufferMap[appName].m_endTime >= startTime )
     736              :         {
     737            0 :             std::cerr << "good!\n";
     738            0 :             return 0;
     739              :         }
     740              : 
     741              : #ifdef DEBUG
     742              :         std::cerr << __FILE__ << " " << __LINE__ << "\n";
     743              : #endif
     744              : 
     745            0 :         if( m_appToBufferMap[appName].m_startTime > startTime ) // Files don't go back far enough
     746              :         {
     747              : #ifdef DEBUG
     748              :             std::cerr << __FILE__ << " " << __LINE__ << "\n";
     749              : #endif
     750              : 
     751            0 :             auto last = m_appToFileMap[appName].begin();
     752            0 :             while( last->timestamp() < m_appToBufferMap[appName].m_startTime )
     753              :             {
     754            0 :                 ++last;
     755            0 :                 if( last == m_appToFileMap[appName].end() )
     756            0 :                     break;
     757              :             }
     758              :             // Now last is the last file to open in the for loop sense.
     759            0 :             auto first = last;
     760              : 
     761            0 :             while( first->timestamp() > startTime )
     762              :             {
     763            0 :                 --first;
     764            0 :                 if( first == m_appToFileMap[appName].begin() )
     765            0 :                     break;
     766              :             }
     767              : 
     768              :             // Now open each of these files, in reverse
     769            0 :             std::cerr << "open earlier files!\n";
     770            0 :             --last;
     771            0 :             --first;
     772            0 :             for( auto it = last; it != first; --it )
     773              :             {
     774            0 :                 m_appToBufferMap[appName].loadFile( *it );
     775              :             }
     776              : 
     777            0 :             return 0;
     778              :         }
     779              :         else
     780              :         {
     781            0 :             auto first = m_appToFileMap[appName].end();
     782            0 :             --first;
     783              : 
     784            0 :             while( first->timestamp() > m_appToBufferMap[appName].m_endTime )
     785              :             {
     786            0 :                 --first;
     787            0 :                 if( first == m_appToFileMap[appName].begin() )
     788            0 :                     break;
     789              :             }
     790            0 :             ++first;
     791            0 :             auto last = first;
     792            0 :             while( last->timestamp() < startTime )
     793              :             {
     794            0 :                 ++last;
     795            0 :                 if( last == m_appToFileMap[appName].end() )
     796            0 :                     break;
     797              :             }
     798              : 
     799              :             // Now open each of these files
     800            0 :             std::cerr << "open later file for " << appName << "!\n";
     801            0 :             for( auto it = first; it != last; ++it )
     802              :             {
     803            0 :                 m_appToBufferMap[appName].loadFile( *it );
     804              :             }
     805            0 :             return 0;
     806              :         }
     807              :     }
     808              : 
     809              : #ifdef DEBUG
     810              :     std::cerr << __FILE__ << " " << __LINE__ << "\n";
     811              : #endif
     812              : 
     813            0 :     auto before = m_appToFileMap[appName].begin();
     814              : 
     815            0 :     for( ; before != m_appToFileMap[appName].end(); ++before )
     816              :     {
     817            0 :         if( !( before->timestamp() < startTime ) )
     818              :         {
     819            0 :             break;
     820              :         }
     821              :     }
     822              : 
     823              : #ifdef debug
     824              :     std::cerr << __FILE__ << " " << __LINE__ << "\n";
     825              : #endif
     826              : 
     827            0 :     if( before == m_appToFileMap[appName].begin() )
     828              :     {
     829            0 :         std::cerr << "No files in range for " << appName << "\n";
     830              :     }
     831            0 :     --before;
     832              : 
     833              : #ifdef DEBUG
     834              :     std::cerr << __FILE__ << " " << __LINE__ << "\n";
     835              : #endif
     836              : 
     837            0 :     m_appToBufferMap.emplace( std::pair<std::string, logInMemory>( appName, logInMemory() ) );
     838              : 
     839              : #ifdef DEBUG
     840              :     std::cerr << __FILE__ << " " << __LINE__ << "\n";
     841              : #endif
     842              : 
     843            0 :     m_appToBufferMap[appName].loadFile( *before );
     844            0 :     if( ++before != m_appToFileMap[appName].end() )
     845              :     {
     846            0 :         m_appToBufferMap[appName].loadFile( *before );
     847              :     }
     848              : 
     849              : #ifdef DEBUG
     850              :     std::cerr << __FILE__ << " " << __LINE__ << "\n";
     851              : #endif
     852              : 
     853            0 :     return 0;
     854              : }
     855              : 
     856              : #ifdef XWCTEST_NAMESPACE
     857              : } // namespace XWCTEST_NAMESPACE
     858              : #endif
     859              : 
     860              : extern template class logMap<XWC_DEFAULT_VERBOSITY>;
     861              : 
     862              : } // namespace logger
     863              : } // namespace MagAOX
     864              : 
     865              : #endif // logger_logMap_hpp
        

Generated by: LCOV version 2.0-1