Abseil Common Libraries (C++) (grcp 依赖)
https://abseil.io/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
176 lines
6.1 KiB
176 lines
6.1 KiB
// 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/log_streamer.h |
|
// ----------------------------------------------------------------------------- |
|
// |
|
// This header declares the class `LogStreamer` and convenience functions to |
|
// construct LogStreamer objects with different associated log severity levels. |
|
|
|
#ifndef ABSL_LOG_LOG_STREAMER_H_ |
|
#define ABSL_LOG_LOG_STREAMER_H_ |
|
|
|
#include <ios> |
|
#include <memory> |
|
#include <ostream> |
|
#include <string> |
|
#include <utility> |
|
|
|
#include "absl/base/config.h" |
|
#include "absl/base/log_severity.h" |
|
#include "absl/log/log.h" |
|
#include "absl/memory/memory.h" |
|
#include "absl/strings/internal/ostringstream.h" |
|
#include "absl/strings/string_view.h" |
|
|
|
namespace absl { |
|
ABSL_NAMESPACE_BEGIN |
|
|
|
// LogStreamer |
|
// |
|
// Although you can stream into `LOG(INFO)`, you can't pass it into a function |
|
// that takes a `std::ostream` parameter. `LogStreamer::stream()` provides a |
|
// `std::ostream` that buffers everything that's streamed in. The buffer's |
|
// contents are logged as if by `LOG` when the `LogStreamer` is destroyed. |
|
// If nothing is streamed in, an empty message is logged. If the specified |
|
// severity is `absl::LogSeverity::kFatal`, the program will be terminated when |
|
// the `LogStreamer` is destroyed regardless of whether any data were streamed |
|
// in. |
|
// |
|
// Factory functions corresponding to the `absl::LogSeverity` enumerators |
|
// are provided for convenience; if the desired severity is variable, invoke the |
|
// constructor directly. |
|
// |
|
// LogStreamer is movable, but not copyable. |
|
// |
|
// Examples: |
|
// |
|
// ShaveYakAndWriteToStream( |
|
// yak, absl::LogInfoStreamer(__FILE__, __LINE__).stream()); |
|
// |
|
// { |
|
// // This logs a single line containing data streamed by all three function |
|
// // calls. |
|
// absl::LogStreamer streamer(absl::LogSeverity::kInfo, __FILE__, __LINE__); |
|
// ShaveYakAndWriteToStream(yak1, streamer.stream()); |
|
// streamer.stream() << " "; |
|
// ShaveYakAndWriteToStream(yak2, streamer.stream()); |
|
// streamer.stream() << " "; |
|
// ShaveYakAndWriteToStreamPointer(yak3, &streamer.stream()); |
|
// } |
|
class LogStreamer final { |
|
public: |
|
// LogStreamer::LogStreamer() |
|
// |
|
// Creates a LogStreamer with a given `severity` that will log a message |
|
// attributed to the given `file` and `line`. |
|
explicit LogStreamer(absl::LogSeverity severity, absl::string_view file, |
|
int line) |
|
: severity_(severity), |
|
line_(line), |
|
file_(file), |
|
stream_( |
|
absl::make_unique<absl::strings_internal::OStringStream>(&buf_)) { |
|
// To match `LOG`'s defaults: |
|
stream_->setf(std::ios_base::showbase | std::ios_base::boolalpha); |
|
} |
|
|
|
// A moved-from `absl::LogStreamer` does not `LOG` when destroyed, |
|
// and a program that streams into one has undefined behavior. |
|
LogStreamer(LogStreamer&& that) noexcept |
|
: severity_(that.severity_), |
|
line_(that.line_), |
|
file_(std::move(that.file_)), |
|
buf_(std::move(that.buf_)), |
|
stream_(that.stream_ |
|
? absl::make_unique<absl::strings_internal::OStringStream>( |
|
&buf_) |
|
: nullptr) { |
|
that.stream_.reset(); |
|
} |
|
LogStreamer& operator=(LogStreamer&& that) { |
|
LOG_IF(LEVEL(severity_), stream_).AtLocation(file_, line_) << buf_; |
|
severity_ = that.severity_; |
|
file_ = std::move(that.file_); |
|
line_ = that.line_; |
|
buf_ = std::move(that.buf_); |
|
stream_ = |
|
that.stream_ |
|
? absl::make_unique<absl::strings_internal::OStringStream>(&buf_) |
|
: nullptr; |
|
that.stream_.reset(); |
|
return *this; |
|
} |
|
|
|
// LogStreamer::~LogStreamer() |
|
// |
|
// Logs this LogStreamer's buffered content as if by LOG. |
|
~LogStreamer() { |
|
LOG_IF(LEVEL(severity_), stream_).AtLocation(file_, line_) << buf_; |
|
} |
|
|
|
// LogStreamer::stream() |
|
// |
|
// Returns the `std::ostream` to use to write into this LogStreamer' internal |
|
// buffer. |
|
std::ostream& stream() { return *stream_; } |
|
|
|
private: |
|
absl::LogSeverity severity_; |
|
int line_; |
|
std::string file_; |
|
std::string buf_; |
|
// TODO(durandal): de-pointerize this once we are off of our old mostly-C++11 |
|
// libstdc++ (which lacks move constructors for std streams). |
|
// `stream_` is null in a moved-from `LogStreamer`; this is in fact how we |
|
// recognize one to avoid logging when it is destroyed or reassigned. |
|
std::unique_ptr<absl::strings_internal::OStringStream> stream_; |
|
}; |
|
|
|
// LogInfoStreamer() |
|
// |
|
// Returns a LogStreamer that writes at level LogSeverity::kInfo. |
|
inline LogStreamer LogInfoStreamer(absl::string_view file, int line) { |
|
return absl::LogStreamer(absl::LogSeverity::kInfo, file, line); |
|
} |
|
|
|
// LogWarningStreamer() |
|
// |
|
// Returns a LogStreamer that writes at level LogSeverity::kWarning. |
|
inline LogStreamer LogWarningStreamer(absl::string_view file, int line) { |
|
return absl::LogStreamer(absl::LogSeverity::kWarning, file, line); |
|
} |
|
|
|
// LogErrorStreamer() |
|
// |
|
// Returns a LogStreamer that writes at level LogSeverity::kError. |
|
inline LogStreamer LogErrorStreamer(absl::string_view file, int line) { |
|
return absl::LogStreamer(absl::LogSeverity::kError, file, line); |
|
} |
|
|
|
// LogFatalStreamer() |
|
// |
|
// Returns a LogStreamer that writes at level LogSeverity::kFatal. |
|
// |
|
// The program will be terminated when this `LogStreamer` is destroyed, |
|
// regardless of whether any data were streamed in. |
|
inline LogStreamer LogFatalStreamer(absl::string_view file, int line) { |
|
return absl::LogStreamer(absl::LogSeverity::kFatal, file, line); |
|
} |
|
|
|
ABSL_NAMESPACE_END |
|
} // namespace absl |
|
|
|
#endif // ABSL_LOG_LOG_STREAMER_H_
|
|
|