ug4
log.h
Go to the documentation of this file.
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>
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 
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
97 {
98  public:
100  static LogAssistant& instance();
101 
103  ~LogAssistant();
104 
106 
110  bool enable_file_output(bool bEnable, const char* filename = "uglog.log");
111 
113  bool rename_log_file(const char * newname);
114 
116 
117  bool enable_terminal_output(bool bEnable);
118 
120  inline std::ostream& debug_logger();
121 
123  inline std::ostream& logger();
124 
126 
128  inline std::ostream& error_logger();
129 
131  void flush_error_log();
132 
134  bool set_debug_levels(int lev)
135  {
136  return GetDebugIDManager().set_debug_levels(lev);
137  }
138 
140  inline int get_debug_level(DebugID &debugID) const
141  {
142  return GetDebugIDManager().get_debug_level(debugID);
143  }
145  inline int get_debug_level(const char *debugID) const
146  {
147  return GetDebugIDManager().get_debug_level(debugID);
148  }
150  int get_debug_level_noninline(const char *debugID) const;
151 
152 
154  inline bool set_debug_level(DebugID &debugID, int level)
155  {
156  return GetDebugIDManager().set_debug_level(debugID, level);
157  }
158 
160  inline bool set_debug_level(const char* debugID, int level)
161  {
162  return GetDebugIDManager().set_debug_level(debugID, level);
163  }
164 
165  bool set_debug_level_noninline(const char* debugID, int level);
166 
168  inline std::string get_registered_debug_IDs()
169  {
171  }
172 
174 
175  void set_output_process(int procRank);
176 
178  inline int get_output_process();
179 
181 
182  bool is_output_process();
183 
185  int get_process_rank();
186 
187  void flush();
188 
189  protected:
191 
192  void update_ostream();
193 
195  bool open_logfile();
196 
197  private:
199 
200  LogAssistant();
201 
203  LogAssistant(const LogAssistant&);
204 
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 
216 
217  std::string m_logFileName;
218  std::ofstream m_fileStream;
219  std::stringstream m_errStream;
220 
223 
225 
226 };
227 
228 // returns singleton instance of LogAssistant
229 inline LogAssistant& GetLogAssistant();
230 
232 inline std::string ConvertNumber (uint64_t size, unsigned int width,
233  unsigned int numDisplayedDigits);
234 
236 inline std::string ConvertNumberSI (uint64_t size, unsigned int width,
237  unsigned int numDisplayedDigits);
238 
239 // end group ugbase_common
241 
242 } // end namespace ug
243 
244 
247 // DEBUG LOG
250 
251 
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 
308 // WARNING LOG
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 
356 // LOG
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 
377 // LOG
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
390 
391 #endif /* __H__UG__COMMON__LOG__ */
Definition: debug_id.h:94
Used by EmptyStream, to send tokens into nirvana!
Definition: empty_stream.h:50
Definition: log.h:97
std::streambuf * m_emptyBuf
Definition: log.h:209
OStreamBufferSplitter m_splitBufInst
Definition: log.h:215
bool m_terminalOutputEnabled
Definition: log.h:221
std::stringstream m_errStream
Definition: log.h:219
bool set_debug_level(DebugID &debugID, int level)
sets the debug level of debugID
Definition: log.h:154
bool m_fileOutputEnabled
Definition: log.h:222
EmptyStreamBuffer m_emptyBufInst
Definition: log.h:214
std::streambuf * m_logBuf
Definition: log.h:210
int get_debug_level(const char *debugID) const
returns the debug level of debugID
Definition: log.h:145
std::streambuf * m_splitBuf
Definition: log.h:212
bool set_debug_level(const char *debugID, int level)
returns the debug level of debugID
Definition: log.h:160
std::string m_logFileName
Definition: log.h:217
bool set_debug_levels(int lev)
sets the debug level of all tags to 'lev'
Definition: log.h:134
int m_outputProc
Definition: log.h:224
std::ofstream m_fileStream
Definition: log.h:218
int get_debug_level(DebugID &debugID) const
returns the debug level of debugID
Definition: log.h:140
std::string get_registered_debug_IDs()
returns the debug level of debugID
Definition: log.h:168
std::streambuf * m_fileBuf
Definition: log.h:211
forwards data written to this stream-buffer to other stream buffers.
Definition: ostream_buffer_splitter.h:51
virtual void init()
const uint64 UNIT_PETA_SI
Definition: log.h:74
const uint64 UNIT_KILO_SI
Definition: log.h:70
LogAssistant & GetLogAssistant()
Definition: log_impl.h:69
bool set_debug_level(uint32 debugIDhash, int level)
sets the debug level of debugIDhash if registered to 'level'
Definition: debug_id.h:151
const uint64 UNIT_PETA
Definition: log.h:66
const uint64 UNIT_GIGA_SI
Definition: log.h:72
std::string ConvertNumberSI(uint64_t size, unsigned int width, unsigned int numDisplayedDigits)
returns number 'size' in a more human readable format (using SI prefixes)
Definition: log_impl.h:132
#define UG_API
Definition: ug_config.h:65
int get_debug_level(uint32 debugIDhash) const
returns the debug level of debugIDhash, -1 if not found
Definition: debug_id.h:143
const uint64 UNIT_TERA
Definition: log.h:65
bool set_debug_levels(int lev)
sets the debug level of all registered debugIDs to 'lev'
Definition: debug_id.cpp:64
const uint64 UNIT_GIGA
Definition: log.h:64
std::string get_registered_debug_IDs() const
returns a string describing all registered debugIDs.
Definition: debug_id.h:208
const uint64 UNIT_EXA_SI
Definition: log.h:75
const uint64 UNIT_MEGA
Definition: log.h:63
const uint64 UNIT_KILO
Definition: log.h:62
const uint64 UNIT_EXA
Definition: log.h:67
DebugIDManager & GetDebugIDManager()
Definition: debug_id.h:231
const uint64 UNIT_TERA_SI
Definition: log.h:73
const uint64 UNIT_MEGA_SI
Definition: log.h:71
std::string ConvertNumber(uint64_t size, unsigned int width, unsigned int numDisplayedDigits)
returns number 'size' in a more human readable format (using IEC binary prefixes)
Definition: log_impl.h:81
ugtypes::uint64_t uint64
Definition: types.h:117
the ug namespace