Logger.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /*
  2. * Copyright 2017-present Facebook, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #pragma once
  17. #include <folly/Conv.h>
  18. #include <folly/Format.h>
  19. #include <folly/logging/LogCategory.h>
  20. #include <folly/logging/LogLevel.h>
  21. #include <folly/logging/LogStream.h>
  22. #include <folly/logging/LogStreamProcessor.h>
  23. /**
  24. * Log a message to the specified logger.
  25. *
  26. * This macro avoids evaluating the log arguments unless the log level check
  27. * succeeds.
  28. *
  29. * Beware that the logger argument is evaluated twice, so this argument should
  30. * be an expression with no side-effects.
  31. */
  32. #define FB_LOG(logger, level, ...) \
  33. FB_LOG_IMPL( \
  34. logger, \
  35. ::folly::LogLevel::level, \
  36. ::folly::LogStreamProcessor::APPEND, \
  37. ##__VA_ARGS__)
  38. /**
  39. * Log a message to the specified logger, using a folly::format() string.
  40. *
  41. * The arguments will be processed using folly::format(). The format syntax
  42. * is similar to Python format strings.
  43. *
  44. * This macro avoids evaluating the log arguments unless the log level check
  45. * succeeds.
  46. *
  47. * Beware that the logger argument is evaluated twice, so this argument should
  48. * be an expression with no side-effects.
  49. */
  50. #define FB_LOGF(logger, level, fmt, arg1, ...) \
  51. FB_LOG_IMPL( \
  52. logger, \
  53. ::folly::LogLevel::level, \
  54. ::folly::LogStreamProcessor::FORMAT, \
  55. fmt, \
  56. arg1, \
  57. ##__VA_ARGS__)
  58. /**
  59. * FB_LOG_RAW() can be used by callers that want to pass in the log level as a
  60. * variable, and/or who want to explicitly specify the filename and line
  61. * number.
  62. *
  63. * This is useful for callers implementing their own log wrapper functions
  64. * that want to pass in their caller's filename and line number rather than
  65. * their own.
  66. *
  67. * The log level parameter must be an explicitly qualified LogLevel value, or a
  68. * LogLevel variable. (This differs from FB_LOG() and FB_LOGF() which accept
  69. * an unqualified LogLevel name.)
  70. */
  71. #define FB_LOG_RAW(logger, level, filename, linenumber, functionName, ...) \
  72. FB_LOG_RAW_IMPL( \
  73. logger, \
  74. level, \
  75. filename, \
  76. linenumber, \
  77. functionName, \
  78. ::folly::LogStreamProcessor::APPEND, \
  79. ##__VA_ARGS__)
  80. /**
  81. * FB_LOGF_RAW() is similar to FB_LOG_RAW(), but formats the log arguments
  82. * using folly::format().
  83. */
  84. #define FB_LOGF_RAW( \
  85. logger, level, filename, linenumber, functionName, fmt, arg1, ...) \
  86. FB_LOG_RAW_IMPL( \
  87. logger, \
  88. level, \
  89. filename, \
  90. linenumber, \
  91. functionName, \
  92. ::folly::LogStreamProcessor::FORMAT, \
  93. fmt, \
  94. arg1, \
  95. ##__VA_ARGS__)
  96. /**
  97. * Helper macro for implementing FB_LOG() and FB_LOGF().
  98. *
  99. * This macro generally should not be used directly by end users.
  100. */
  101. #define FB_LOG_IMPL(logger, level, type, ...) \
  102. (!(logger).getCategory()->logCheck(level)) \
  103. ? ::folly::logDisabledHelper( \
  104. ::folly::bool_constant<::folly::isLogLevelFatal(level)>{}) \
  105. : ::folly::LogStreamVoidify<::folly::isLogLevelFatal(level)>{} & \
  106. ::folly::LogStreamProcessor{(logger).getCategory(), \
  107. (level), \
  108. __FILE__, \
  109. __LINE__, \
  110. __func__, \
  111. (type), \
  112. ##__VA_ARGS__} \
  113. .stream()
  114. /**
  115. * Helper macro for implementing FB_LOG_RAW() and FB_LOGF_RAW().
  116. *
  117. * This macro generally should not be used directly by end users.
  118. *
  119. * This is very similar to FB_LOG_IMPL(), but since the level may be a variable
  120. * instead of a compile-time constant, we cannot detect at compile time if this
  121. * is a fatal log message or not.
  122. */
  123. #define FB_LOG_RAW_IMPL( \
  124. logger, level, filename, line, functionName, type, ...) \
  125. (!(logger).getCategory()->logCheck(level)) \
  126. ? static_cast<void>(0) \
  127. : ::folly::LogStreamVoidify<false>{} & \
  128. ::folly::LogStreamProcessor{(logger).getCategory(), \
  129. (level), \
  130. (filename), \
  131. (line), \
  132. (functionName), \
  133. (type), \
  134. ##__VA_ARGS__} \
  135. .stream()
  136. namespace folly {
  137. class LoggerDB;
  138. class LogMessage;
  139. /**
  140. * Logger is the class you will use to specify the log category when logging
  141. * messages with FB_LOG().
  142. *
  143. * Logger is really just a small wrapper class that contains a pointer to the
  144. * appropriate LogCategory object. It primarily exists as syntactic sugar to
  145. * allow for easily looking up LogCategory objects.
  146. */
  147. class Logger {
  148. public:
  149. /**
  150. * Construct a Logger for the given category name.
  151. *
  152. * A LogCategory object for this category will be created if one does not
  153. * already exist.
  154. */
  155. explicit Logger(folly::StringPiece name);
  156. /**
  157. * Construct a Logger pointing to an existing LogCategory object.
  158. */
  159. explicit Logger(LogCategory* cat);
  160. /**
  161. * Construct a Logger for a specific LoggerDB object, rather than the main
  162. * singleton.
  163. *
  164. * This is primarily intended for use in unit tests.
  165. */
  166. Logger(LoggerDB* db, folly::StringPiece name);
  167. /**
  168. * Get the LogCategory that this Logger refers to.
  169. */
  170. LogCategory* getCategory() const {
  171. return category_;
  172. }
  173. private:
  174. LogCategory* const category_{nullptr};
  175. };
  176. } // namespace folly