Fast DDS  Version 3.0.0
Fast DDS
Loading...
Searching...
No Matches
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
65namespace eprosima {
66namespace fastdds {
67namespace dds {
68
69class LogConsumer;
70
79class Log
80{
81public:
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
196inline 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
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{
226public:
227
228 virtual ~LogConsumer() = default;
229
230 virtual void Consume(
231 const Log::Entry&) = 0;
232
233protected:
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:45
std::ostream & operator<<(std::ostream &output, const Time_t &t)
Definition Time_t.hpp:261
eProsima namespace.
const char * category
Definition Log.hpp:170
int line
Definition Log.hpp:168
const char * filename
Definition Log.hpp:167
const char * function
Definition Log.hpp:169
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