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 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 // Returns a serialized protobuf holding the operands streamed into this 173 // log message. The message definition is not yet published. 174 // 175 // The buffer does not outlive the entry; if you need the data later, you must 176 // copy them. encoded_message()177 absl::string_view encoded_message() const ABSL_ATTRIBUTE_LIFETIME_BOUND { 178 return encoding_; 179 } 180 181 // LogEntry::stacktrace() 182 // 183 // Optional stacktrace, e.g. for `FATAL` logs and failed `CHECK`s. 184 // 185 // Fatal entries are dispatched to each sink twice: first with all data and 186 // metadata but no stacktrace, and then with the stacktrace. This is done 187 // because stacktrace collection is sometimes slow and fallible, and it's 188 // critical to log enough information to diagnose the failure even if the 189 // stacktrace collection hangs. 190 // 191 // The buffer does not outlive the entry; if you need the data later, you must 192 // copy them. stacktrace()193 absl::string_view stacktrace() const ABSL_ATTRIBUTE_LIFETIME_BOUND { 194 return stacktrace_; 195 } 196 197 private: 198 LogEntry() = default; 199 200 absl::string_view full_filename_; 201 absl::string_view base_filename_; 202 int line_; 203 bool prefix_; 204 absl::LogSeverity severity_; 205 int verbose_level_; // >=0 for `VLOG`, etc.; otherwise `kNoVerbosityLevel`. 206 absl::Time timestamp_; 207 tid_t tid_; 208 absl::Span<const char> text_message_with_prefix_and_newline_and_nul_; 209 size_t prefix_len_; 210 absl::string_view encoding_; 211 std::string stacktrace_; 212 213 friend class log_internal::LogEntryTestPeer; 214 friend class log_internal::LogMessage; 215 }; 216 217 ABSL_NAMESPACE_END 218 } // namespace absl 219 220 #endif // ABSL_LOG_LOG_ENTRY_H_ 221