Flow123d  release_2.1.0-84-g6a13a75
logger.hh
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file logger.hh
15  * @brief
16  */
17 
18 #ifndef LOGGER_HH_
19 #define LOGGER_HH_
20 
21 
22 #include <iostream>
23 #include <sstream>
24 #include <vector>
25 
26 #include "system/fmt/format.h"
27 
28 
29 
30 /**
31  * @brief Helper class, store mask specifying streams
32  *
33  * Defines masks of all used streams as static methods and allows combining and comparing masks using
34  * the overloaded operators.
35  */
36 class StreamMask {
37 public:
38  /// Empty constructor
40  : mask_(0) {}
41 
42  /// Constructor set \p mask_ value
43  StreamMask(int mask)
44  : mask_(mask) {}
45 
46  /// Predefined mask of std::cout output
47  static StreamMask cout;
48 
49  /// Predefined mask of std::cerr output
50  static StreamMask cerr;
51 
52  /// Predefined mask of log file output
53  static StreamMask log;
54 
55  // Overload & operator
56  StreamMask operator &(const StreamMask &other);
57 
58  // Overload | operator
59  StreamMask operator |(const StreamMask &other);
60 
61  // Overload () operator
62  int operator()(void);
63 
64 private:
65  int mask_;
66 };
67 
68 
69 /**
70  * @brief Class for storing logger messages.
71  *
72  * Allow define different levels of log messages and distinguish output streams
73  * for individual leves. These output streams are -
74  * - standard console output (std::cout)
75  * - standard error output (std::cerr)
76  * - file output (see \p LoggerOptions class)
77  *
78  * Logger distinguishes four type of levels -
79  * - warning: printed to standard error and file output
80  * - message: printed to standard console and file output
81  * - log: printed to file output
82  * - debug: printed to file output (level is used only in debug mode)
83  *
84  * File output is optional. See \p LoggerOptions for setting this output stream.
85  *
86  * <b>Example of Logger usage:</b>
87  *
88  * For individual levels are defined macros -
89  * - MessageOut()
90  * - WarningOut()
91  * - LogOut()
92  * - DebugOut()
93  * that ensure display of actual code point (source file, line and function).
94  *
95  * Logger message is created by using an operator << and allow to add each type
96  * that has override this operator. Message is terminated with manipulator
97  * std::endl. Implicitly logger message is printed only in processor with rank
98  * zero. If necessary printed message for all process, it provides a method
99  * every_proc().
100  *
101  * Examples of logger messages formating:
102  *
103  @code
104  MessageOut() << "End of simulation at time: " << secondary_eq->solved_time() << "\n";
105  WarningOut() << "Unprocessed key '" << key_name << "' in Record '" << rec->type_name() << "'." << "\n";
106  LogOut() << "Write output to output stream: " << this->_base_filename << " for time: " << time << "\n";
107  DebugOut() << "Calling 'initialize' of empty equation '" << typeid(*this).name() << "'." << "\n";
108  @endcode
109  *
110  * Logger message can be created by more than one line ("\n" can be used multiple
111  * times):
112  *
113  @code
114  MessageOut() << "Start time: " << this->start_time() << "\n" << "End time: " << this->end_time() << "\n";
115  @endcode
116  *
117  * Or Logger allow using fmtlib functionality for simpler formatting of message:
118  *
119  @code
120  MessageOut() << fmt::format("Start time: {}\nEnd time: {}\n", this->start_time(), this->end_time());
121  MessageOut().fmt("Start time: {}\nEnd time: {}\n", this->start_time(), this->end_time());
122  @endcode
123  *
124  * In some cases message can be printed for all processes:
125  *
126  @code
127  MessageOut().every_proc() << "Size distributed at process: " << distr->lsize() << "\n";
128  @endcode
129  *
130  * Implementation of Logger does not support manipulator std::endl. Please, use "\n" instead.
131  */
132 class Logger : public std::ostream {
133 public:
134  /// Enum of types of Logger messages.
135  enum MsgType {
136  warning = 0,
137  message = 1,
138  log = 2,
139  debug = 3,
140  error = 4
141  };
142 
143  /// Return string value of given MsgType in full or shorter format (e.g. "WARNING" of "Wrn")
144  static const std::string msg_type_string(MsgType msg_type, bool full_format = true);
145 
146  /// Constructor.
147  Logger(MsgType type);
148 
149  /// Stores values for printing out line number, function, etc
150  Logger& set_context(const char* file_name, const char* function, const int line);
151 
152  /// Set flag every_process_ to true
153  Logger& every_proc();
154 
155  /**
156  * @brief Allow use functionality of fmtlib for formating message.
157  *
158  * See examples in description of Logger class.
159  */
160  template<class... T>
161  Logger& fmt(T&&... t)
162  {
163  return *this << fmt::format(std::forward<T>(t)...);
164  }
165 
166  /// Destructor.
167  ~Logger();
168 
169 
170 private:
171  /// Set @p streams_mask_ according to the type of message.
172  void set_mask();
173 
174  /// Print formated message to given screen stream if mask corresponds with @p streams_mask_.
175  void print_to_screen(std::ostream& stream, std::stringstream& scr_stream, StreamMask mask);
176 
177  /// Print formated message to given file stream if mask corresponds with @p streams_mask_.
178  void print_to_file(std::ofstream& stream, std::stringstream& file_stream, StreamMask mask);
179 
180  /// Print header to screen stream, helper method called from \p print_to_screen.
181  bool print_screen_header(std::ostream& stream, std::stringstream& scr_stream);
182 
183  /// Print header to file stream, helper method called from \p print_to_file.
184  void print_file_header(std::ofstream& stream, std::stringstream& file_stream);
185 
186  std::stringstream cout_stream_; ///< Store messages printed to cout output stream
187  std::stringstream cerr_stream_; ///< Store messages printed to cerr output stream
188  std::stringstream file_stream_; ///< Store messages printed to file
189 
190  MsgType type_; ///< Type of message.
191  bool every_process_; ///< Flag marked if log message is printing for all processes or only for zero process.
192  std::string file_name_; ///< Actual file.
193  std::string function_; ///< Actual function.
194  int line_; ///< Actual line.
195  std::string date_time_; ///< Actual date and time.
196  int mpi_rank_; ///< Actual process (if MPI is supported)
197  StreamMask streams_mask_; ///< Mask of logger, specifies streams in actual time into which to be written
198  StreamMask full_streams_mask_; ///< Mask of logger, specifies all streams into which to be written in logger message
199 
200  template <class T>
201  friend Logger &operator<<(Logger & log, const T & x);
202  friend Logger &operator<<(Logger & log, std::ostream & (*pf) (std::ostream &) );
203  friend Logger &operator<<(Logger & log, StreamMask mask);
204 };
205 
206 
207 Logger &operator<<(Logger & log, StreamMask mask);
208 
209 
210 Logger &operator<<(Logger & log, std::ostream & (*pf) (std::ostream &) );
211 
212 
213 template <class T>
214 Logger &operator<<(Logger & log, const T & x)
215 {
216  if ( (log.streams_mask_ & StreamMask::cout)() ) log.cout_stream_ << x;
217  if ( (log.streams_mask_ & StreamMask::cerr)() ) log.cerr_stream_ << x;
218  if ( (log.streams_mask_ & StreamMask::log )() ) log.file_stream_ << x;
219  return log;
220 }
221 
222 
223 
224 
225 
226 
227 /// Internal macro defining universal record of log
228 #define _LOG(type) \
229  Logger( type ).set_context( __FILE__, __func__, __LINE__)
230 /// Macro defining 'message' record of log
231 #define MessageOut() \
232  _LOG( Logger::MsgType::message )
233 /// Macro defining 'warning' record of log
234 #define WarningOut() \
235  _LOG( Logger::MsgType::warning )
236 /// Macro defining 'log' record of log
237 #define LogOut() \
238  _LOG( Logger::MsgType::log )
239 /// Macro defining 'debug' record of log
240 #define DebugOut() \
241  _LOG( Logger::MsgType::debug )
242 
243 /**
244  * Print variable name and value.
245  * Usage:
246  * DebugOut() << print_var(x) << print_var(y)
247  */
248 #define print_var(var) \
249  std::string(#var) << "=" << (var) << ", "
250 
251 
252 
253 
254 #endif /* LOGGER_HH_ */
Class for storing logger messages.
Definition: logger.hh:132
static StreamMask cout
Predefined mask of std::cout output.
Definition: logger.hh:47
int operator()(void)
Definition: logger.cc:54
std::stringstream cout_stream_
Store messages printed to cout output stream.
Definition: logger.hh:186
Logger & operator<<(Logger &log, StreamMask mask)
Definition: logger.cc:269
StreamMask streams_mask_
Mask of logger, specifies streams in actual time into which to be written.
Definition: logger.hh:197
StreamMask()
Empty constructor.
Definition: logger.hh:39
std::stringstream cerr_stream_
Store messages printed to cerr output stream.
Definition: logger.hh:187
std::string function_
Actual function.
Definition: logger.hh:193
StreamMask operator|(const StreamMask &other)
Definition: logger.cc:49
Logger & fmt(T &&...t)
Allow use functionality of fmtlib for formating message.
Definition: logger.hh:161
StreamMask(int mask)
Constructor set mask_ value.
Definition: logger.hh:43
static StreamMask cerr
Predefined mask of std::cerr output.
Definition: logger.hh:50
static StreamMask log
Predefined mask of log file output.
Definition: logger.hh:53
StreamMask operator&(const StreamMask &other)
Definition: logger.cc:44
Helper class, store mask specifying streams.
Definition: logger.hh:36
std::string date_time_
Actual date and time.
Definition: logger.hh:195
int mask_
Definition: logger.hh:65
bool every_process_
Flag marked if log message is printing for all processes or only for zero process.
Definition: logger.hh:191
int line_
Actual line.
Definition: logger.hh:194
std::stringstream file_stream_
Store messages printed to file.
Definition: logger.hh:188
StreamMask full_streams_mask_
Mask of logger, specifies all streams into which to be written in logger message. ...
Definition: logger.hh:198
std::string file_name_
Actual file.
Definition: logger.hh:192
int mpi_rank_
Actual process (if MPI is supported)
Definition: logger.hh:196
MsgType type_
Type of message.
Definition: logger.hh:190
MsgType
Enum of types of Logger messages.
Definition: logger.hh:135