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/log_entry.h 17 // ----------------------------------------------------------------------------- 18 // 19 // This header declares `class absl::LogEntry`, which represents a log record as 20 // passed to `LogSink::Send`. Data returned by pointer or by reference or by 21 // `absl::string_view` must be copied if they are needed after the lifetime of 22 // the `absl::LogEntry`. 23 24 #ifndef ABSL_LOG_LOG_ENTRY_H_ 25 #define ABSL_LOG_LOG_ENTRY_H_ 26 27 #include <cstddef> 28 #include <string> 29 30 #include "absl/base/attributes.h" 31 #include "absl/base/config.h" 32 #include "absl/base/log_severity.h" 33 #include "absl/log/internal/config.h" 34 #include "absl/strings/string_view.h" 35 #include "absl/time/time.h" 36 #include "absl/types/span.h" 37 38 namespace absl { 39 ABSL_NAMESPACE_BEGIN 40 41 namespace log_internal { 42 // Test only friend. 43 class LogEntryTestPeer; 44 class LogMessage; 45 } // namespace log_internal 46 47 // LogEntry 48 // 49 // Represents a single entry in a log, i.e., one `LOG` statement or failed 50 // `CHECK`. 51 // 52 // `LogEntry` is copyable and thread-compatible. 53 class LogEntry final { 54 public: 55 using tid_t = log_internal::Tid; 56 57 // For non-verbose log entries, `verbosity()` returns `kNoVerbosityLevel`. 58 static constexpr int kNoVerbosityLevel = -1; 59 static constexpr int kNoVerboseLevel = -1; // TO BE removed 60 61 // Pass `LogEntry` by reference, and do not store it as its state does not 62 // outlive the call to `LogSink::Send()`. 63 LogEntry(const LogEntry&) = delete; 64 LogEntry& operator=(const LogEntry&) = delete; 65 66 // Source file and line where the log message occurred. Taken from `__FILE__` 67 // and `__LINE__` unless overridden by `LOG(...).AtLocation(...)`. 68 // 69 // Take special care not to use the values returned by `source_filename()` and 70 // `source_basename()` after the lifetime of the entry. This is always 71 // incorrect, but it will often work in practice because they usually point 72 // into a statically allocated character array obtained from `__FILE__`. 73 // Statements like `LOG(INFO).AtLocation(std::string(...), ...)` will expose 74 // the bug. If you need the data later, you must copy them. source_filename()75 absl::string_view source_filename() const ABSL_ATTRIBUTE_LIFETIME_BOUND { 76 return full_filename_; 77 } source_basename()78 absl::string_view source_basename() const ABSL_ATTRIBUTE_LIFETIME_BOUND { 79 return base_filename_; 80 } source_line()81 int source_line() const { return line_; } 82 83 // LogEntry::prefix() 84 // 85 // True unless the metadata prefix was suppressed once by 86 // `LOG(...).NoPrefix()` or globally by `absl::EnableLogPrefix(false)`. 87 // Implies `text_message_with_prefix() == text_message()`. prefix()88 bool prefix() const { return prefix_; } 89 90 // LogEntry::log_severity() 91 // 92 // Returns this entry's severity. For `LOG`, taken from the first argument; 93 // for `CHECK`, always `absl::LogSeverity::kFatal`. log_severity()94 absl::LogSeverity log_severity() const { return severity_; } 95 96 // LogEntry::verbosity() 97 // 98 // Returns this entry's verbosity, or `kNoVerbosityLevel` for a non-verbose 99 // entry. Verbosity control is not available outside of Google yet. verbosity()100 int verbosity() const { return verbose_level_; } 101 102 // LogEntry::timestamp() 103 // 104 // Returns the time at which this entry was written. Captured during 105 // evaluation of `LOG`, but can be overridden by 106 // `LOG(...).WithTimestamp(...)`. 107 // 108 // Take care not to rely on timestamps increasing monotonically, or even to 109 // rely on timestamps having any particular relationship with reality (since 110 // they can be overridden). timestamp()111 absl::Time timestamp() const { return timestamp_; } 112 113 // LogEntry::tid() 114 // 115 // Returns the ID of the thread that wrote this entry. Captured during 116 // evaluation of `LOG`, but can be overridden by `LOG(...).WithThreadID(...)`. 117 // 118 // Take care not to *rely* on reported thread IDs as they can be overridden as 119 // specified above. tid()120 tid_t tid() const { return tid_; } 121 122 // Text-formatted version of the log message. An underlying buffer holds 123 // these contiguous data: 124 // 125 // * A prefix formed by formatting metadata (timestamp, filename, line number, 126 // etc.) 127 // The prefix may be empty - see `LogEntry::prefix()` - and may rarely be 128 // truncated if the metadata are very long. 129 // * The streamed data 130 // The data may be empty if nothing was streamed, or may be truncated to fit 131 // the buffer. 132 // * A newline 133 // * A nul terminator 134 // 135 // The newline and nul terminator will be present even if the prefix and/or 136 // data are truncated. 137 // 138 // These methods give access to the most commonly useful substrings of the 139 // buffer's contents. Other combinations can be obtained with substring 140 // arithmetic. 141 // 142 // The buffer does not outlive the entry; if you need the data later, you must 143 // copy them. text_message_with_prefix_and_newline()144 absl::string_view text_message_with_prefix_and_newline() const 145 ABSL_ATTRIBUTE_LIFETIME_BOUND { 146 return absl::string_view( 147 text_message_with_prefix_and_newline_and_nul_.data(), 148 text_message_with_prefix_and_newline_and_nul_.size() - 1); 149 } text_message_with_prefix()150 absl::string_view text_message_with_prefix() const 151 ABSL_ATTRIBUTE_LIFETIME_BOUND { 152 return absl::string_view( 153 text_message_with_prefix_and_newline_and_nul_.data(), 154 text_message_with_prefix_and_newline_and_nul_.size() - 2); 155 } text_message_with_newline()156 absl::string_view text_message_with_newline() const 157 ABSL_ATTRIBUTE_LIFETIME_BOUND { 158 return absl::string_view( 159 text_message_with_prefix_and_newline_and_nul_.data() + prefix_len_, 160 text_message_with_prefix_and_newline_and_nul_.size() - prefix_len_ - 1); 161 } text_message()162 absl::string_view text_message() const ABSL_ATTRIBUTE_LIFETIME_BOUND { 163 return absl::string_view( 164 text_message_with_prefix_and_newline_and_nul_.data() + prefix_len_, 165 text_message_with_prefix_and_newline_and_nul_.size() - prefix_len_ - 2); 166 } text_message_with_prefix_and_newline_c_str()167 const char* text_message_with_prefix_and_newline_c_str() const 168 ABSL_ATTRIBUTE_LIFETIME_BOUND { 169 return text_message_with_prefix_and_newline_and_nul_.data(); 170 } 171 172 // LogEntry::stacktrace() 173 // 174 // Optional stacktrace, e.g. for `FATAL` logs and failed `CHECK`s. 175 // 176 // Fatal entries are dispatched to each sink twice: first with all data and 177 // metadata but no stacktrace, and then with the stacktrace. This is done 178 // because stacktrace collection is sometimes slow and fallible, and it's 179 // critical to log enough information to diagnose the failure even if the 180 // stacktrace collection hangs. 181 // 182 // The buffer does not outlive the entry; if you need the data later, you must 183 // copy them. stacktrace()184 absl::string_view stacktrace() const ABSL_ATTRIBUTE_LIFETIME_BOUND { 185 return stacktrace_; 186 } 187 188 private: 189 LogEntry() = default; 190 191 absl::string_view full_filename_; 192 absl::string_view base_filename_; 193 int line_; 194 bool prefix_; 195 absl::LogSeverity severity_; 196 int verbose_level_; // >=0 for `VLOG`, etc.; otherwise `kNoVerbosityLevel`. 197 absl::Time timestamp_; 198 tid_t tid_; 199 absl::Span<const char> text_message_with_prefix_and_newline_and_nul_; 200 size_t prefix_len_; 201 std::string stacktrace_; 202 203 friend class log_internal::LogEntryTestPeer; 204 friend class log_internal::LogMessage; 205 }; 206 207 ABSL_NAMESPACE_END 208 } // namespace absl 209 210 #endif // ABSL_LOG_LOG_ENTRY_H_ 211