LCOV - code coverage report
Current view: top level - ugbase/common - log.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 20.0 % 5 1
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 2 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2010-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Authors: Andreas Vogel, Sebastian Reiter
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #ifndef __H__UG__COMMON__LOG__
      34              : #define __H__UG__COMMON__LOG__
      35              : 
      36              : #include <iostream>
      37              : #include <fstream>
      38              : #include <string>
      39              : #include <sstream>
      40              : #include "util/ostream_buffer_splitter.h"
      41              : #include "types.h"
      42              : #include "ug_config.h"
      43              : 
      44              : #include <vector>
      45              : #include <map>
      46              : #include "common/util/crc32.h"
      47              : #include "debug_id.h"
      48              : 
      49              : 
      50              : //      in order to support VRL logs, we're including bindings_vrl.h
      51              : //  this is necessary to get access to the JVM environment
      52              : #ifdef UG_FOR_VRL
      53              :                 #include <sstream>
      54              :                 #include "bindings/vrl/messaging.h"
      55              : #endif
      56              : 
      57              : namespace ug{
      58              : 
      59              : /// \addtogroup ugbase_common
      60              : /// \{
      61              : 
      62              :         const uint64 UNIT_KILO     = 1024;                   // 2^{10}
      63              :         const uint64 UNIT_MEGA     = UNIT_KILO * 1024;       // 2^{20} =                 1'048'576
      64              :         const uint64 UNIT_GIGA     = UNIT_MEGA * 1024;       // 2^{30} =             1'073'741'824
      65              :         const uint64 UNIT_TERA     = UNIT_GIGA * 1024ll;     // 2^{40} =         1'099'511'627'776
      66              :         const uint64 UNIT_PETA     = UNIT_TERA * 1024ll;     // 2^{50} =     1'125'899'906'842'624
      67              :         const uint64 UNIT_EXA      = UNIT_PETA * 1024ll;     // 2^{60} = 1'152'921'504'606'846'976
      68              :         //const uint64_t UNIT_ZETTA    = UNIT_EXA  * 1024ll;   // 2^{70} -- too big for 64 bit 'long long int'!
      69              :         
      70              :         const uint64 UNIT_KILO_SI  = 1000;                   // 10^{ 3}
      71              :         const uint64 UNIT_MEGA_SI  = UNIT_KILO_SI * 1000;    // 10^{ 6}
      72              :         const uint64 UNIT_GIGA_SI  = UNIT_MEGA_SI * 1000;    // 10^{ 9}
      73              :         const uint64 UNIT_TERA_SI  = UNIT_GIGA_SI * 1000ll;  // 10^{12}
      74              :         const uint64 UNIT_PETA_SI  = UNIT_TERA_SI * 1000ll;  // 10^{15}
      75              :         const uint64 UNIT_EXA_SI   = UNIT_PETA_SI * 1000ll;  // 10^{18}
      76              :         //const uint64_t UNIT_ZETTA_SI = UNIT_EXA_SI  * 1000ll;// 10^{21} -- too big for 64 bit 'long long int'!
      77              : 
      78              : 
      79              : 
      80              : // LogAssistant
      81              : /**
      82              :  * This class provides infrastructure for logging. It separates the log messages
      83              :  * in different levels:
      84              :  *
      85              :  * logger() returns the output stream for normal User information output.
      86              :  * debug_logger() returns the output stream for debug informations.
      87              :  *
      88              :  * Debug messages are grouped by tags and debug levels. It is intended, that
      89              :  * only messages are printed, when the current level is equal or greater than
      90              :  * the debug level chosen in the code.
      91              :  *
      92              :  * Please note that this class operates on std::clog. Thus, if output-options
      93              :  * are changed (e.g. file-logging enabled) the stream buffer on which clog
      94              :  * operates will change too.
      95              :  */
      96              : class UG_API LogAssistant
      97              : {
      98              :         public:
      99              :         ///     returns a reference to the single instance of LogAssistant
     100              :                 static LogAssistant& instance();
     101              : 
     102              :         ///     flushes all buffers before deletion
     103              :                 ~LogAssistant();
     104              : 
     105              :         /// enables or disables file output.
     106              :         /** a filename can be specified. Default is 'uglog.log'.
     107              :          *      Please note that only the filename given at the first call is considered.
     108              :          *      Filelogging is disabled by default.
     109              :          */
     110              :                 bool enable_file_output(bool bEnable, const char* filename = "uglog.log");
     111              : 
     112              :         /// renames output file if opened.
     113              :                 bool rename_log_file(const char * newname);
     114              : 
     115              :         ///     enables or disables terminal output.
     116              :         /**     terminal output is enbled by default.*/
     117              :                 bool enable_terminal_output(bool bEnable);
     118              : 
     119              :         /// returns the debug output stream
     120              :                 inline std::ostream& debug_logger();
     121              : 
     122              :         /// returns the normal output stream
     123              :                 inline std::ostream& logger();
     124              : 
     125              :         ///     returns the error output stream
     126              :         /**     Note that error-logs are not immediately visible. Instead they are
     127              :          * gathered and can be printed in one block using LogAssistant::flush_error_log().*/
     128              :                 inline std::ostream& error_logger();
     129              : 
     130              :         ///     outputs all gathered error-logs to the standard logger and clears the error log.
     131              :                 void flush_error_log();
     132              : 
     133              :         /// sets the debug level of all tags to 'lev'
     134            0 :                 bool set_debug_levels(int lev)
     135              :                 {
     136            1 :                         return GetDebugIDManager().set_debug_levels(lev);
     137              :                 }
     138              : 
     139              :         /// returns the debug level of debugID
     140              :                 inline int get_debug_level(DebugID &debugID) const
     141              :                 {
     142              :                         return GetDebugIDManager().get_debug_level(debugID);
     143              :                 }
     144              :         /// returns the debug level of debugID
     145              :                 inline int get_debug_level(const char *debugID) const
     146              :                 {
     147              :                         return GetDebugIDManager().get_debug_level(debugID);
     148              :                 }
     149              :                 /// returns the debug level of debugID
     150              :                 int get_debug_level_noninline(const char *debugID) const;
     151              :                 
     152              :                 
     153              :         /// sets the debug level of debugID
     154              :                 inline bool set_debug_level(DebugID &debugID, int level)
     155              :                 {
     156              :                         return GetDebugIDManager().set_debug_level(debugID, level);
     157              :                 }
     158              :                 
     159              :         /// returns the debug level of debugID
     160              :                 inline bool set_debug_level(const char* debugID, int level)
     161              :                 {
     162            0 :                         return GetDebugIDManager().set_debug_level(debugID, level);
     163              :                 }
     164              :                 
     165              :                 bool set_debug_level_noninline(const char* debugID, int level);
     166              :                 
     167              :         /// returns the debug level of debugID
     168            0 :                 inline std::string get_registered_debug_IDs()
     169              :                 {
     170            0 :                         return GetDebugIDManager().get_registered_debug_IDs();
     171              :                 }
     172              : 
     173              :         ///     sets the output-process in a parallel environment. Default is 0.
     174              :         /**     pass a procRank of -1 to enable output on all processes.*/
     175              :                 void set_output_process(int procRank);
     176              : 
     177              :         ///     returns the rank of the current output-process or -1 if all procs perform output.
     178              :                 inline int get_output_process();
     179              : 
     180              :         ///     returns true if the current process is an output process.
     181              :         /**     This is always true, if the application is executed in a serial environment.*/
     182              :                 bool is_output_process();
     183              : 
     184              :         ///     returns the process rank of the underlying process (same as pcl::ProcRank)
     185              :                 int get_process_rank();
     186              : 
     187              :                 void flush();
     188              : 
     189              :         protected:
     190              :         ///     updates and sets stream buffers based on current options.
     191              :         /**     Note that this method changes the buffer on which clog works.*/
     192              :                 void update_ostream();
     193              : 
     194              :         ///     opens the local logFile, if the process is the output-process
     195              :                 bool open_logfile();
     196              : 
     197              :         private:
     198              :         /// Constructor, resets all debug levels to -1
     199              :         /**     Constructor is private since only one instance of LogAssistant may exist.*/
     200              :                 LogAssistant();
     201              : 
     202              :         ///     Prevent copying through private copy constructor.
     203              :                 LogAssistant(const LogAssistant&);
     204              : 
     205              :         ///     Performs some initialization
     206              :                 void init();
     207              :         private:
     208              :         //      streams
     209              :                 std::streambuf* m_emptyBuf;
     210              :                 std::streambuf* m_logBuf;
     211              :                 std::streambuf* m_fileBuf;
     212              :                 std::streambuf* m_splitBuf;
     213              : 
     214              :                 EmptyStreamBuffer               m_emptyBufInst;
     215              :                 OStreamBufferSplitter   m_splitBufInst;
     216              : 
     217              :                 std::string                     m_logFileName;
     218              :                 std::ofstream                   m_fileStream;
     219              :                 std::stringstream               m_errStream;
     220              : 
     221              :                 bool m_terminalOutputEnabled;
     222              :                 bool m_fileOutputEnabled;
     223              : 
     224              :                 int m_outputProc;
     225              : 
     226              : };
     227              : 
     228              : // returns singleton instance of LogAssistant
     229              : inline LogAssistant& GetLogAssistant();
     230              : 
     231              : /// returns number 'size' in a more human readable format (using IEC binary prefixes)
     232              : inline std::string ConvertNumber (uint64_t size, unsigned int width,
     233              :                                   unsigned int numDisplayedDigits);
     234              : 
     235              : /// returns number 'size' in a more human readable format (using SI prefixes)
     236              : inline std::string ConvertNumberSI (uint64_t size, unsigned int width,
     237              :                                     unsigned int numDisplayedDigits);
     238              : 
     239              : // end group ugbase_common
     240              : /// \}
     241              : 
     242              : } // end namespace ug
     243              : 
     244              : 
     245              : ////////////////////////////////////////////////////////////////////////////////
     246              : ////////////////////////////////////////////////////////////////////////////////
     247              : // DEBUG LOG
     248              : ////////////////////////////////////////////////////////////////////////////////
     249              : ////////////////////////////////////////////////////////////////////////////////
     250              : 
     251              : 
     252              : /// \addtogroup ugbase_common
     253              : /// \{
     254              : 
     255              : // Usage:
     256              : /* The following macros can be used to control debug messages.
     257              :  * To use them the define 'UG_ENABLE_DEBUG_LOGS' must be set. Otherwise nothing will be done (no runtime overhead).
     258              :  *
     259              :  * UG_SET_DEBUG_LEVEL(__debugID__, level)       - sets the debug levels of DebugID __debugID__ to level 'level'
     260              :  * UG_RESET_DEBUG_LEVELS()                                      - sets the debug level of all Tags to -1
     261              :  * UG_SET_DEBUG_LEVELS(level)                           - sets the debug levels of all DebugIDs to level 'level'
     262              :  * UG_DLOG(__debugID__, level, msg)                     - prints the message "msg" to the debug log stream, if current level of DebugID __debugID__ is >= level
     263              :  *
     264              :  * __debugID__ has to be of type DebugID.
     265              :  * For a list of standard DebugIDs and how to define your own, see debug_id.h .
     266              :  *
     267              :  *      Example:
     268              :  *
     269              :         UG_RESET_DEBUG_LEVELS();
     270              :         UG_DLOG(MAIN, 0, "DLOG on level 0.\n");               // no message printed
     271              :         UG_SET_DEBUG_LEVEL(MAIN, 0);
     272              :         UG_DLOG(MAIN, 0, "DLOG on level 0.\n");               // message printed
     273              :         UG_DLOG(MAIN, 1, "DLOG on level 1.\n");               // no message printed
     274              :  */
     275              : #ifdef UG_ENABLE_DEBUG_LOGS
     276              :         #define UG_SET_DEBUG_LEVEL(__debugID__, level)          {ug::GetDebugIDManager().set_debug_level(__debugID__, level);}
     277              :         #define UG_RESET_DEBUG_LEVELS()                                         {ug::GetDebugIDManager().set_debug_levels(-1);}
     278              :         #define UG_SET_DEBUG_LEVELS(level)                                      {ug::GetDebugIDManager().set_debug_levels(level);}
     279              :         #define UG_DEBUG_BEGIN(__debugID__, level)                      { if(ug::GetDebugIDManager().get_debug_level(__debugID__) >= level) {
     280              :         #define UG_DEBUG_END(__debugID__, level)                        }; }
     281              :         #define IF_DEBUG(__debugID__, level)                            if(ug::GetDebugIDManager().get_debug_level(__debugID__) >= level)
     282              : 
     283              :         #define UG_DLOG(__debugID__, level, msg) \
     284              :                         {if(ug::GetDebugIDManager().get_debug_level(__debugID__) >= level)\
     285              :                         {ug::GetLogAssistant().debug_logger() << msg; ug::GetLogAssistant().debug_logger().flush();}}
     286              : 
     287              :         #define UG_DLOGN(__debugID__, level, msg)                       UG_DLOG(__debugID__, level, msg << "\n");
     288              : 
     289              :         #define UG_DLOG_ALL_PROCS(__debugID__, level, msg)      \
     290              :                         {if(ug::GetDebugIDManager().get_debug_level(__debugID__) >= level)\
     291              :                         {ug::LogAssistant& la = ug::GetLogAssistant(); int op = la.get_output_process();\
     292              :                         la.set_output_process(-1); la.debug_logger() << "[Proc " << la.get_process_rank() << "]: "\
     293              :                         << msg << std::flush; la.set_output_process(op);}}
     294              : #else
     295              :         #define UG_SET_DEBUG_LEVEL(__debugID__, level)          {}
     296              :         #define UG_RESET_DEBUG_LEVELS()                                         {}
     297              :         #define UG_SET_DEBUG_LEVELS(level)                                      {}
     298              :         #define UG_DLOG(__debugID__, level, msg)                        {}
     299              :         #define UG_DLOGN(__debugID__, level, msg)                       {}
     300              :         #define UG_DLOG_ALL_PROCS(__debugID__, level, msg)      {}
     301              :         #define UG_DEBUG_BEGIN(__debugID__, level)                      { if(1==0) {
     302              :         #define UG_DEBUG_END(__debugID__, level)                        }; }
     303              :         #define IF_DEBUG(__debugID__, level)                            if(1==0)
     304              : #endif
     305              : 
     306              : ////////////////////////////////////////////////////////////////////////////////
     307              : ////////////////////////////////////////////////////////////////////////////////
     308              : // WARNING LOG
     309              : ////////////////////////////////////////////////////////////////////////////////
     310              : ////////////////////////////////////////////////////////////////////////////////
     311              : 
     312              : // Warning and debug logs are disabled when compiling for release
     313              : // defines (currently here, should be compiling options)
     314              : #ifndef NDEBUG
     315              :         #define UG_ENABLE_WARNINGS
     316              : #else /* NDEBUG */
     317              :         #undef UG_ENABLE_WARNINGS
     318              : #endif /* NDEBUG*/
     319              : 
     320              : // Usage:
     321              : /* The following macro can be used to print warning messages.
     322              :  * To use it the define 'UG_ENABLE_WARNINGS' must be set. Otherwise nothing will
     323              :  * be done (no runtime overhead).
     324              :  *
     325              :  * UG_WARNING(msg)                      - prints a warning to the normal output stream
     326              :  */
     327              : #ifdef UG_ENABLE_WARNINGS
     328              :         #define UG_WARNING(msg) {ug::GetLogAssistant().logger() << "UG_WARNING in "\
     329              :                                                                 << __FILE__ << " at line " << __LINE__ << ": " \
     330              :                                                                 << msg << std::flush;}
     331              : #else
     332              :         #define UG_WARNING(msg) {}
     333              : #endif
     334              : 
     335              : 
     336              : // Usage:
     337              : /* The following macro can be used to print warning messages if condition is met.
     338              :  * To use it the define 'UG_ENABLE_WARNINGS' must be set. Otherwise nothing will
     339              :  * be done (no runtime overhead).
     340              :  *
     341              :  * UG_WARNING(cond, msg)                - prints a warning to the normal output stream
     342              :  */
     343              : #ifdef UG_ENABLE_WARNINGS
     344              :         #define UG_COND_WARNING(cond, msg) { if (cond) {ug::GetLogAssistant().logger() << "UG_WARNING in "\
     345              :                                                         << __FILE__ << " at line " << __LINE__ << ": " \
     346              :                                                         << msg << std::flush;} }
     347              : #else
     348              :         #define UG_COND_WARNING(cond, msg) {}
     349              : #endif
     350              : 
     351              : 
     352              : 
     353              : 
     354              : 
     355              : ////////////////////////////////////////////////////////////////////////////////
     356              : // LOG
     357              : /**
     358              :  * UG_LOG(msg)                  - prints a message to the normal output stream
     359              :  */
     360              : #ifdef UG_FOR_VRL
     361              :         #define VRL_LOG(msg) {std::stringstream __ss; __ss << "" << msg;\
     362              :                                                   ug::vrl::MessageBuffer::addMessage(__ss.str());}
     363              : #else
     364              :         #define VRL_LOG(msg)
     365              : #endif
     366              : 
     367              : #define UG_LOG(msg) {ug::GetLogAssistant().logger() << msg << std::flush; VRL_LOG(msg);}
     368              : #define UG_COND_LOG(cond, msg) { if (cond) { UG_LOG(msg); } }
     369              : #define UG_LOGN(msg) UG_LOG(msg << "\n")
     370              : #define UG_COND_LOGN(cond, msg) { if (cond) { UG_LOGN(msg); } }
     371              : #define UG_LOG_ALL_PROCS(msg) {ug::LogAssistant& la = ug::GetLogAssistant();\
     372              :                                                            int op = la.get_output_process(); la.set_output_process(-1);\
     373              :                                                            la.logger() << "[Proc " << std::setw(3) << la.get_process_rank() << "]: "\
     374              :                                                            << msg << std::flush; VRL_LOG(msg); la.set_output_process(op);}
     375              : 
     376              : ////////////////////////////////////////////////////////////////////////////////
     377              : // LOG
     378              : /**
     379              :  * UG_ERR_LOG(msg)  prints msg to LogAssistant::error_logger().
     380              :  *                                      Those messages are not immediately flushed. Instead they can
     381              :  *                                      be flushed to the standard logger using LogAssistant::flush_error_log
     382              :  */
     383              : #define UG_ERR_LOG(msg) {ug::GetLogAssistant().error_logger() << msg; VRL_LOG(msg);}
     384              : 
     385              : // include implementation
     386              : #include "log_impl.h"
     387              : 
     388              : // end group ugbase_common
     389              : /// \}
     390              : 
     391              : #endif /* __H__UG__COMMON__LOG__ */
        

Generated by: LCOV version 2.0-1