Loading [MathJax]/extensions/TeX/AMSsymbols.js
Radium Engine  1.5.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
Log.hpp
1 #pragma once
2 
3 #include <Core/RaCore.hpp>
4 #include <ctime>
5 #include <sstream>
6 #include <stdio.h>
7 #include <string>
8 
9 namespace Ra {
10 namespace Core {
11 namespace Utils {
12 
13 inline std::string NowTime();
14 
15 enum TLogLevel {
16  logERROR,
17  logWARNING,
18  logINFO,
19  logDEBUG,
20  logDEBUG1,
21  logDEBUG2,
22  logDEBUG3,
23  logDEBUG4
24 };
25 
26 template <typename T>
27 class Log
28 {
29  public:
30  Log();
31  virtual ~Log();
32  std::ostringstream& Get( TLogLevel level = logINFO );
33 
34  public:
35  static TLogLevel& ReportingLevel();
36  static std::string ToString( TLogLevel level );
37  static TLogLevel FromString( const std::string& level );
38 
39  protected:
40  std::ostringstream os;
41 
42  private:
43  Log( const Log& );
44  Log& operator=( const Log& );
45 };
46 
47 template <typename T>
48 Log<T>::Log() {}
49 
50 template <typename T>
51 std::ostringstream& Log<T>::Get( TLogLevel level ) {
52  os << "- " << NowTime();
53  os << " " << ToString( level ) << ": ";
54  os << std::string( level > logDEBUG ? level - logDEBUG : 0, '\t' );
55  return os;
56 }
57 
58 template <typename T>
59 Log<T>::~Log() {
60  os << std::endl;
61  T::Output( os.str() );
62 }
63 
64 template <typename T>
65 TLogLevel& Log<T>::ReportingLevel() {
66  static TLogLevel reportingLevel = logDEBUG4;
67  return reportingLevel;
68 }
69 
70 template <typename T>
71 std::string Log<T>::ToString( TLogLevel level ) {
72  static const char* const buffer[] = {
73  "ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4" };
74  return buffer[level];
75 }
76 
77 template <typename T>
78 TLogLevel Log<T>::FromString( const std::string& level ) {
79  if ( level == "DEBUG4" ) { return logDEBUG4; }
80  if ( level == "DEBUG3" ) { return logDEBUG3; }
81  if ( level == "DEBUG2" ) { return logDEBUG2; }
82  if ( level == "DEBUG1" ) { return logDEBUG1; }
83  if ( level == "DEBUG" ) { return logDEBUG; }
84  if ( level == "INFO" ) { return logINFO; }
85  if ( level == "WARNING" ) { return logWARNING; }
86  if ( level == "ERROR" ) { return logERROR; }
87  Log<T>().Get( logWARNING ) << "Unknown logging level '" << level
88  << "'. Using INFO level as default.";
89  return logINFO;
90 }
91 
92 class Output2FILE
93 {
94  public:
95  static FILE*& Stream();
96  static void Output( const std::string& msg );
97 };
98 
99 inline FILE*& Output2FILE::Stream() {
100  static FILE* pStream = stderr;
101  return pStream;
102 }
103 
104 inline void Output2FILE::Output( const std::string& msg ) {
105  FILE* pStream = Stream();
106  if ( !pStream ) { return; }
107  fprintf( pStream, "%s", msg.c_str() );
108  fflush( pStream );
109 }
110 
111 class FILELog : public Log<Output2FILE>
112 {};
113 // using FILELog = Log<Output2FILE>;
114 
115 inline std::string NowTime() {
116  char buffer[100];
117  std::time_t t = std::time( nullptr );
118  ON_ASSERT( int ok = ) std::strftime( buffer, 100, "%X", std::localtime( &t ) );
119  CORE_ASSERT( ok, "Increase buffer size." );
120  std::string result( buffer );
121  // This doesn't work with minGW. Maybe indicates a serious issue ?
122  // Ra::Core::Utils::stringPrintf( result, "%s", buffer );
123  return result;
124 }
125 
126 } // namespace Utils
127 } // namespace Core
128 } // namespace Ra
129 
130 #ifndef FILELOG_MAX_LEVEL
131 # ifdef CORE_DEBUG
132 # define FILELOG_MAX_LEVEL Ra::Core::Utils::logDEBUG4
133 # else
134 # define FILELOG_MAX_LEVEL Ra::Core::Utils::logINFO
135 # endif
136 #endif
137 
138 #define FILE_LOG( level ) \
139  if ( level > FILELOG_MAX_LEVEL ) \
140  ; \
141  else if ( level > Ra::Core::Utils::FILELog::ReportingLevel() || \
142  !Ra::Core::Utils::Output2FILE::Stream() ) \
143  ; \
144  else \
145  Ra::Core::Utils::FILELog().Get( level )
146 
147 #ifdef RA_NO_LOG
148 # define LOG( level ) FILE_LOG( Ra::Core::Utils::TLogLevel( FILELOG_MAX_LEVEL + 1 ) )
149 #else
150 # define LOG( level ) FILE_LOG( level )
151 #endif
Definition: Cage.cpp:3