Logging.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. // Copyright 2020 Canonical ltd.
  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. * @file Logging.h
  16. */
  17. #ifndef _FASTDDS_RTPS_SECURITY_LOGGING_LOGGING_H_
  18. #define _FASTDDS_RTPS_SECURITY_LOGGING_LOGGING_H_
  19. #include <limits>
  20. #include <iomanip>
  21. #include <fastdds/dds/log/Log.hpp>
  22. #include <fastdds/rtps/security/logging/LogOptions.h>
  23. #include <fastdds/rtps/security/logging/BuiltinLoggingType.h>
  24. #include <fastdds/rtps/security/exceptions/SecurityException.h>
  25. #include <fastdds/rtps/common/Guid.h>
  26. namespace eprosima {
  27. namespace fastrtps {
  28. namespace rtps {
  29. namespace security {
  30. /**
  31. * @brief The LoggerListener class
  32. */
  33. class LoggerListener
  34. {
  35. LoggerListener() = default;
  36. ~LoggerListener() = default;
  37. };
  38. /**
  39. * @brief Base class for all security logging plugins.
  40. */
  41. class Logging
  42. {
  43. public:
  44. Logging();
  45. virtual ~Logging() = default;
  46. /**
  47. * @brief set_log_options
  48. * @param log_options
  49. * @param exception
  50. * @return TRUE if successful
  51. */
  52. bool set_log_options(
  53. const LogOptions& log_options,
  54. SecurityException& exception);
  55. /**
  56. * @brief get_log_options
  57. * @param log_options
  58. * @param exception
  59. * @return
  60. */
  61. bool get_log_options(
  62. LogOptions& log_options,
  63. SecurityException& exception) const;
  64. /**
  65. * @brief enable_logging
  66. */
  67. bool enable_logging(
  68. SecurityException& exception);
  69. /**
  70. * @brief set_listener
  71. * @param listener
  72. * @param exception
  73. * @return
  74. */
  75. bool set_listener(
  76. LoggerListener* listener,
  77. SecurityException& exception);
  78. /**
  79. * @brief log
  80. * @param log_level
  81. * @param message
  82. * @param category
  83. * @param exception
  84. */
  85. void log(
  86. const LoggingLevel log_level,
  87. const std::string& message,
  88. const std::string& category,
  89. SecurityException& exception) const;
  90. /**
  91. * @brief Whether the options are set or not.
  92. * @return True if the options are set.
  93. */
  94. bool options_set() const
  95. {
  96. return options_set_;
  97. }
  98. /**
  99. * @brief Whether the logging is enabled or not.
  100. * @return True if the logging is enabled.
  101. */
  102. bool enabled() const
  103. {
  104. return logging_enabled_;
  105. }
  106. /**
  107. * @brief Return the LoggerListener.
  108. * @return A pointer to the (const) LoggerListener.
  109. */
  110. LoggerListener const* get_listener() const
  111. {
  112. return listener_;
  113. }
  114. bool set_guid(
  115. const GUID_t& guid,
  116. SecurityException& exception);
  117. bool set_domain_id(
  118. const uint32_t id,
  119. SecurityException& exception);
  120. protected:
  121. /**
  122. * @brief enable_logging_impl
  123. * @return
  124. */
  125. virtual bool enable_logging_impl(
  126. SecurityException& /*exception*/)
  127. {
  128. return true;
  129. }
  130. /**
  131. * @brief convert
  132. * @param log_level
  133. * @param message
  134. * @param category
  135. * @param builtin_msg
  136. * @param exception
  137. * @return
  138. */
  139. virtual bool convert(
  140. const LoggingLevel log_level,
  141. const std::string& message,
  142. const std::string& category,
  143. BuiltinLoggingType& builtin_msg,
  144. SecurityException& exception) const;
  145. template <typename Stream>
  146. bool compose_header(
  147. Stream& header,
  148. const BuiltinLoggingType& builtin_msg,
  149. SecurityException& exception) const;
  150. /**
  151. * @brief log_impl
  152. * @param message
  153. * @param exception
  154. */
  155. virtual void log_impl(
  156. const BuiltinLoggingType& message,
  157. SecurityException& exception) const = 0;
  158. private:
  159. LoggerListener* listener_;
  160. bool logging_enabled_ = false;
  161. bool options_set_ = false;
  162. LogOptions log_options_;
  163. GUID_t guid_;
  164. std::string guid_str_;
  165. uint32_t domain_id_ = std::numeric_limits<uint32_t>::max();
  166. std::string domain_id_str_;
  167. };
  168. template <typename Stream>
  169. bool Logging::compose_header(
  170. Stream& header,
  171. const BuiltinLoggingType& builtin_msg,
  172. SecurityException& exception) const
  173. {
  174. const auto it = builtin_msg.structured_data.find("DDS");
  175. if (builtin_msg.structured_data.end() == it)
  176. {
  177. exception = SecurityException("Could not find expected DDS field.");
  178. return false;
  179. }
  180. std::string severity;
  181. if (!LogLevel_to_string(builtin_msg.severity, severity, exception))
  182. {
  183. return false;
  184. }
  185. // header format is:
  186. // [stamp] [severity] <guid> <domain_id> <plugin_class::plugin_method>
  187. header << std::setprecision (std::numeric_limits<double>::digits10 + 1)
  188. << "[" << builtin_msg.timestamp << "] "
  189. << "[" << severity << "] "
  190. << it->second.at(0).value << " "
  191. << it->second.at(1).value << " "
  192. << it->second.at(2).value << "::" << it->second.at(3).value;
  193. return true;
  194. }
  195. } //namespace security
  196. } //namespace rtps
  197. } //namespace fastrtps
  198. } //namespace eprosima
  199. // gcc expands __VA_ARGS___ before passing it into the macro.
  200. // Visual Studio expands __VA_ARGS__ after passing it.
  201. // This macro is a workaround to support both
  202. #define __FASTRTPS_EXPAND(x) x
  203. #define __FASTRTPS_SECURITY_LOGGING(LEVEL, CLASS, MESSAGE, EXCEPTION) \
  204. do { \
  205. auto logger = get_logger(); \
  206. if (logger){ \
  207. logger->log(LEVEL, \
  208. MESSAGE, \
  209. std::string(CLASS ",") + __func__, \
  210. EXCEPTION); \
  211. } else { \
  212. switch (LEVEL){ \
  213. case LoggingLevel::EMERGENCY_LEVEL: \
  214. case LoggingLevel::ALERT_LEVEL: \
  215. case LoggingLevel::CRITICAL_LEVEL: \
  216. case LoggingLevel::ERROR_LEVEL: \
  217. logError(SECURITY, MESSAGE); \
  218. break; \
  219. case LoggingLevel::WARNING_LEVEL: \
  220. logWarning(SECURITY, MESSAGE); \
  221. break; \
  222. case LoggingLevel::NOTICE_LEVEL: \
  223. case LoggingLevel::INFORMATIONAL_LEVEL: \
  224. case LoggingLevel::DEBUG_LEVEL: \
  225. logInfo(SECURITY, MESSAGE); \
  226. break; \
  227. } \
  228. } \
  229. } while (0);
  230. #define __FASTRTPS_SECURITY_LOGGING_EX(LEVEL, CLASS, MESSAGE) \
  231. do { \
  232. eprosima::fastrtps::rtps::security::SecurityException lexception; \
  233. __FASTRTPS_SECURITY_LOGGING(LEVEL, CLASS, MESSAGE, lexception); \
  234. } while (0);
  235. #define __FASTRTPS_MACRO_SELECTOR(_1, _2, _3, _4, NAME, ...) NAME
  236. #define SECURITY_LOGGING(...) \
  237. __FASTRTPS_EXPAND( \
  238. __FASTRTPS_MACRO_SELECTOR(__VA_ARGS__, \
  239. __FASTRTPS_SECURITY_LOGGING, \
  240. __FASTRTPS_SECURITY_LOGGING_EX, \
  241. _UNUSED)(__VA_ARGS__) )
  242. #define EMERGENCY_SECURITY_LOGGING(...) SECURITY_LOGGING(LoggingLevel::EMERGENCY_LEVEL, __VA_ARGS__)
  243. #define ALERT_SECURITY_LOGGING(...) SECURITY_LOGGING(LoggingLevel::ALERT_LEVEL, __VA_ARGS__)
  244. #define CRITICAL_SECURITY_LOGGING(...) SECURITY_LOGGING(LoggingLevel::CRITICAL_LEVEL, __VA_ARGS__)
  245. #define ERROR_SECURITY_LOGGING(...) SECURITY_LOGGING(LoggingLevel::ERROR_LEVEL, __VA_ARGS__)
  246. #define WARNING_SECURITY_LOGGING(...) SECURITY_LOGGING(LoggingLevel::WARNING_LEVEL, __VA_ARGS__)
  247. #define NOTICE_SECURITY_LOGGING(...) SECURITY_LOGGING(LoggingLevel::NOTICE_LEVEL, __VA_ARGS__)
  248. #define INFORMATIONAL_SECURITY_LOGGING(...) SECURITY_LOGGING(LoggingLevel::INFORMATIONAL_LEVEL, __VA_ARGS__)
  249. #define DEBUG_SECURITY_LOGGING(...) SECURITY_LOGGING(LoggingLevel::DEBUG_LEVEL, __VA_ARGS__)
  250. #endif // _FASTDDS_RTPS_SECURITY_LOGGING_LOGGING_H_