1 // -*- C++ -*- 2 /** 3 * @brief Log records all user information to a file or tty 4 * 5 * Copyright 2005-2021 Airbus-EDF-IMACS-ONERA-Phimeca 6 * 7 * This library is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU Lesser General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public License 18 * along with this library. If not, see <http://www.gnu.org/licenses/>. 19 * 20 */ 21 #ifndef OPENTURNS_LOG_HXX 22 #define OPENTURNS_LOG_HXX 23 24 #include <fstream> 25 #include <map> 26 #include "openturns/OTprivate.hxx" 27 #include "openturns/AtomicInt.hxx" 28 #include "openturns/TTY.hxx" 29 #include "openturns/MutexLock.hxx" 30 31 32 #define LOGDEBUG(st) do { if (OT::Log::HasDebug() ) OT::Log::Debug(st); } while(0) 33 #define LOGINFO(st) do { if (OT::Log::HasInfo() ) OT::Log::Info(st); } while(0) 34 #define LOGUSER(st) do { if (OT::Log::HasUser() ) OT::Log::User(st); } while(0) 35 #define LOGWARN(st) do { if (OT::Log::HasWarn() ) OT::Log::Warn(st); } while(0) 36 #define LOGERROR(st) do { if (OT::Log::HasError() ) OT::Log::Error(st); } while(0) 37 #define LOGTRACE(st) do { if (OT::Log::HasTrace() ) OT::Log::Trace(st); } while(0) 38 39 40 BEGIN_NAMESPACE_OPENTURNS 41 42 43 44 #ifndef SWIG 45 struct _Prefix 46 { 47 typedef String Value; 48 Value color_, nocolor_, prefix_; _Prefix_Prefix49 _Prefix() : color_(), nocolor_(), prefix_() {} _Prefix_Prefix50 _Prefix( const Value & color, const Value & nocolor, const Value & prefix) : color_(color), nocolor_(nocolor), prefix_(prefix) {} 51 }; 52 53 std::ostream & operator << ( std::ostream & os, const _Prefix & pfx ); 54 55 #endif 56 57 /** 58 * @class log 59 * @brief Records all user information to a file or tty 60 * @internal 61 */ 62 63 class OT_API Log 64 { 65 public: 66 67 typedef unsigned long Severity; 68 69 private: 70 #ifndef SWIG 71 /** GetInstance gives a locked access to the singleton */ 72 static MutexLockSingleton<Log> GetInstance(); 73 #endif 74 75 public: 76 /** Those flags should be ORed */ 77 static const Severity DBG; 78 static const Severity INFO; 79 static const Severity USER; 80 static const Severity WARN; 81 static const Severity ERROR; 82 static const Severity TRACE; 83 84 static const Severity DEFAULT; 85 static const Severity NONE; 86 static const Severity ALL; 87 88 #ifndef SWIG 89 /** Change the Log */ 90 static void Reset(); 91 #endif 92 93 /** Log messages according to the DBG level 94 * @param msg The message to be logged 95 */ 96 static void Debug(const String & msg); HasDebug()97 static inline Bool HasDebug() 98 { 99 return 0 != (Flags() & Log::DBG); 100 } 101 102 /** Log messages according to the INFO level 103 * @param msg The message to be logged 104 */ 105 static void Info(const String & msg); HasInfo()106 static inline Bool HasInfo() 107 { 108 return 0 != (Flags() & Log::INFO); 109 } 110 111 /** Log messages according to the USER level 112 * @param msg The message to be logged 113 */ 114 static void User(const String & msg); HasUser()115 static inline Bool HasUser() 116 { 117 return 0 != (Flags() & Log::USER); 118 } 119 120 /** Log messages according to the WARN level 121 * @param msg The message to be logged 122 */ 123 static void Warn(const String & msg); HasWarn()124 static inline Bool HasWarn() 125 { 126 return 0 != (Flags() & Log::WARN); 127 } 128 129 /** Log messages according to the ERROR level 130 * @param msg The message to be logged 131 */ 132 static void Error(const String & msg); HasError()133 static inline Bool HasError() 134 { 135 return 0 != (Flags() & Log::ERROR); 136 } 137 138 /** Log messages according to the TRACE level 139 * @param msg The message to be logged 140 */ 141 static void Trace(const String & msg); HasTrace()142 static inline Bool HasTrace() 143 { 144 return 0 != (Flags() & Log::TRACE); 145 } 146 147 /** Divert the output to a file 148 * @param file The filename where the log will be written 149 */ 150 static void SetFile(const FileName & file); 151 152 /** Set the level flags for the messages logged to the file 153 * @param flags An integer built from ORed level flags 154 */ 155 static void Show(Severity flags); 156 157 /** Get the current level flags 158 * @return An integer built from ORed level flags 159 */ 160 static Severity Flags(); 161 162 /** Flush pending messages 163 * @internal 164 */ 165 static void Flush(); 166 167 /** Does Log show repeated messages or not 168 * If repeat is false then Log shows every messages it receives 169 * even if they are identical to the previous ones. 170 * If repeat is true then Log only shows the first message 171 * and a message counting how much identical messages were 172 * received after that. 173 */ 174 static void Repeat( Bool repeat ); 175 176 /** Color accessors. */ 177 static void SetColor(const Log::Severity severity, 178 const TTY::Color color); 179 static void SetColor(const Log::Severity severity, 180 const String & color); 181 static String GetColor(const Log::Severity severity); 182 183 #ifndef SWIG 184 struct OT_API Entry 185 { 186 Severity sev_; 187 String msg_; EntryLog::Entry188 Entry(Severity sev, String msg) : sev_(sev), msg_(msg) {} EntryLog::Entry189 Entry() : sev_(0), msg_() {} operator ==Log::Entry190 Bool operator== (const Entry & other) const 191 { 192 return (this->sev_ == other.sev_) && (this->msg_ == other.msg_); 193 } 194 }; /* end struct Entry */ 195 #endif 196 ~Log(); 197 198 private: 199 Log(); 200 void push(const Entry & entry); 201 void printRepeatedMessage(const Entry & entry); 202 void flush(); 203 void repeat( Bool r ); 204 void setColor(const Log::Severity severity, 205 const String & color); 206 String getColor(const Log::Severity severity) const; 207 208 /** Set the name of the log file */ 209 void setFile(const FileName & file); 210 211 /** Human readable log */ 212 mutable std::map<Severity, _Prefix > logName_; 213 214 /** The environment variable name */ 215 const char * openturnsLogSeverityVariableName_; 216 217 /** Set Severity according to Openturns LogSeverity Variable */ 218 void initSeverityFromEnvironment(); 219 220 /** The file where to write messages */ 221 std::ostream * p_file_; 222 223 /** Remember the previous message */ 224 mutable Entry previousMessage_; 225 mutable UnsignedInteger count_; 226 mutable AtomicInt repeat_; 227 228 friend struct Log_init; /* friendship for static member initialization */ 229 }; /* end class Log */ 230 231 232 233 /** This struct initializes all static members of Log */ 234 struct OT_API Log_init 235 { 236 Log_init(); 237 ~Log_init(); 238 }; /* end struct Log_init */ 239 240 241 END_NAMESPACE_OPENTURNS 242 243 #endif /* OPENTURNS_LOG_HXX */ 244