// Copyright 2022 The Abseil Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // ----------------------------------------------------------------------------- // File: log/internal/log_message.h // ----------------------------------------------------------------------------- // // This file declares `class absl::log_internal::LogMessage`. This class more or // less represents a particular log message. LOG/CHECK macros create a temporary // instance of `LogMessage` and then stream values to it. At the end of the // LOG/CHECK statement, the LogMessage is voidified by operator&&, and `Flush()` // directs the message to the registered log sinks. Heap-allocation of // `LogMessage` is unsupported. Construction outside of a `LOG` macro is // unsupported.
// Used for `LOG`.
LogMessage(absl::Nonnull<constchar*> file, int line,
absl::LogSeverity severity) ABSL_ATTRIBUTE_COLD; // These constructors are slightly smaller/faster to call; the severity is // curried into the function pointer.
LogMessage(absl::Nonnull<constchar*> file, int line,
InfoTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE;
LogMessage(absl::Nonnull<constchar*> file, int line,
WarningTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE;
LogMessage(absl::Nonnull<constchar*> file, int line,
ErrorTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE;
LogMessage(const LogMessage&) = delete;
LogMessage& operator=(const LogMessage&) = delete;
~LogMessage() ABSL_ATTRIBUTE_COLD;
// Overrides the location inferred from the callsite. The string pointed to // by `file` must be valid until the end of the statement.
LogMessage& AtLocation(absl::string_view file, int line); // Omits the prefix from this line. The prefix includes metadata about the // logged data such as source code location and timestamp.
LogMessage& NoPrefix(); // Sets the verbosity field of the logged message as if it was logged by // `VLOG(verbose_level)`. Unlike `VLOG`, this method does not affect // evaluation of the statement when the specified `verbose_level` has been // disabled. The only effect is on `absl::LogSink` implementations which // make use of the `absl::LogSink::verbosity()` value. The value // `absl::LogEntry::kNoVerbosityLevel` can be specified to mark the message // not verbose.
LogMessage& WithVerbosity(int verbose_level); // Uses the specified timestamp instead of one collected in the constructor.
LogMessage& WithTimestamp(absl::Time timestamp); // Uses the specified thread ID instead of one collected in the constructor.
LogMessage& WithThreadID(absl::LogEntry::tid_t tid); // Copies all metadata (but no data) from the specified `absl::LogEntry`.
LogMessage& WithMetadataFrom(const absl::LogEntry& entry); // Appends to the logged message a colon, a space, a textual description of // the current value of `errno` (as by strerror(3)), and the numerical value // of `errno`.
LogMessage& WithPerror(); // Sends this message to `*sink` in addition to whatever other sinks it would // otherwise have been sent to.
LogMessage& ToSinkAlso(absl::Nonnull<absl::LogSink*> sink); // Sends this message to `*sink` and no others.
LogMessage& ToSinkOnly(absl::Nonnull<absl::LogSink*> sink);
// Don't call this method from outside this library.
LogMessage& InternalStream() { return *this; }
// These overloads are more efficient since no `ostream` is involved.
LogMessage& operator<<(const std::string& v);
LogMessage& operator<<(absl::string_view v);
// Literal strings. This allows us to record C string literals as literals in // the logging.proto.Value. // // Allow this overload to be inlined to prevent generating instantiations of // this template for every value of `SIZE` encountered in each source code // file. That significantly increases linker input sizes. Inlining is cheap // because the argument to this overload is almost always a string literal so // the call to `strlen` can be replaced at compile time. The overload for // `char[]` below should not be inlined. The compiler typically does not have // the string at compile time and cannot replace the call to `strlen` so // inlining it increases the binary size. See the discussion on // cl/107527369. template <int SIZE>
LogMessage& operator<<(constchar (&buf)[SIZE]);
// This prevents non-const `char[]` arrays from looking like literals. template <int SIZE>
LogMessage& operator<<(char (&buf)[SIZE]) ABSL_ATTRIBUTE_NOINLINE;
// Types that support `AbslStringify()` are serialized that way. // Types that don't support `AbslStringify()` but do support streaming into a // `std::ostream&` are serialized that way. template <typename T>
LogMessage& operator<<(const T& v) ABSL_ATTRIBUTE_NOINLINE;
// Dispatches the completed `absl::LogEntry` to applicable `absl::LogSink`s. void Flush();
// Note: We explicitly do not support `operator<<` for non-const references // because it breaks logging of non-integer bitfield types (i.e., enums).
protected: // Call `abort()` or similar to perform `LOG(FATAL)` crash. It is assumed // that the caller has already generated and written the trace as appropriate.
[[noreturn]] staticvoid FailWithoutStackTrace();
// Similar to `FailWithoutStackTrace()`, but without `abort()`. Terminates // the process with an error exit code.
[[noreturn]] staticvoid FailQuietly();
// After this is called, failures are done as quiet as possible for this log // message. void SetFailQuietly();
// This streambuf writes directly into the structured logging buffer so that // arbitrary types can be encoded as string data (using // `operator<<(std::ostream &, ...)` without any extra allocation or copying. // Space is reserved before the data to store the length field, which is // filled in by `~OstreamView`. class OstreamView final : public std::streambuf {
public: explicit OstreamView(LogMessageData& message_data);
~OstreamView() override;
OstreamView(const OstreamView&) = delete;
OstreamView& operator=(const OstreamView&) = delete;
std::ostream& stream();
// Copies `field` to the encoded buffer, then appends `str` after it // (truncating `str` if necessary to fit). template <StringType str_type> void CopyToEncodedBufferWithStructuredProtoField(StructuredProtoField field,
absl::string_view str)
ABSL_ATTRIBUTE_NOINLINE;
// Returns `true` if the message is fatal or enabled debug-fatal. bool IsFatal() const;
// Records some tombstone-type data in anticipation of `Die`. void PrepareToDie(); void Die();
void SendToLog();
// Checks `FLAGS_log_backtrace_at` and appends a backtrace if appropriate. void LogBacktraceIfNeeded();
// This should be the first data member so that its initializer captures errno // before any other initializers alter it (e.g. with calls to new) and so that // no other destructors run afterward an alter it (e.g. with calls to delete).
absl::base_internal::ErrnoSaver errno_saver_;
// We keep the data in a separate struct so that each instance of `LogMessage` // uses less stack space.
absl::Nonnull<std::unique_ptr<LogMessageData>> data_;
};
// Helper class so that `AbslStringify()` can modify the LogMessage. class StringifySink final {
public: explicit StringifySink(LogMessage& message) : message_(message) {}
// `LogMessageFatal` ensures the process will exit in failure after logging this // message. class LogMessageFatal final : public LogMessage {
public:
LogMessageFatal(absl::Nonnull<constchar*> file, int line) ABSL_ATTRIBUTE_COLD;
LogMessageFatal(absl::Nonnull<constchar*> file, int line,
absl::Nonnull<constchar*> failure_msg) ABSL_ATTRIBUTE_COLD;
[[noreturn]] ~LogMessageFatal();
};
// `LogMessageDebugFatal` ensures the process will exit in failure after logging // this message. It matches LogMessageFatal but is not [[noreturn]] as it's used // for DLOG(FATAL) variants. class LogMessageDebugFatal final : public LogMessage {
public:
LogMessageDebugFatal(absl::Nonnull<constchar*> file, int line) ABSL_ATTRIBUTE_COLD;
~LogMessageDebugFatal();
};
class LogMessageQuietlyDebugFatal final : public LogMessage {
public: // DLOG(QFATAL) calls this instead of LogMessageQuietlyFatal to make sure the // destructor is not [[noreturn]] even if this is always FATAL as this is only // invoked when DLOG() is enabled.
LogMessageQuietlyDebugFatal(absl::Nonnull<constchar*> file, int line) ABSL_ATTRIBUTE_COLD;
~LogMessageQuietlyDebugFatal();
};
// Used for LOG(QFATAL) to make sure it's properly understood as [[noreturn]]. class LogMessageQuietlyFatal final : public LogMessage {
public:
LogMessageQuietlyFatal(absl::Nonnull<constchar*> file, int line) ABSL_ATTRIBUTE_COLD;
LogMessageQuietlyFatal(absl::Nonnull<constchar*> file, int line,
absl::Nonnull<constchar*> failure_msg)
ABSL_ATTRIBUTE_COLD;
[[noreturn]] ~LogMessageQuietlyFatal();
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.