| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #ifndef ABSL_LOG_INTERNAL_LOG_MESSAGE_H_ |
| #define ABSL_LOG_INTERNAL_LOG_MESSAGE_H_ |
|
|
| #include <ios> |
| #include <memory> |
| #include <ostream> |
| #include <streambuf> |
| #include <string> |
|
|
| #include "absl/base/attributes.h" |
| #include "absl/base/config.h" |
| #include "absl/base/internal/errno_saver.h" |
| #include "absl/base/log_severity.h" |
| #include "absl/log/internal/nullguard.h" |
| #include "absl/log/log_entry.h" |
| #include "absl/log/log_sink.h" |
| #include "absl/strings/has_absl_stringify.h" |
| #include "absl/strings/string_view.h" |
| #include "absl/time/time.h" |
|
|
| namespace absl { |
| ABSL_NAMESPACE_BEGIN |
| namespace log_internal { |
| constexpr int kLogMessageBufferSize = 15000; |
|
|
| class LogMessage { |
| public: |
| struct InfoTag {}; |
| struct WarningTag {}; |
| struct ErrorTag {}; |
|
|
| |
| LogMessage(const char* file, int line, |
| absl::LogSeverity severity) ABSL_ATTRIBUTE_COLD; |
| |
| |
| LogMessage(const char* file, int line, |
| InfoTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE; |
| LogMessage(const char* file, int line, |
| WarningTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE; |
| LogMessage(const char* file, int line, |
| ErrorTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE; |
| LogMessage(const LogMessage&) = delete; |
| LogMessage& operator=(const LogMessage&) = delete; |
| ~LogMessage() ABSL_ATTRIBUTE_COLD; |
|
|
| |
| |
| LogMessage& AtLocation(absl::string_view file, int line); |
| |
| |
| LogMessage& NoPrefix(); |
| |
| |
| |
| |
| |
| |
| |
| LogMessage& WithVerbosity(int verbose_level); |
| |
| LogMessage& WithTimestamp(absl::Time timestamp); |
| |
| LogMessage& WithThreadID(absl::LogEntry::tid_t tid); |
| |
| LogMessage& WithMetadataFrom(const absl::LogEntry& entry); |
| |
| |
| |
| LogMessage& WithPerror(); |
| |
| |
| LogMessage& ToSinkAlso(absl::LogSink* sink); |
| |
| LogMessage& ToSinkOnly(absl::LogSink* sink); |
|
|
| |
| LogMessage& InternalStream() { return *this; } |
|
|
| |
| |
| |
| |
| LogMessage& operator<<(char v) { return operator<< <char>(v); } |
| LogMessage& operator<<(signed char v) { return operator<< <signed char>(v); } |
| LogMessage& operator<<(unsigned char v) { |
| return operator<< <unsigned char>(v); |
| } |
| LogMessage& operator<<(signed short v) { |
| return operator<< <signed short>(v); |
| } |
| LogMessage& operator<<(signed int v) { return operator<< <signed int>(v); } |
| LogMessage& operator<<(signed long v) { |
| return operator<< <signed long>(v); |
| } |
| LogMessage& operator<<(signed long long v) { |
| return operator<< <signed long long>(v); |
| } |
| LogMessage& operator<<(unsigned short v) { |
| return operator<< <unsigned short>(v); |
| } |
| LogMessage& operator<<(unsigned int v) { |
| return operator<< <unsigned int>(v); |
| } |
| LogMessage& operator<<(unsigned long v) { |
| return operator<< <unsigned long>(v); |
| } |
| LogMessage& operator<<(unsigned long long v) { |
| return operator<< <unsigned long long>(v); |
| } |
| LogMessage& operator<<(void* v) { return operator<< <void*>(v); } |
| LogMessage& operator<<(const void* v) { return operator<< <const void*>(v); } |
| LogMessage& operator<<(float v) { return operator<< <float>(v); } |
| LogMessage& operator<<(double v) { return operator<< <double>(v); } |
| LogMessage& operator<<(bool v) { return operator<< <bool>(v); } |
| |
|
|
| |
| LogMessage& operator<<(const std::string& v); |
| LogMessage& operator<<(absl::string_view v); |
|
|
| |
| LogMessage& operator<<(std::ostream& (*m)(std::ostream& os)); |
| LogMessage& operator<<(std::ios_base& (*m)(std::ios_base& os)); |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| template <int SIZE> |
| LogMessage& operator<<(const char (&buf)[SIZE]); |
|
|
| |
| template <int SIZE> |
| LogMessage& operator<<(char (&buf)[SIZE]) ABSL_ATTRIBUTE_NOINLINE; |
|
|
| |
| template <typename T, |
| typename std::enable_if<absl::HasAbslStringify<T>::value, |
| int>::type = 0> |
| LogMessage& operator<<(const T& v) ABSL_ATTRIBUTE_NOINLINE; |
|
|
| |
| |
| template <typename T, |
| typename std::enable_if<!absl::HasAbslStringify<T>::value, |
| int>::type = 0> |
| LogMessage& operator<<(const T& v) ABSL_ATTRIBUTE_NOINLINE; |
|
|
| |
| |
|
|
| protected: |
| |
| |
| ABSL_ATTRIBUTE_NORETURN static void FailWithoutStackTrace(); |
|
|
| |
| |
| ABSL_ATTRIBUTE_NORETURN static void FailQuietly(); |
|
|
| |
| |
| |
| void Flush(); |
|
|
| |
| |
| void SetFailQuietly(); |
|
|
| private: |
| struct LogMessageData; |
| friend class AsLiteralImpl; |
| friend class StringifySink; |
|
|
| |
| |
| |
| |
| |
| 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(); |
|
|
| private: |
| LogMessageData& data_; |
| absl::Span<char> encoded_remaining_copy_; |
| absl::Span<char> message_start_; |
| absl::Span<char> string_start_; |
| }; |
|
|
| enum class StringType { |
| kLiteral, |
| kNotLiteral, |
| }; |
| template <StringType str_type> |
| void CopyToEncodedBuffer(absl::string_view str) ABSL_ATTRIBUTE_NOINLINE; |
| template <StringType str_type> |
| void CopyToEncodedBuffer(char ch, size_t num) ABSL_ATTRIBUTE_NOINLINE; |
|
|
| |
| bool IsFatal() const; |
|
|
| |
| void PrepareToDie(); |
| void Die(); |
|
|
| void SendToLog(); |
|
|
| |
| void LogBacktraceIfNeeded(); |
|
|
| |
| |
| |
| absl::base_internal::ErrnoSaver errno_saver_; |
|
|
| |
| |
| std::unique_ptr<LogMessageData> data_; |
| }; |
|
|
| |
| class StringifySink final { |
| public: |
| explicit StringifySink(LogMessage& message) : message_(message) {} |
|
|
| void Append(size_t count, char ch) { |
| message_.CopyToEncodedBuffer<LogMessage::StringType::kNotLiteral>(ch, |
| count); |
| } |
|
|
| void Append(absl::string_view v) { |
| message_.CopyToEncodedBuffer<LogMessage::StringType::kNotLiteral>(v); |
| } |
|
|
| |
| friend void AbslFormatFlush(StringifySink* sink, absl::string_view v) { |
| sink->Append(v); |
| } |
|
|
| private: |
| LogMessage& message_; |
| }; |
|
|
| |
| template <typename T, |
| typename std::enable_if<absl::HasAbslStringify<T>::value, int>::type> |
| LogMessage& LogMessage::operator<<(const T& v) { |
| StringifySink sink(*this); |
| |
| AbslStringify(sink, v); |
| return *this; |
| } |
|
|
| |
| template <typename T, |
| typename std::enable_if<!absl::HasAbslStringify<T>::value, int>::type> |
| LogMessage& LogMessage::operator<<(const T& v) { |
| OstreamView view(*data_); |
| view.stream() << log_internal::NullGuard<T>().Guard(v); |
| return *this; |
| } |
|
|
| template <int SIZE> |
| LogMessage& LogMessage::operator<<(const char (&buf)[SIZE]) { |
| CopyToEncodedBuffer<StringType::kLiteral>(buf); |
| return *this; |
| } |
|
|
| |
| template <int SIZE> |
| LogMessage& LogMessage::operator<<(char (&buf)[SIZE]) { |
| CopyToEncodedBuffer<StringType::kNotLiteral>(buf); |
| return *this; |
| } |
| |
| |
| |
| extern template LogMessage& LogMessage::operator<<(const char& v); |
| extern template LogMessage& LogMessage::operator<<(const signed char& v); |
| extern template LogMessage& LogMessage::operator<<(const unsigned char& v); |
| extern template LogMessage& LogMessage::operator<<(const short& v); |
| extern template LogMessage& LogMessage::operator<<( |
| const unsigned short& v); |
| extern template LogMessage& LogMessage::operator<<(const int& v); |
| extern template LogMessage& LogMessage::operator<<( |
| const unsigned int& v); |
| extern template LogMessage& LogMessage::operator<<(const long& v); |
| extern template LogMessage& LogMessage::operator<<( |
| const unsigned long& v); |
| extern template LogMessage& LogMessage::operator<<( |
| const long long& v); |
| extern template LogMessage& LogMessage::operator<<( |
| const unsigned long long& v); |
| extern template LogMessage& LogMessage::operator<<(void* const& v); |
| extern template LogMessage& LogMessage::operator<<(const void* const& v); |
| extern template LogMessage& LogMessage::operator<<(const float& v); |
| extern template LogMessage& LogMessage::operator<<(const double& v); |
| extern template LogMessage& LogMessage::operator<<(const bool& v); |
|
|
| extern template void LogMessage::CopyToEncodedBuffer< |
| LogMessage::StringType::kLiteral>(absl::string_view str); |
| extern template void LogMessage::CopyToEncodedBuffer< |
| LogMessage::StringType::kNotLiteral>(absl::string_view str); |
| extern template void |
| LogMessage::CopyToEncodedBuffer<LogMessage::StringType::kLiteral>(char ch, |
| size_t num); |
| extern template void LogMessage::CopyToEncodedBuffer< |
| LogMessage::StringType::kNotLiteral>(char ch, size_t num); |
|
|
| |
| |
| class LogMessageFatal final : public LogMessage { |
| public: |
| LogMessageFatal(const char* file, int line) ABSL_ATTRIBUTE_COLD; |
| LogMessageFatal(const char* file, int line, |
| absl::string_view failure_msg) ABSL_ATTRIBUTE_COLD; |
| ABSL_ATTRIBUTE_NORETURN ~LogMessageFatal(); |
| }; |
|
|
| class LogMessageQuietlyFatal final : public LogMessage { |
| public: |
| LogMessageQuietlyFatal(const char* file, int line) ABSL_ATTRIBUTE_COLD; |
| LogMessageQuietlyFatal(const char* file, int line, |
| absl::string_view failure_msg) ABSL_ATTRIBUTE_COLD; |
| ABSL_ATTRIBUTE_NORETURN ~LogMessageQuietlyFatal(); |
| }; |
|
|
| } |
| ABSL_NAMESPACE_END |
| } |
|
|
| extern "C" ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL( |
| AbslInternalOnFatalLogMessage)(const absl::LogEntry&); |
|
|
| #endif |
|
|