mc_rtc  2.14.0
logging.h
Go to the documentation of this file.
1 /*
2  * Copyright 2015-2019 CNRS-UM LIRMM, CNRS-AIST JRL
3  */
4 
5 #pragma once
6 
7 #include <mc_rtc/utils_api.h>
8 
9 #include <iostream>
10 
11 #include <spdlog/fmt/fmt.h>
12 #include <spdlog/fmt/ostr.h>
13 #include <spdlog/logger.h>
14 
15 // fmt 9.0.0 removed automated operator<< discovery we use fmt::streamed instead when needed through a macro
16 #if FMT_VERSION >= 9 * 10000
17 # define MC_FMT_STREAMED(X) fmt::streamed(X)
18 # include <boost/filesystem.hpp>
19 # include <Eigen/Core>
20 # include <fmt/ostream.h>
21 # include <fmt/ranges.h>
22 # include <type_traits>
23 
24 // Formatter for Eigen dense types (like Eigen::Matrix, Eigen::Array)
25 template<typename T, typename Char>
26 struct fmt::formatter<T,
27  Char,
28  std::enable_if_t<std::is_base_of_v<Eigen::DenseBase<T>, T>
29  && (fmt::range_format_kind<T, Char, void>::value == fmt::range_format::disabled)>>
30 : fmt::ostream_formatter
31 {
32 };
33 
34 // Formatter for boost::filesystem::path
35 template<>
36 struct fmt::formatter<boost::filesystem::path> : fmt::formatter<std::string>
37 {
38  template<typename FormatContext>
39  auto format(const boost::filesystem::path & p, FormatContext & ctx)
40  {
41  return fmt::formatter<std::string>::format(p.string(), ctx);
42  }
43 };
44 
45 #else
46 # define MC_FMT_STREAMED(X) X
47 #endif
48 
49 #define BOOST_STACKTRACE_LINK
50 #include <boost/stacktrace.hpp>
51 
52 namespace mc_rtc
53 {
54 
55 namespace log
56 {
57 
58 namespace details
59 {
60 
61 MC_RTC_UTILS_DLLAPI spdlog::logger & success();
62 
63 MC_RTC_UTILS_DLLAPI spdlog::logger & info();
64 
65 MC_RTC_UTILS_DLLAPI spdlog::logger & cerr();
66 
67 MC_RTC_UTILS_DLLAPI void notify(const std::string & message);
68 
70 
71 } // namespace details
72 
73 template<typename ExceptionT = std::runtime_error, typename... Args>
74 void error_and_throw [[noreturn]] (Args &&... args)
75 {
76  auto message = fmt::format(std::forward<Args>(args)...);
77  details::notify(message);
78  details::cerr().critical(message);
79  details::cerr().critical("=== Backtrace ===\n{}", MC_FMT_STREAMED(boost::stacktrace::stacktrace()));
80  throw ExceptionT(message);
81 }
82 
83 template<typename... Args>
84 void critical(Args &&... args)
85 {
86  details::cerr().critical(std::forward<Args>(args)...);
87 }
88 
89 template<typename... Args>
90 void error(Args &&... args)
91 {
92  details::cerr().error(std::forward<Args>(args)...);
93 }
94 
95 template<typename... Args>
96 void warning(Args &&... args)
97 {
98  details::cerr().warn(std::forward<Args>(args)...);
99 }
100 
101 template<typename... Args>
102 void info(Args &&... args)
103 {
104  details::info().info(std::forward<Args>(args)...);
105 }
106 
107 template<typename... Args>
108 void success(Args &&... args)
109 {
110  details::success().info(std::forward<Args>(args)...);
111 }
112 
113 template<typename... Args>
114 void notify(Args &&... args)
115 {
116  details::notify(fmt::format(std::forward<Args>(args)...));
117 }
118 
119 } // namespace log
120 
121 } // namespace mc_rtc
122 
123 #ifndef WIN32
124 
125 namespace mc_rtc
126 {
127 
128 constexpr auto OUT_NONE = "\033[00m";
129 constexpr auto OUT_BLUE = "\033[01;34m";
130 constexpr auto OUT_GREEN = "\033[01;32m";
131 constexpr auto OUT_PURPLE = "\033[01;35m";
132 constexpr auto OUT_RED = "\033[01;31m";
133 
134 } // namespace mc_rtc
135 
136 # define LOG_ERROR(args) \
137  _Pragma("GCC warning \"This macro is deprecated, use mc_rtc::log::error instead\""); \
138  std::cerr << mc_rtc::OUT_RED << args << mc_rtc::OUT_NONE << "\n";
139 # define LOG_WARNING(args) \
140  _Pragma("GCC warning \"This macro is deprecated, use mc_rtc::log::warning instead\""); \
141  std::cerr << mc_rtc::OUT_PURPLE << args << mc_rtc::OUT_NONE << "\n";
142 # define LOG_INFO(args) \
143  _Pragma("GCC warning \"This macro is deprecated, use mc_rtc::log::info instead\""); \
144  std::cout << mc_rtc::OUT_BLUE << args << mc_rtc::OUT_NONE << "\n";
145 # define LOG_SUCCESS(args) \
146  _Pragma("GCC warning \"This macro is deprecated, use mc_rtc::log::success instead\""); \
147  std::cout << mc_rtc::OUT_GREEN << args << mc_rtc::OUT_NONE << "\n";
148 
149 # define LOG_ERROR_AND_THROW(exception_type, args) \
150  { \
151  _Pragma("GCC warning \"This macro is deprecated, use mc_rtc::log::error_and_throw<exception_type> instead\""); \
152  std::stringstream strstrm; \
153  strstrm << args; \
154  LOG_ERROR(strstrm.str()) \
155  throw exception_type(strstrm.str()); \
156  }
157 
158 #else
159 
160 # include <windows.h>
161 namespace mc_rtc
162 {
163 static const HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
164 constexpr auto OUT_NONE = 15;
165 constexpr auto OUT_BLUE = 11;
166 constexpr auto OUT_GREEN = 10;
167 constexpr auto OUT_PURPLE = 13;
168 constexpr auto OUT_RED = 12;
169 } // namespace mc_rtc
170 
171 # define __MC_RTC_STR2__(x) #x
172 # define __MC_RTC_STR1__(x) __MC_RTC_STR2__(x)
173 # define __MC_RTC_PRAGMA_LOC__ __FILE__ "("__MC_RTC_STR1__(__LINE__) ") "
174 
175 # define LOG_ERROR(args) \
176  __pragma(message(__MC_RTC_PRAGMA_LOC__ ": warning: this macro is deprecated, use mc_rtc::log::error instead")); \
177  SetConsoleTextAttribute(mc_rtc::hConsole, mc_rtc::OUT_RED); \
178  std::cerr << args << std::endl; \
179  SetConsoleTextAttribute(mc_rtc::hConsole, mc_rtc::OUT_NONE);
180 
181 # define LOG_WARNING(args) \
182  __pragma(message(__MC_RTC_PRAGMA_LOC__ ": warning: this macro is deprecated, use mc_rtc::log::warning instead")); \
183  SetConsoleTextAttribute(mc_rtc::hConsole, mc_rtc::OUT_PURPLE); \
184  std::cerr << args << std::endl; \
185  SetConsoleTextAttribute(mc_rtc::hConsole, mc_rtc::OUT_NONE);
186 
187 # define LOG_INFO(args) \
188  __pragma(message(__MC_RTC_PRAGMA_LOC__ ": warning: this macro is deprecated, use mc_rtc::log::info instead")); \
189  SetConsoleTextAttribute(mc_rtc::hConsole, mc_rtc::OUT_BLUE); \
190  std::cout << args << std::endl; \
191  SetConsoleTextAttribute(mc_rtc::hConsole, mc_rtc::OUT_NONE);
192 
193 # define LOG_SUCCESS(args) \
194  __pragma(message(__MC_RTC_PRAGMA_LOC__ ": warning: this macro is deprecated, use mc_rtc::log::success instead")); \
195  SetConsoleTextAttribute(mc_rtc::hConsole, mc_rtc::OUT_GREEN); \
196  std::cout << args << std::endl; \
197  SetConsoleTextAttribute(mc_rtc::hConsole, mc_rtc::OUT_NONE);
198 
199 # define LOG_ERROR_AND_THROW(exception_type, args) \
200  { \
201  __pragma( \
202  message(__MC_RTC_PRAGMA_LOC__ \
203  ": warning: this macro is deprecated, use mc_rtc::log::error_and_throw<exception_type> instead")); \
204  std::stringstream strstrm; \
205  strstrm << args; \
206  LOG_ERROR(strstrm.str()) \
207  throw exception_type(strstrm.str()); \
208  }
209 
210 #endif
#define MC_FMT_STREAMED(X)
Definition: logging.h:46
MC_RTC_UTILS_DLLAPI spdlog::logger & info()
MC_RTC_UTILS_DLLAPI spdlog::logger & success()
MC_RTC_UTILS_DLLAPI void disable_notifications()
MC_RTC_UTILS_DLLAPI void notify(const std::string &message)
MC_RTC_UTILS_DLLAPI spdlog::logger & cerr()
void info(Args &&... args)
Definition: logging.h:102
void error_and_throw(Args &&... args)
Definition: logging.h:74
void success(Args &&... args)
Definition: logging.h:108
void notify(Args &&... args)
Definition: logging.h:114
void critical(Args &&... args)
Definition: logging.h:84
void warning(Args &&... args)
Definition: logging.h:96
void error(Args &&... args)
Definition: logging.h:90
Definition: Contact.h:88
constexpr auto OUT_BLUE
Definition: logging.h:129
constexpr auto OUT_GREEN
Definition: logging.h:130
constexpr auto OUT_RED
Definition: logging.h:132
constexpr auto OUT_NONE
Definition: logging.h:128
constexpr auto OUT_PURPLE
Definition: logging.h:131
Definition: Contact.h:67
#define MC_RTC_UTILS_DLLAPI
Definition: utils_api.h:50