/src/abseil-cpp/absl/log/log_entry.h
Line  | Count  | Source (jump to first uncovered line)  | 
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.  | 
75  | 0  |   absl::string_view source_filename() const ABSL_ATTRIBUTE_LIFETIME_BOUND { | 
76  | 0  |     return full_filename_;  | 
77  | 0  |   }  | 
78  | 3.24M  |   absl::string_view source_basename() const ABSL_ATTRIBUTE_LIFETIME_BOUND { | 
79  | 3.24M  |     return base_filename_;  | 
80  | 3.24M  |   }  | 
81  | 3.24M  |   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()`.  | 
88  | 3.24M  |   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`.  | 
94  | 22.6M  |   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.  | 
100  | 0  |   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).  | 
111  | 3.24M  |   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.  | 
120  | 3.24M  |   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.  | 
144  |  |   absl::string_view text_message_with_prefix_and_newline() const  | 
145  | 3.24M  |       ABSL_ATTRIBUTE_LIFETIME_BOUND { | 
146  | 3.24M  |     return absl::string_view(  | 
147  | 3.24M  |         text_message_with_prefix_and_newline_and_nul_.data(),  | 
148  | 3.24M  |         text_message_with_prefix_and_newline_and_nul_.size() - 1);  | 
149  | 3.24M  |   }  | 
150  |  |   absl::string_view text_message_with_prefix() const  | 
151  | 0  |       ABSL_ATTRIBUTE_LIFETIME_BOUND { | 
152  | 0  |     return absl::string_view(  | 
153  | 0  |         text_message_with_prefix_and_newline_and_nul_.data(),  | 
154  | 0  |         text_message_with_prefix_and_newline_and_nul_.size() - 2);  | 
155  | 0  |   }  | 
156  |  |   absl::string_view text_message_with_newline() const  | 
157  | 0  |       ABSL_ATTRIBUTE_LIFETIME_BOUND { | 
158  | 0  |     return absl::string_view(  | 
159  | 0  |         text_message_with_prefix_and_newline_and_nul_.data() + prefix_len_,  | 
160  | 0  |         text_message_with_prefix_and_newline_and_nul_.size() - prefix_len_ - 1);  | 
161  | 0  |   }  | 
162  | 0  |   absl::string_view text_message() const ABSL_ATTRIBUTE_LIFETIME_BOUND { | 
163  | 0  |     return absl::string_view(  | 
164  | 0  |         text_message_with_prefix_and_newline_and_nul_.data() + prefix_len_,  | 
165  | 0  |         text_message_with_prefix_and_newline_and_nul_.size() - prefix_len_ - 2);  | 
166  | 0  |   }  | 
167  |  |   const char* text_message_with_prefix_and_newline_c_str() const  | 
168  | 0  |       ABSL_ATTRIBUTE_LIFETIME_BOUND { | 
169  | 0  |     return text_message_with_prefix_and_newline_and_nul_.data();  | 
170  | 0  |   }  | 
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.  | 
177  | 0  |   absl::string_view encoded_message() const ABSL_ATTRIBUTE_LIFETIME_BOUND { | 
178  | 0  |     return encoding_;  | 
179  | 0  |   }  | 
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.  | 
193  | 3.24M  |   absl::string_view stacktrace() const ABSL_ATTRIBUTE_LIFETIME_BOUND { | 
194  | 3.24M  |     return stacktrace_;  | 
195  | 3.24M  |   }  | 
196  |  |  | 
197  |  |  private:  | 
198  | 3.24M  |   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_  |