From af19a1b07245b7d0be4fd492bd3731964937c7c6 Mon Sep 17 00:00:00 2001 From: Gil Date: Wed, 23 May 2018 07:00:05 -0700 Subject: Reimplement C++ logging (#1313) * Add direct support for formatting Objective-C objects * Rewrite log.h * Convert FSTWarn to LOG_WARN * Convert FSTLog to LOG_DEBUG * Remove FSTLogger --- .../firestore/local/leveldb_transaction.cc | 4 +- Firestore/core/src/firebase/firestore/util/log.h | 71 +++++++++++++------- .../core/src/firebase/firestore/util/log_apple.mm | 77 ++++------------------ .../core/src/firebase/firestore/util/log_stdio.cc | 63 ++++-------------- .../src/firebase/firestore/util/string_format.h | 7 ++ 5 files changed, 82 insertions(+), 140 deletions(-) (limited to 'Firestore/core/src/firebase/firestore') diff --git a/Firestore/core/src/firebase/firestore/local/leveldb_transaction.cc b/Firestore/core/src/firebase/firestore/local/leveldb_transaction.cc index 3581ef5..da9f004 100644 --- a/Firestore/core/src/firebase/firestore/local/leveldb_transaction.cc +++ b/Firestore/core/src/firebase/firestore/local/leveldb_transaction.cc @@ -212,9 +212,7 @@ void LevelDbTransaction::Commit() { batch.Put(it->first, it->second); } - if (util::LogGetLevel() <= util::kLogLevelDebug) { - util::LogDebug("Committing transaction: %s", ToString().c_str()); - } + LOG_DEBUG("Committing transaction: %s", ToString()); Status status = db_->Write(write_options_, &batch); HARD_ASSERT(status.ok(), "Failed to commit transaction:\n%s\n Failed: %s", diff --git a/Firestore/core/src/firebase/firestore/util/log.h b/Firestore/core/src/firebase/firestore/util/log.h index 1944596..248d434 100644 --- a/Firestore/core/src/firebase/firestore/util/log.h +++ b/Firestore/core/src/firebase/firestore/util/log.h @@ -17,44 +17,65 @@ #ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_LOG_H_ #define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_LOG_H_ -#include +#include + +#include "Firestore/core/src/firebase/firestore/util/string_format.h" namespace firebase { namespace firestore { namespace util { -/// @brief Levels used when logging messages. +// Levels used when logging messages. enum LogLevel { - /// Verbose Log Level - kLogLevelVerbose = 0, - /// Debug Log Level + // Debug Log Level kLogLevelDebug, - /// Info Log Level - kLogLevelInfo, - /// Warning Log Level + // Warning Log Level kLogLevelWarning, - /// Error Log Level - kLogLevelError, }; -// Common log methods. +// Log a message if kLogLevelDebug is enabled. Arguments are not evaluated if +// logging is disabled. +// +// @param format A format string suitable for use with `util::StringFormat` +// @param ... C++ variadic arguments that match the format string. Not C +// varargs. +#define LOG_DEBUG(...) \ + do { \ + namespace _util = firebase::firestore::util; \ + if (_util::LogIsLoggable(_util::kLogLevelDebug)) { \ + std::string _message = _util::StringFormat(__VA_ARGS__); \ + _util::LogMessage(_util::kLogLevelDebug, _message); \ + } \ + } while (0) + +// Log a message if kLogLevelWarn is enabled (it is by default). Arguments are +// not evaluated if logging is disabled. +// +// @param format A format string suitable for use with `util::StringFormat` +// @param ... C++ variadic arguments that match the format string. Not C +// varargs. +#define LOG_WARN(...) \ + do { \ + namespace _util = firebase::firestore::util; \ + if (_util::LogIsLoggable(_util::kLogLevelWarning)) { \ + std::string _message = _util::StringFormat(__VA_ARGS__); \ + _util::LogMessage(_util::kLogLevelWarning, _message); \ + } \ + } while (0) + +// Tests to see if the given log level is loggable. +bool LogIsLoggable(LogLevel level); + +// Is debug logging enabled? +inline bool LogIsDebugEnabled() { + return LogIsLoggable(kLogLevelDebug); +} // All messages at or above the specified log level value are displayed. void LogSetLevel(LogLevel level); -// Get the currently set log level. -LogLevel LogGetLevel(); -// Log a debug message to the system log. -void LogDebug(const char* format, ...); -// Log an info message to the system log. -void LogInfo(const char* format, ...); -// Log a warning to the system log. -void LogWarning(const char* format, ...); -// Log an error to the system log. -void LogError(const char* format, ...); -// Log a firebase message (implemented by the platform specific logger). -void LogMessageV(LogLevel log_level, const char* format, va_list args); -// Log a firebase message via LogMessageV(). -void LogMessage(LogLevel log_level, const char* format, ...); + +// Log a message at the given level. +void LogMessage(LogLevel log_level, const std::string& message); } // namespace util } // namespace firestore diff --git a/Firestore/core/src/firebase/firestore/util/log_apple.mm b/Firestore/core/src/firebase/firestore/util/log_apple.mm index cb2c58e..45e4f55 100644 --- a/Firestore/core/src/firebase/firestore/util/log_apple.mm +++ b/Firestore/core/src/firebase/firestore/util/log_apple.mm @@ -19,6 +19,7 @@ #import #import +#include #include #include "Firestore/core/src/firebase/firestore/util/string_apple.h" @@ -32,90 +33,40 @@ namespace { // Translates a C++ LogLevel to the equivalent Objective-C FIRLoggerLevel FIRLoggerLevel ToFIRLoggerLevel(LogLevel level) { switch (level) { - case kLogLevelVerbose: // fall through case kLogLevelDebug: return FIRLoggerLevelDebug; - case kLogLevelInfo: - return FIRLoggerLevelInfo; case kLogLevelWarning: return FIRLoggerLevelWarning; - case kLogLevelError: - return FIRLoggerLevelError; default: // Unsupported log level. FIRSetLoggerLevel will deal with it. return static_cast(-1); } } -} // namespace - -void LogSetLevel(LogLevel level) { - FIRSetLoggerLevel(ToFIRLoggerLevel(level)); -} - -LogLevel LogGetLevel() { - // We return the true log level. True log level is what the SDK used to - // determine whether to log instead of what parameter is used in the last call - // of LogSetLevel(). - if (FIRIsLoggableLevel(FIRLoggerLevelInfo, NO)) { - if (FIRIsLoggableLevel(FIRLoggerLevelDebug, NO)) { - // FIRLoggerLevelMax is actually kLogLevelDebug right now. We do not check - // further. - return kLogLevelDebug; - } else { - return kLogLevelInfo; - } - } else { - if (FIRIsLoggableLevel(FIRLoggerLevelWarning, NO)) { - return kLogLevelWarning; - } else { - return kLogLevelError; - } - } -} - -void LogDebug(const char* format, ...) { +// Actually logs a message via FIRLogger. This must be a C varargs function +// so that we can call FIRLogBasic which takes a `va_list`. +void LogMessageV(LogLevel level, NSString* format, ...) { va_list list; va_start(list, format); - FIRLogBasic(FIRLoggerLevelDebug, kFIRLoggerFirestore, @"I-FST000001", - WrapNSStringNoCopy(format), list); - va_end(list); -} -void LogInfo(const char* format, ...) { - va_list list; - va_start(list, format); - FIRLogBasic(FIRLoggerLevelInfo, kFIRLoggerFirestore, @"I-FST000001", - WrapNSStringNoCopy(format), list); - va_end(list); -} + FIRLogBasic(ToFIRLoggerLevel(level), kFIRLoggerFirestore, @"I-FST000001", + format, list); -void LogWarning(const char* format, ...) { - va_list list; - va_start(list, format); - FIRLogBasic(FIRLoggerLevelWarning, kFIRLoggerFirestore, @"I-FST000001", - WrapNSStringNoCopy(format), list); va_end(list); } -void LogError(const char* format, ...) { - va_list list; - va_start(list, format); - FIRLogBasic(FIRLoggerLevelError, kFIRLoggerFirestore, @"I-FST000001", - WrapNSStringNoCopy(format), list); - va_end(list); +} // namespace + +void LogSetLevel(LogLevel level) { + FIRSetLoggerLevel(ToFIRLoggerLevel(level)); } -void LogMessageV(LogLevel log_level, const char* format, va_list args) { - FIRLogBasic(ToFIRLoggerLevel(log_level), kFIRLoggerFirestore, @"I-FST000001", - WrapNSStringNoCopy(format), args); +bool LogIsLoggable(LogLevel level) { + return FIRIsLoggableLevel(ToFIRLoggerLevel(level), NO); } -void LogMessage(LogLevel log_level, const char* format, ...) { - va_list list; - va_start(list, format); - LogMessageV(log_level, format, list); - va_end(list); +void LogMessage(LogLevel level, const std::string& message) { + LogMessageV(level, @"%s", message.c_str()); } } // namespace util diff --git a/Firestore/core/src/firebase/firestore/util/log_stdio.cc b/Firestore/core/src/firebase/firestore/util/log_stdio.cc index b277406..6fff885 100644 --- a/Firestore/core/src/firebase/firestore/util/log_stdio.cc +++ b/Firestore/core/src/firebase/firestore/util/log_stdio.cc @@ -19,77 +19,42 @@ #include #include +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + namespace firebase { namespace firestore { namespace util { -LogLevel g_log_level = kLogLevelInfo; +LogLevel g_log_level = kLogLevelWarning; void LogSetLevel(LogLevel level) { g_log_level = level; } -LogLevel LogGetLevel() { - return g_log_level; -} - -void LogDebug(const char* format, ...) { - va_list list; - va_start(list, format); - LogMessageV(kLogLevelDebug, format, list); - va_end(list); -} - -void LogInfo(const char* format, ...) { - va_list list; - va_start(list, format); - LogMessageV(kLogLevelInfo, format, list); - va_end(list); -} - -void LogWarning(const char* format, ...) { - va_list list; - va_start(list, format); - LogMessageV(kLogLevelWarning, format, list); - va_end(list); +bool LogIsLoggable(LogLevel level) { + return level >= g_log_level; } -void LogError(const char* format, ...) { - va_list list; - va_start(list, format); - LogMessageV(kLogLevelError, format, list); - va_end(list); -} - -void LogMessageV(LogLevel log_level, const char* format, va_list args) { +void LogMessage(LogLevel log_level, const std::string& message) { if (log_level < g_log_level) { return; } + + const char* level_word; + switch (log_level) { - case kLogLevelVerbose: - printf("VERBOSE: "); - break; case kLogLevelDebug: - printf("DEBUG: "); - break; - case kLogLevelInfo: + level_word = "DEBUG"; break; case kLogLevelWarning: - printf("WARNING: "); + level_word = "WARNING"; break; - case kLogLevelError: - printf("ERROR: "); + default: + UNREACHABLE(); break; } - vprintf(format, args); - printf("\n"); -} -void LogMessage(LogLevel log_level, const char* format, ...) { - va_list list; - va_start(list, format); - LogMessageV(log_level, format, list); - va_end(list); + printf("%s: %s\n", level_word, message.c_str()); } } // namespace util diff --git a/Firestore/core/src/firebase/firestore/util/string_format.h b/Firestore/core/src/firebase/firestore/util/string_format.h index 3d7a1dc..f8da785 100644 --- a/Firestore/core/src/firebase/firestore/util/string_format.h +++ b/Firestore/core/src/firebase/firestore/util/string_format.h @@ -21,6 +21,7 @@ #include #include +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" #include "absl/base/attributes.h" #include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" @@ -66,6 +67,12 @@ class FormatArg : public absl::AlphaNum { : FormatArg{std::forward(value), internal::FormatChoice<0>{}} { } +#if __OBJC__ + FormatArg(NSObject* object) // NOLINT(runtime/explicit) + : AlphaNum{MakeStringView([object description])} { + } +#endif + private: /** * Creates a FormatArg from a boolean value, representing the string -- cgit v1.2.3