log_message.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. // Copyright 2022 The Abseil Authors.
  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. // https://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. // -----------------------------------------------------------------------------
  16. // File: log/internal/log_message.h
  17. // -----------------------------------------------------------------------------
  18. //
  19. // This file declares `class absl::log_internal::LogMessage`. This class more or
  20. // less represents a particular log message. LOG/CHECK macros create a
  21. // temporary instance of `LogMessage` and then stream values to it. At the end
  22. // of the LOG/CHECK statement, LogMessage instance goes out of scope and
  23. // `~LogMessage` directs the message to the registered log sinks.
  24. // Heap-allocation of `LogMessage` is unsupported. Construction outside of a
  25. // `LOG` macro is unsupported.
  26. #ifndef ABSL_LOG_INTERNAL_LOG_MESSAGE_H_
  27. #define ABSL_LOG_INTERNAL_LOG_MESSAGE_H_
  28. #include <ios>
  29. #include <memory>
  30. #include <ostream>
  31. #include <streambuf>
  32. #include <string>
  33. #include "absl/base/attributes.h"
  34. #include "absl/base/config.h"
  35. #include "absl/base/internal/errno_saver.h"
  36. #include "absl/base/log_severity.h"
  37. #include "absl/log/internal/nullguard.h"
  38. #include "absl/log/log_entry.h"
  39. #include "absl/log/log_sink.h"
  40. #include "absl/strings/has_absl_stringify.h"
  41. #include "absl/strings/string_view.h"
  42. #include "absl/time/time.h"
  43. namespace absl {
  44. ABSL_NAMESPACE_BEGIN
  45. namespace log_internal {
  46. constexpr int kLogMessageBufferSize = 15000;
  47. class LogMessage {
  48. public:
  49. struct InfoTag {};
  50. struct WarningTag {};
  51. struct ErrorTag {};
  52. // Used for `LOG`.
  53. LogMessage(const char* file, int line,
  54. absl::LogSeverity severity) ABSL_ATTRIBUTE_COLD;
  55. // These constructors are slightly smaller/faster to call; the severity is
  56. // curried into the function pointer.
  57. LogMessage(const char* file, int line,
  58. InfoTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE;
  59. LogMessage(const char* file, int line,
  60. WarningTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE;
  61. LogMessage(const char* file, int line,
  62. ErrorTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE;
  63. LogMessage(const LogMessage&) = delete;
  64. LogMessage& operator=(const LogMessage&) = delete;
  65. ~LogMessage() ABSL_ATTRIBUTE_COLD;
  66. // Overrides the location inferred from the callsite. The string pointed to
  67. // by `file` must be valid until the end of the statement.
  68. LogMessage& AtLocation(absl::string_view file, int line);
  69. // Omits the prefix from this line. The prefix includes metadata about the
  70. // logged data such as source code location and timestamp.
  71. LogMessage& NoPrefix();
  72. // Sets the verbosity field of the logged message as if it was logged by
  73. // `VLOG(verbose_level)`. Unlike `VLOG`, this method does not affect
  74. // evaluation of the statement when the specified `verbose_level` has been
  75. // disabled. The only effect is on `absl::LogSink` implementations which
  76. // make use of the `absl::LogSink::verbosity()` value. The value
  77. // `absl::LogEntry::kNoVerbosityLevel` can be specified to mark the message
  78. // not verbose.
  79. LogMessage& WithVerbosity(int verbose_level);
  80. // Uses the specified timestamp instead of one collected in the constructor.
  81. LogMessage& WithTimestamp(absl::Time timestamp);
  82. // Uses the specified thread ID instead of one collected in the constructor.
  83. LogMessage& WithThreadID(absl::LogEntry::tid_t tid);
  84. // Copies all metadata (but no data) from the specified `absl::LogEntry`.
  85. LogMessage& WithMetadataFrom(const absl::LogEntry& entry);
  86. // Appends to the logged message a colon, a space, a textual description of
  87. // the current value of `errno` (as by strerror(3)), and the numerical value
  88. // of `errno`.
  89. LogMessage& WithPerror();
  90. // Sends this message to `*sink` in addition to whatever other sinks it would
  91. // otherwise have been sent to. `sink` must not be null.
  92. LogMessage& ToSinkAlso(absl::LogSink* sink);
  93. // Sends this message to `*sink` and no others. `sink` must not be null.
  94. LogMessage& ToSinkOnly(absl::LogSink* sink);
  95. // Don't call this method from outside this library.
  96. LogMessage& InternalStream() { return *this; }
  97. // By-value overloads for small, common types let us overlook common failures
  98. // to define globals and static data members (i.e. in a .cc file).
  99. // clang-format off
  100. // The CUDA toolchain cannot handle these <<<'s:
  101. LogMessage& operator<<(char v) { return operator<< <char>(v); }
  102. LogMessage& operator<<(signed char v) { return operator<< <signed char>(v); }
  103. LogMessage& operator<<(unsigned char v) {
  104. return operator<< <unsigned char>(v);
  105. }
  106. LogMessage& operator<<(signed short v) { // NOLINT
  107. return operator<< <signed short>(v); // NOLINT
  108. }
  109. LogMessage& operator<<(signed int v) { return operator<< <signed int>(v); }
  110. LogMessage& operator<<(signed long v) { // NOLINT
  111. return operator<< <signed long>(v); // NOLINT
  112. }
  113. LogMessage& operator<<(signed long long v) { // NOLINT
  114. return operator<< <signed long long>(v); // NOLINT
  115. }
  116. LogMessage& operator<<(unsigned short v) { // NOLINT
  117. return operator<< <unsigned short>(v); // NOLINT
  118. }
  119. LogMessage& operator<<(unsigned int v) {
  120. return operator<< <unsigned int>(v);
  121. }
  122. LogMessage& operator<<(unsigned long v) { // NOLINT
  123. return operator<< <unsigned long>(v); // NOLINT
  124. }
  125. LogMessage& operator<<(unsigned long long v) { // NOLINT
  126. return operator<< <unsigned long long>(v); // NOLINT
  127. }
  128. LogMessage& operator<<(void* v) { return operator<< <void*>(v); }
  129. LogMessage& operator<<(const void* v) { return operator<< <const void*>(v); }
  130. LogMessage& operator<<(float v) { return operator<< <float>(v); }
  131. LogMessage& operator<<(double v) { return operator<< <double>(v); }
  132. LogMessage& operator<<(bool v) { return operator<< <bool>(v); }
  133. // clang-format on
  134. // These overloads are more efficient since no `ostream` is involved.
  135. LogMessage& operator<<(const std::string& v);
  136. LogMessage& operator<<(absl::string_view v);
  137. // Handle stream manipulators e.g. std::endl.
  138. LogMessage& operator<<(std::ostream& (*m)(std::ostream& os));
  139. LogMessage& operator<<(std::ios_base& (*m)(std::ios_base& os));
  140. // Literal strings. This allows us to record C string literals as literals in
  141. // the logging.proto.Value.
  142. //
  143. // Allow this overload to be inlined to prevent generating instantiations of
  144. // this template for every value of `SIZE` encountered in each source code
  145. // file. That significantly increases linker input sizes. Inlining is cheap
  146. // because the argument to this overload is almost always a string literal so
  147. // the call to `strlen` can be replaced at compile time. The overload for
  148. // `char[]` below should not be inlined. The compiler typically does not have
  149. // the string at compile time and cannot replace the call to `strlen` so
  150. // inlining it increases the binary size. See the discussion on
  151. // cl/107527369.
  152. template <int SIZE>
  153. LogMessage& operator<<(const char (&buf)[SIZE]);
  154. // This prevents non-const `char[]` arrays from looking like literals.
  155. template <int SIZE>
  156. LogMessage& operator<<(char (&buf)[SIZE]) ABSL_ATTRIBUTE_NOINLINE;
  157. // Types that support `AbslStringify()` are serialized that way.
  158. template <typename T,
  159. typename std::enable_if<absl::HasAbslStringify<T>::value,
  160. int>::type = 0>
  161. LogMessage& operator<<(const T& v) ABSL_ATTRIBUTE_NOINLINE;
  162. // Types that don't support `AbslStringify()` but do support streaming into a
  163. // `std::ostream&` are serialized that way.
  164. template <typename T,
  165. typename std::enable_if<!absl::HasAbslStringify<T>::value,
  166. int>::type = 0>
  167. LogMessage& operator<<(const T& v) ABSL_ATTRIBUTE_NOINLINE;
  168. // Note: We explicitly do not support `operator<<` for non-const references
  169. // because it breaks logging of non-integer bitfield types (i.e., enums).
  170. protected:
  171. // Call `abort()` or similar to perform `LOG(FATAL)` crash. It is assumed
  172. // that the caller has already generated and written the trace as appropriate.
  173. [[noreturn]] static void FailWithoutStackTrace();
  174. // Similar to `FailWithoutStackTrace()`, but without `abort()`. Terminates
  175. // the process with an error exit code.
  176. [[noreturn]] static void FailQuietly();
  177. // Dispatches the completed `absl::LogEntry` to applicable `absl::LogSink`s.
  178. // This might as well be inlined into `~LogMessage` except that
  179. // `~LogMessageFatal` needs to call it early.
  180. void Flush();
  181. // After this is called, failures are done as quiet as possible for this log
  182. // message.
  183. void SetFailQuietly();
  184. private:
  185. struct LogMessageData; // Opaque type containing message state
  186. friend class AsLiteralImpl;
  187. friend class StringifySink;
  188. // This streambuf writes directly into the structured logging buffer so that
  189. // arbitrary types can be encoded as string data (using
  190. // `operator<<(std::ostream &, ...)` without any extra allocation or copying.
  191. // Space is reserved before the data to store the length field, which is
  192. // filled in by `~OstreamView`.
  193. class OstreamView final : public std::streambuf {
  194. public:
  195. explicit OstreamView(LogMessageData& message_data);
  196. ~OstreamView() override;
  197. OstreamView(const OstreamView&) = delete;
  198. OstreamView& operator=(const OstreamView&) = delete;
  199. std::ostream& stream();
  200. private:
  201. LogMessageData& data_;
  202. absl::Span<char> encoded_remaining_copy_;
  203. absl::Span<char> message_start_;
  204. absl::Span<char> string_start_;
  205. };
  206. enum class StringType {
  207. kLiteral,
  208. kNotLiteral,
  209. };
  210. template <StringType str_type>
  211. void CopyToEncodedBuffer(absl::string_view str) ABSL_ATTRIBUTE_NOINLINE;
  212. template <StringType str_type>
  213. void CopyToEncodedBuffer(char ch, size_t num) ABSL_ATTRIBUTE_NOINLINE;
  214. // Returns `true` if the message is fatal or enabled debug-fatal.
  215. bool IsFatal() const;
  216. // Records some tombstone-type data in anticipation of `Die`.
  217. void PrepareToDie();
  218. void Die();
  219. void SendToLog();
  220. // Checks `FLAGS_log_backtrace_at` and appends a backtrace if appropriate.
  221. void LogBacktraceIfNeeded();
  222. // This should be the first data member so that its initializer captures errno
  223. // before any other initializers alter it (e.g. with calls to new) and so that
  224. // no other destructors run afterward an alter it (e.g. with calls to delete).
  225. absl::base_internal::ErrnoSaver errno_saver_;
  226. // We keep the data in a separate struct so that each instance of `LogMessage`
  227. // uses less stack space.
  228. std::unique_ptr<LogMessageData> data_;
  229. };
  230. // Helper class so that `AbslStringify()` can modify the LogMessage.
  231. class StringifySink final {
  232. public:
  233. explicit StringifySink(LogMessage& message) : message_(message) {}
  234. void Append(size_t count, char ch) {
  235. message_.CopyToEncodedBuffer<LogMessage::StringType::kNotLiteral>(ch,
  236. count);
  237. }
  238. void Append(absl::string_view v) {
  239. message_.CopyToEncodedBuffer<LogMessage::StringType::kNotLiteral>(v);
  240. }
  241. // For types that implement `AbslStringify` using `absl::Format()`.
  242. friend void AbslFormatFlush(StringifySink* sink, absl::string_view v) {
  243. sink->Append(v);
  244. }
  245. private:
  246. LogMessage& message_;
  247. };
  248. // Note: the following is declared `ABSL_ATTRIBUTE_NOINLINE`
  249. template <typename T,
  250. typename std::enable_if<absl::HasAbslStringify<T>::value, int>::type>
  251. LogMessage& LogMessage::operator<<(const T& v) {
  252. StringifySink sink(*this);
  253. // Replace with public API.
  254. AbslStringify(sink, v);
  255. return *this;
  256. }
  257. // Note: the following is declared `ABSL_ATTRIBUTE_NOINLINE`
  258. template <typename T,
  259. typename std::enable_if<!absl::HasAbslStringify<T>::value, int>::type>
  260. LogMessage& LogMessage::operator<<(const T& v) {
  261. OstreamView view(*data_);
  262. view.stream() << log_internal::NullGuard<T>().Guard(v);
  263. return *this;
  264. }
  265. template <int SIZE>
  266. LogMessage& LogMessage::operator<<(const char (&buf)[SIZE]) {
  267. CopyToEncodedBuffer<StringType::kLiteral>(buf);
  268. return *this;
  269. }
  270. // Note: the following is declared `ABSL_ATTRIBUTE_NOINLINE`
  271. template <int SIZE>
  272. LogMessage& LogMessage::operator<<(char (&buf)[SIZE]) {
  273. CopyToEncodedBuffer<StringType::kNotLiteral>(buf);
  274. return *this;
  275. }
  276. // We instantiate these specializations in the library's TU to save space in
  277. // other TUs. Since the template is marked `ABSL_ATTRIBUTE_NOINLINE` we will be
  278. // emitting a function call either way.
  279. extern template LogMessage& LogMessage::operator<<(const char& v);
  280. extern template LogMessage& LogMessage::operator<<(const signed char& v);
  281. extern template LogMessage& LogMessage::operator<<(const unsigned char& v);
  282. extern template LogMessage& LogMessage::operator<<(const short& v); // NOLINT
  283. extern template LogMessage& LogMessage::operator<<(
  284. const unsigned short& v); // NOLINT
  285. extern template LogMessage& LogMessage::operator<<(const int& v);
  286. extern template LogMessage& LogMessage::operator<<(
  287. const unsigned int& v); // NOLINT
  288. extern template LogMessage& LogMessage::operator<<(const long& v); // NOLINT
  289. extern template LogMessage& LogMessage::operator<<(
  290. const unsigned long& v); // NOLINT
  291. extern template LogMessage& LogMessage::operator<<(
  292. const long long& v); // NOLINT
  293. extern template LogMessage& LogMessage::operator<<(
  294. const unsigned long long& v); // NOLINT
  295. extern template LogMessage& LogMessage::operator<<(void* const& v);
  296. extern template LogMessage& LogMessage::operator<<(const void* const& v);
  297. extern template LogMessage& LogMessage::operator<<(const float& v);
  298. extern template LogMessage& LogMessage::operator<<(const double& v);
  299. extern template LogMessage& LogMessage::operator<<(const bool& v);
  300. extern template void LogMessage::CopyToEncodedBuffer<
  301. LogMessage::StringType::kLiteral>(absl::string_view str);
  302. extern template void LogMessage::CopyToEncodedBuffer<
  303. LogMessage::StringType::kNotLiteral>(absl::string_view str);
  304. extern template void
  305. LogMessage::CopyToEncodedBuffer<LogMessage::StringType::kLiteral>(char ch,
  306. size_t num);
  307. extern template void LogMessage::CopyToEncodedBuffer<
  308. LogMessage::StringType::kNotLiteral>(char ch, size_t num);
  309. // `LogMessageFatal` ensures the process will exit in failure after logging this
  310. // message.
  311. class LogMessageFatal final : public LogMessage {
  312. public:
  313. LogMessageFatal(const char* file, int line) ABSL_ATTRIBUTE_COLD;
  314. LogMessageFatal(const char* file, int line,
  315. absl::string_view failure_msg) ABSL_ATTRIBUTE_COLD;
  316. [[noreturn]] ~LogMessageFatal();
  317. };
  318. // `LogMessageDebugFatal` ensures the process will exit in failure after logging
  319. // this message. It matches LogMessageFatal but is not [[noreturn]] as it's used
  320. // for DLOG(FATAL) variants.
  321. class LogMessageDebugFatal final : public LogMessage {
  322. public:
  323. LogMessageDebugFatal(const char* file, int line) ABSL_ATTRIBUTE_COLD;
  324. ~LogMessageDebugFatal();
  325. };
  326. class LogMessageQuietlyDebugFatal final : public LogMessage {
  327. public:
  328. // DLOG(QFATAL) calls this instead of LogMessageQuietlyFatal to make sure the
  329. // destructor is not [[noreturn]] even if this is always FATAL as this is only
  330. // invoked when DLOG() is enabled.
  331. LogMessageQuietlyDebugFatal(const char* file, int line) ABSL_ATTRIBUTE_COLD;
  332. ~LogMessageQuietlyDebugFatal();
  333. };
  334. // Used for LOG(QFATAL) to make sure it's properly understood as [[noreturn]].
  335. class LogMessageQuietlyFatal final : public LogMessage {
  336. public:
  337. LogMessageQuietlyFatal(const char* file, int line) ABSL_ATTRIBUTE_COLD;
  338. LogMessageQuietlyFatal(const char* file, int line,
  339. absl::string_view failure_msg) ABSL_ATTRIBUTE_COLD;
  340. [[noreturn]] ~LogMessageQuietlyFatal();
  341. };
  342. } // namespace log_internal
  343. ABSL_NAMESPACE_END
  344. } // namespace absl
  345. extern "C" ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(
  346. AbslInternalOnFatalLogMessage)(const absl::LogEntry&);
  347. #endif // ABSL_LOG_INTERNAL_LOG_MESSAGE_H_