xref: /aosp_15_r20/external/abseil-cpp/absl/log/log_entry.h (revision 9356374a3709195abf420251b3e825997ff56c0f)
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