Fast DDS  Version 3.6.1.0
Fast DDS
Log.hpp
1 // Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 #ifndef FASTDDS_DDS_LOG__LOG_HPP
16 #define FASTDDS_DDS_LOG__LOG_HPP
17 
18 #include <regex>
19 #include <sstream>
20 
21 #include <fastdds/rtps/attributes/ThreadSettings.hpp>
22 #include <fastdds/fastdds_dll.hpp>
23 
37 // Logging API:
38 
39 // EPROSIMA LOG MACROS
41 #define EPROSIMA_LOG_INFO(cat, msg) EPROSIMA_LOG_INFO_IMPL_(cat, msg)
43 #define EPROSIMA_LOG_WARNING(cat, msg) EPROSIMA_LOG_WARNING_IMPL_(cat, msg)
45 #define EPROSIMA_LOG_ERROR(cat, msg) EPROSIMA_LOG_ERROR_IMPL_(cat, msg)
46 
47 #if ENABLE_OLD_LOG_MACROS_
48 // Compile old eProsima macros for compatibility shake.
49 // However, these macros will be deprecated in future releases, so please do not use them.
50 
52 #define logInfo(cat, msg) logInfo_(cat, msg)
54 #define logWarning(cat, msg) logWarning_(cat, msg)
56 #define logError(cat, msg) logError_(cat, msg)
57 
59 #define logInfo_(cat, msg) EPROSIMA_LOG_INFO_IMPL_(cat, msg);
60 #define logWarning_(cat, msg) EPROSIMA_LOG_WARNING_IMPL_(cat, msg);
61 #define logError_(cat, msg) EPROSIMA_LOG_ERROR_IMPL_(cat, msg);
62 
63 #endif // ENABLE_OLD_LOG_MACROS_
64 
65 namespace eprosima {
66 namespace fastdds {
67 namespace dds {
68 
69 class LogConsumer;
70 
79 class Log
80 {
81 public:
82 
89  enum Kind
90  {
94  };
95 
101  FASTDDS_EXPORTED_API static void RegisterConsumer(
102  std::unique_ptr<LogConsumer>&& consumer);
103 
105  FASTDDS_EXPORTED_API static void ClearConsumers();
106 
108  FASTDDS_EXPORTED_API static void ReportFilenames(
109  bool);
110 
112  FASTDDS_EXPORTED_API static void ReportFunctions(
113  bool);
114 
116  FASTDDS_EXPORTED_API static void SetVerbosity(
117  Log::Kind);
118 
120  FASTDDS_EXPORTED_API static Log::Kind GetVerbosity();
121 
123  FASTDDS_EXPORTED_API static void SetCategoryFilter(
124  const std::regex&);
125 
127  FASTDDS_EXPORTED_API static void UnsetCategoryFilter();
128 
130  FASTDDS_EXPORTED_API static bool HasCategoryFilter();
131 
133  FASTDDS_EXPORTED_API static std::regex GetCategoryFilter();
134 
136  FASTDDS_EXPORTED_API static void SetFilenameFilter(
137  const std::regex&);
138 
140  FASTDDS_EXPORTED_API static std::regex GetFilenameFilter();
141 
143  FASTDDS_EXPORTED_API static void SetErrorStringFilter(
144  const std::regex&);
145 
147  FASTDDS_EXPORTED_API static void SetThreadConfig(
148  const rtps::ThreadSettings&);
149 
151  FASTDDS_EXPORTED_API static std::regex GetErrorStringFilter();
152 
154  FASTDDS_EXPORTED_API static void Reset();
155 
157  FASTDDS_EXPORTED_API static void Flush();
158 
160  FASTDDS_EXPORTED_API static void KillThread();
161 
162  // Note: In VS2013, if you're linking this class statically, you will have to call KillThread before leaving
163  // main, due to an unsolved MSVC bug.
164 
165  struct Context
166  {
167  const char* filename;
168  int line;
169  const char* function;
170  const char* category;
171  };
172 
173  struct Entry
174  {
175  std::string message;
178  std::string timestamp;
179  };
180 
189  FASTDDS_EXPORTED_API static void QueueLog(
190  const std::string& message,
191  const Log::Context&,
192  Log::Kind);
193 };
194 
196 inline std::ostream& operator <<(
197  std::ostream& output,
198  const Log::Kind& kind)
199 {
200  switch (kind){
201  case Log::Kind::Info:
202  output << "Info";
203  break;
204 
205  case Log::Kind::Warning:
206  output << "Warning";
207  break;
208 
209  case Log::Kind::Error:
210  output << "Error";
211  break;
212 
213  default:
214  output << "Invalid Verbosity Kind.";
215  break;
216  }
217 
218  return output;
219 }
220 
225 {
226 public:
227 
228  virtual ~LogConsumer() = default;
229 
230  virtual void Consume(
231  const Log::Entry&) = 0;
232 
233 protected:
234 
235  FASTDDS_EXPORTED_API void print_timestamp(
236  std::ostream& stream,
237  const Log::Entry&,
238  bool color) const;
239 
240  FASTDDS_EXPORTED_API void print_header(
241  std::ostream& stream,
242  const Log::Entry&,
243  bool color) const;
244 
245  FASTDDS_EXPORTED_API void print_context(
246  std::ostream& stream,
247  const Log::Entry&,
248  bool color) const;
249 
250  FASTDDS_EXPORTED_API void print_message(
251  std::ostream& stream,
252  const Log::Entry&,
253  bool color) const;
254 
255  FASTDDS_EXPORTED_API void print_new_line(
256  std::ostream& stream,
257  bool color) const;
258 };
259 
260 #if defined(WIN32)
261 #define __func__ __FUNCTION__
262 #endif // if defined(WIN32)
263 
264 /********************
265 * Implementation of the log macros depending on the defined macros:
266 * HAVE_LOG_NO_<level> disable completly a verbosity level
267 * _INTERNALDEBUG || __INTERNALDEBUG force to compile the log macro call even when it would not be added to queue
268 * EPROSIMA_LOG_INFO_IMPL_ would only be compiled if HAVE_LOG_NO_INFO is OFF and
269 * - FASTDDS_ENFORCE_LOG_INFO or (DEBUG and INTERNALDEBUG) are defined
270 *
271 * There are 3 implementations for each level:
272 * 1. Compile and add log to queue
273 * 2. Compile but do not add it to queue (with INTERNALDEBUG)
274 * 3. Do not compile
275 *
276 * Every macro (with implementation) occurs inside a code block so after call every internal variable is destroyed.
277 * Every macro declared has a do while(0).
278 * This will not generate an assembler instruction and forces the user of the macro to use ";" after calling it.
279 * https://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html
280 * NOTE: some compilation cases do not use do while loop and so they do not force ";".
281 * It is a risk that a user takes in exchange of a perfect way of non generating code in such cases.
282 ********************/
283 
284 /*********
285 * ERROR *
286 *********/
287 // Name of variables inside macros must be unique, or it could produce an error with external variables
288 #if !HAVE_LOG_NO_ERROR
289 
290 #define EPROSIMA_LOG_ERROR_IMPL_(cat, msg) \
291  do { \
292  std::stringstream fastdds_log_ss_tmp__; \
293  fastdds_log_ss_tmp__ << msg; \
294  eprosima::fastdds::dds::Log::QueueLog( \
295  fastdds_log_ss_tmp__.str(), eprosima::fastdds::dds::Log::Context{__FILE__, __LINE__, __func__, #cat}, \
296  eprosima::fastdds::dds::Log::Kind::Error); \
297  } while (0)
298 
299 #elif (__INTERNALDEBUG || _INTERNALDEBUG)
300 
301 #define EPROSIMA_LOG_ERROR_IMPL_(cat, msg) \
302  do { \
303  auto fastdds_log_lambda_tmp__ = [&]() \
304  { \
305  std::stringstream fastdds_log_ss_tmp__; \
306  fastdds_log_ss_tmp__ << msg; \
307  }; \
308  (void)fastdds_log_lambda_tmp__; \
309  } while (0)
310 #else
311 
312 #define EPROSIMA_LOG_ERROR_IMPL_(cat, msg)
313 
314 #endif // ifndef LOG_NO_ERROR
315 
316 /***********
317 * WARNING *
318 ***********/
319 #if !HAVE_LOG_NO_WARNING
320 
321 #define EPROSIMA_LOG_WARNING_IMPL_(cat, msg) \
322  do { \
323  if (eprosima::fastdds::dds::Log::GetVerbosity() >= eprosima::fastdds::dds::Log::Kind::Warning) \
324  { \
325  std::stringstream fastdds_log_ss_tmp__; \
326  fastdds_log_ss_tmp__ << msg; \
327  eprosima::fastdds::dds::Log::QueueLog( \
328  fastdds_log_ss_tmp__.str(), eprosima::fastdds::dds::Log::Context{__FILE__, __LINE__, __func__, #cat}, \
329  eprosima::fastdds::dds::Log::Kind::Warning); \
330  } \
331  } while (0)
332 
333 #elif (__INTERNALDEBUG || _INTERNALDEBUG)
334 
335 #define EPROSIMA_LOG_WARNING_IMPL_(cat, msg) \
336  do { \
337  auto fastdds_log_lambda_tmp__ = [&]() \
338  { \
339  std::stringstream fastdds_log_ss_tmp__; \
340  fastdds_log_ss_tmp__ << msg; \
341  }; \
342  (void)fastdds_log_lambda_tmp__; \
343  } while (0)
344 
345 #else
346 
347 #define EPROSIMA_LOG_WARNING_IMPL_(cat, msg)
348 
349 #endif // ifndef LOG_NO_WARNING
350 
351 /********
352 * INFO *
353 ********/
354 // Allow multiconfig platforms like windows to disable info queueing on Release and other non-debug configs
355 #if !HAVE_LOG_NO_INFO && \
356  (defined(FASTDDS_ENFORCE_LOG_INFO) || \
357  ((defined(__INTERNALDEBUG) || defined(_INTERNALDEBUG)) && (defined(_DEBUG) || defined(__DEBUG) || \
358  !defined(NDEBUG))))
359 
360 #define EPROSIMA_LOG_INFO_IMPL_(cat, msg) \
361  do { \
362  if (eprosima::fastdds::dds::Log::GetVerbosity() >= eprosima::fastdds::dds::Log::Kind::Info) \
363  { \
364  std::stringstream fastdds_log_ss_tmp__; \
365  fastdds_log_ss_tmp__ << msg; \
366  eprosima::fastdds::dds::Log::QueueLog( \
367  fastdds_log_ss_tmp__.str(), eprosima::fastdds::dds::Log::Context{__FILE__, __LINE__, __func__, #cat}, \
368  eprosima::fastdds::dds::Log::Kind::Info); \
369  } \
370  } while (0)
371 
372 #elif (__INTERNALDEBUG || _INTERNALDEBUG)
373 
374 #define EPROSIMA_LOG_INFO_IMPL_(cat, msg) \
375  do { \
376  auto fastdds_log_lambda_tmp__ = [&]() \
377  { \
378  std::stringstream fastdds_log_ss_tmp__; \
379  fastdds_log_ss_tmp__ << msg; \
380  }; \
381  (void)fastdds_log_lambda_tmp__; \
382  } while (0)
383 
384 #else
385 
386 #define EPROSIMA_LOG_INFO_IMPL_(cat, msg)
387 
388 #endif // ifndef LOG_NO_INFO
389 
390 
391 } // namespace dds
392 } // namespace fastdds
393 } // namespace eprosima
394 
395 #endif // FASTDDS_DDS_LOG__LOG_HPP
Consumes a log entry to output it somewhere.
Definition: Log.hpp:225
FASTDDS_EXPORTED_API void print_context(std::ostream &stream, const Log::Entry &, bool color) const
FASTDDS_EXPORTED_API void print_timestamp(std::ostream &stream, const Log::Entry &, bool color) const
FASTDDS_EXPORTED_API void print_message(std::ostream &stream, const Log::Entry &, bool color) const
FASTDDS_EXPORTED_API void print_header(std::ostream &stream, const Log::Entry &, bool color) const
virtual void Consume(const Log::Entry &)=0
FASTDDS_EXPORTED_API void print_new_line(std::ostream &stream, bool color) const
Logging utilities.
Definition: Log.hpp:80
static FASTDDS_EXPORTED_API void SetCategoryFilter(const std::regex &)
Sets a filter that will pattern-match against log categories, dropping any unmatched categories.
static FASTDDS_EXPORTED_API void Reset()
Returns the logging engine to configuration defaults.
static FASTDDS_EXPORTED_API std::regex GetCategoryFilter()
Returns a copy of the current category filter or an empty object otherwise.
static FASTDDS_EXPORTED_API void RegisterConsumer(std::unique_ptr< LogConsumer > &&consumer)
Registers an user defined consumer to route log output.
static FASTDDS_EXPORTED_API void ClearConsumers()
Removes all registered consumers, including the default stdout.
static FASTDDS_EXPORTED_API void SetErrorStringFilter(const std::regex &)
Sets a filter that will pattern-match against the provided error string, dropping any unmatched categ...
static FASTDDS_EXPORTED_API void SetVerbosity(Log::Kind)
Sets the verbosity level, allowing for messages equal or under that priority to be logged.
static FASTDDS_EXPORTED_API Log::Kind GetVerbosity()
Returns the current verbosity level.
static FASTDDS_EXPORTED_API void SetThreadConfig(const rtps::ThreadSettings &)
Sets thread configuration for the logging thread.
static FASTDDS_EXPORTED_API void SetFilenameFilter(const std::regex &)
Sets a filter that will pattern-match against filenames, dropping any unmatched categories.
static FASTDDS_EXPORTED_API void QueueLog(const std::string &message, const Log::Context &, Log::Kind)
Not recommended to call this method directly! Use the following macros:
static FASTDDS_EXPORTED_API void ReportFunctions(bool)
Enables the reporting of function names in log entries. Enabled by default when supported.
static FASTDDS_EXPORTED_API void KillThread()
Stops the logging thread. It will re-launch on the next call to a successful log macro.
static FASTDDS_EXPORTED_API void ReportFilenames(bool)
Enables the reporting of filenames in log entries. Disabled by default.
Kind
Types of log entry.
Definition: Log.hpp:90
@ Info
Definition: Log.hpp:93
@ Warning
Definition: Log.hpp:92
@ Error
Definition: Log.hpp:91
static FASTDDS_EXPORTED_API void Flush()
Waits until all info logged up to the call time is consumed.
static FASTDDS_EXPORTED_API std::regex GetFilenameFilter()
Returns a copy of the current filename filter or an empty object otherwise.
static FASTDDS_EXPORTED_API bool HasCategoryFilter()
Returns whether a category filter was set or not.
static FASTDDS_EXPORTED_API std::regex GetErrorStringFilter()
Returns a copy of the current error string filter or an empty object otherwise.
static FASTDDS_EXPORTED_API void UnsetCategoryFilter()
Unset the category filter.
Definition: DomainParticipant.hpp:46
std::ostream & operator<<(std::ostream &output, const Time_t &t)
Definition: Time_t.hpp:261
const char * category
Definition: Log.hpp:170
int line
Definition: Log.hpp:168
const char * filename
Definition: Log.hpp:167
Definition: Log.hpp:174
std::string message
Definition: Log.hpp:175
std::string timestamp
Definition: Log.hpp:178
Log::Kind kind
Definition: Log.hpp:177
Log::Context context
Definition: Log.hpp:176
Struct ThreadSettings to specify various thread settings.
Definition: ThreadSettings.hpp:37