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