blob: 5883a2f99f8d5a3f76436cb29ac9c97f9240721b [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_LEDGER_LIB_LOGGING_LOGGING_H_
#define SRC_LEDGER_LIB_LOGGING_LOGGING_H_
#include <iostream>
#include <sstream>
#include "third_party/abseil-cpp/absl/base/log_severity.h"
namespace ledger {
// Transforms a std::ostream result into a boolean with the right priority.
class LogIgnoreStream {
public:
bool operator&(const std::ostream&) { return true; }
};
// Holds a stream and a severity, prints it on destruction.
class LogMessage {
public:
// Starts a new log message. It will be printed on destruction. |severity| is the severity of the
// message, |file| must point to a null-terminated string containing the name of the file where
// the error occured, at line |line|. |condition| is an optional string containing the condition
// used for CHECK/DCHECK.
LogMessage(absl::LogSeverity severity, const char* file, int line, const char* condition);
~LogMessage();
// Returns the underlying stream.
std::ostream& stream();
private:
// Stream that accumulates the error message.
std::ostringstream stream_;
// Should we abort after printing the error message?
bool fatal_;
};
// Sets the minimal log severity at which messages are printed. Negative numbers are used for
// verbose logging.
void SetLogSeverity(absl::LogSeverity severity);
// Sets the maximal log verbosity: all non-verbose messages are printed as well as all verbose
// messages whose verbosity is below or equal |verbosity|.
void SetLogVerbosity(int verbosity);
// Returns the current minimum log severity, or |LogSeverity::kInfo| by default.
absl::LogSeverity GetLogSeverity();
} // namespace ledger
// Macros for log severities.
#define LEDGER_LOGGING_INTERNAL_INFO ::absl::LogSeverity::kInfo
#define LEDGER_LOGGING_INTERNAL_WARNING ::absl::LogSeverity::kWarning
#define LEDGER_LOGGING_INTERNAL_ERROR ::absl::LogSeverity::kError
#define LEDGER_LOGGING_INTERNAL_FATAL ::absl::LogSeverity::kFatal
#define LEDGER_LOG_CONDITIONAL(level, enabled, condition, condition_str) \
!(enabled) || (level) < ::ledger::GetLogSeverity() || (condition) || \
::ledger::LogIgnoreStream() & \
::ledger::LogMessage((level), __FILE__, __LINE__, (condition_str)).stream()
// Logs a message at severity |LOG_level|. If |level| is FATAL, aborts after printing.
#define LEDGER_LOG(level) \
LEDGER_LOG_CONDITIONAL(LEDGER_LOGGING_INTERNAL_##level, true, false, nullptr)
// Logs a message at verbosity level |level|.
#define LEDGER_VLOG(level) \
LEDGER_LOG_CONDITIONAL((::absl::LogSeverity) - (level), true, false, nullptr)
// Logs a mesage and aborts if |condition| is false.
#define LEDGER_CHECK(condition) \
LEDGER_LOG_CONDITIONAL(::absl::LogSeverity::kFatal, true, condition, #condition)
// Debug macros. LEDGER_DCHECK behaves like LEDGER_CHECK in debug builds, and is ignored in
// release builds.
#ifndef NDEBUG
#define LEDGER_DEBUG true
#else
#define LEDGER_DEBUG false
#endif
#define LEDGER_DCHECK(condition) \
LEDGER_LOG_CONDITIONAL(::absl::LogSeverity::kFatal, LEDGER_DEBUG, condition, #condition)
// Asserts that this code path is not reachable. This is only checked in debug mode.
#define LEDGER_NOTREACHED() LEDGER_DCHECK(false) << "Unreachable. "
// Prints an error message, but does not crash.
#define LEDGER_NOTIMPLEMENTED() LEDGER_LOG(ERROR) << "Not implemented. "
#endif // SRC_LEDGER_LIB_LOGGING_LOGGING_H_