log_message.h 17 KB

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