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. Taken from the argument to `VLOG` or from 100 // `LOG(...).WithVerbosity(...)`. verbosity()101 int verbosity() const { return verbose_level_; } 102 103 // LogEntry::timestamp() 104 // 105 // Returns the time at which this entry was written. Captured during 106 // evaluation of `LOG`, but can be overridden by 107 // `LOG(...).WithTimestamp(...)`. 108 // 109 // Take care not to rely on timestamps increasing monotonically, or even to 110 // rely on timestamps having any particular relationship with reality (since 111 // they can be overridden). timestamp()112 absl::Time timestamp() const { return timestamp_; } 113 114 // LogEntry::tid() 115 // 116 // Returns the ID of the thread that wrote this entry. Captured during 117 // evaluation of `LOG`, but can be overridden by `LOG(...).WithThreadID(...)`. 118 // 119 // Take care not to *rely* on reported thread IDs as they can be overridden as 120 // specified above. tid()121 tid_t tid() const { return tid_; } 122 123 // Text-formatted version of the log message. An underlying buffer holds 124 // these contiguous data: 125 // 126 // * A prefix formed by formatting metadata (timestamp, filename, line number, 127 // etc.) 128 // The prefix may be empty - see `LogEntry::prefix()` - and may rarely be 129 // truncated if the metadata are very long. 130 // * The streamed data 131 // The data may be empty if nothing was streamed, or may be truncated to fit 132 // the buffer. 133 // * A newline 134 // * A nul terminator 135 // 136 // The newline and nul terminator will be present even if the prefix and/or 137 // data are truncated. 138 // 139 // These methods give access to the most commonly useful substrings of the 140 // buffer's contents. Other combinations can be obtained with substring 141 // arithmetic. 142 // 143 // The buffer does not outlive the entry; if you need the data later, you must 144 // copy them. text_message_with_prefix_and_newline()145 absl::string_view text_message_with_prefix_and_newline() const 146 ABSL_ATTRIBUTE_LIFETIME_BOUND { 147 return absl::string_view( 148 text_message_with_prefix_and_newline_and_nul_.data(), 149 text_message_with_prefix_and_newline_and_nul_.size() - 1); 150 } text_message_with_prefix()151 absl::string_view text_message_with_prefix() const 152 ABSL_ATTRIBUTE_LIFETIME_BOUND { 153 return absl::string_view( 154 text_message_with_prefix_and_newline_and_nul_.data(), 155 text_message_with_prefix_and_newline_and_nul_.size() - 2); 156 } text_message_with_newline()157 absl::string_view text_message_with_newline() const 158 ABSL_ATTRIBUTE_LIFETIME_BOUND { 159 return absl::string_view( 160 text_message_with_prefix_and_newline_and_nul_.data() + prefix_len_, 161 text_message_with_prefix_and_newline_and_nul_.size() - prefix_len_ - 1); 162 } text_message()163 absl::string_view text_message() const ABSL_ATTRIBUTE_LIFETIME_BOUND { 164 return absl::string_view( 165 text_message_with_prefix_and_newline_and_nul_.data() + prefix_len_, 166 text_message_with_prefix_and_newline_and_nul_.size() - prefix_len_ - 2); 167 } text_message_with_prefix_and_newline_c_str()168 const char* text_message_with_prefix_and_newline_c_str() const 169 ABSL_ATTRIBUTE_LIFETIME_BOUND { 170 return text_message_with_prefix_and_newline_and_nul_.data(); 171 } 172 173 // Returns a serialized protobuf holding the operands streamed into this 174 // log message. The message definition is not yet published. 175 // 176 // The buffer does not outlive the entry; if you need the data later, you must 177 // copy them. encoded_message()178 absl::string_view encoded_message() const ABSL_ATTRIBUTE_LIFETIME_BOUND { 179 return encoding_; 180 } 181 182 // LogEntry::stacktrace() 183 // 184 // Optional stacktrace, e.g. for `FATAL` logs and failed `CHECK`s. 185 // 186 // Fatal entries are dispatched to each sink twice: first with all data and 187 // metadata but no stacktrace, and then with the stacktrace. This is done 188 // because stacktrace collection is sometimes slow and fallible, and it's 189 // critical to log enough information to diagnose the failure even if the 190 // stacktrace collection hangs. 191 // 192 // The buffer does not outlive the entry; if you need the data later, you must 193 // copy them. stacktrace()194 absl::string_view stacktrace() const ABSL_ATTRIBUTE_LIFETIME_BOUND { 195 return stacktrace_; 196 } 197 198 private: 199 LogEntry() = default; 200 201 absl::string_view full_filename_; 202 absl::string_view base_filename_; 203 int line_; 204 bool prefix_; 205 absl::LogSeverity severity_; 206 int verbose_level_; // >=0 for `VLOG`, etc.; otherwise `kNoVerbosityLevel`. 207 absl::Time timestamp_; 208 tid_t tid_; 209 absl::Span<const char> text_message_with_prefix_and_newline_and_nul_; 210 size_t prefix_len_; 211 absl::string_view encoding_; 212 std::string stacktrace_; 213 214 friend class log_internal::LogEntryTestPeer; 215 friend class log_internal::LogMessage; 216 }; 217 218 ABSL_NAMESPACE_END 219 } // namespace absl 220 221 #endif // ABSL_LOG_LOG_ENTRY_H_ 222