Minimize platform/api/logging.h, consolidate macros/impl elsewhere.

Reduces the logging API that must be implemented by embedders to three
simple functions: IsLoggingOn(), LogWithLevel(), and Break(). Added
documentation for these functions.

All logging convenience macros that OpenScreen code uses have been moved
to platform/api/internal/logging_macros.h, and are being #included from
platform/api/logging.h. This is to make it easier for embedder
developers to identify what is being required from them.

All standalone impl for logging has been consolidated into
platform/impl/logging.h (declaration of init routines) and
logging_posix.cc (POSIX implementation, writing to stderr or a FIFO).

Bug: openscreen:77
Change-Id: Id14a380569373a443a81b7bb5139b4648643495e
Reviewed-on: https://chromium-review.googlesource.com/c/openscreen/+/1900333
Reviewed-by: Yuri Wiitala <miu@chromium.org>
Reviewed-by: mark a. foltz <mfoltz@chromium.org>
Commit-Queue: Yuri Wiitala <miu@chromium.org>
diff --git a/platform/api/logging.h b/platform/api/logging.h
index 1f051f0..29f6f92 100644
--- a/platform/api/logging.h
+++ b/platform/api/logging.h
@@ -5,154 +5,65 @@
 #ifndef PLATFORM_API_LOGGING_H_
 #define PLATFORM_API_LOGGING_H_
 
-#include <sstream>
-
 #include "absl/strings/string_view.h"
 
 namespace openscreen {
 namespace platform {
 
 enum class LogLevel {
+  // Very detailed information, often used for evaluating performance or
+  // debugging production issues in-the-wild.
   kVerbose = 0,
-  kInfo,
-  kWarning,
-  kError,
-  kFatal,
+
+  // Used occasionally to note events of interest, but not for indicating any
+  // problems. This is also used for general console messaging in Open Screen's
+  // standalone executables.
+  kInfo = 1,
+
+  // Indicates a problem that may or may not lead to an operational failure.
+  kWarning = 2,
+
+  // Indicates an operational failure that may or may not cause a component to
+  // stop working.
+  kError = 3,
+
+  // Indicates a logic flaw, corruption, impossible/unanticipated situation, or
+  // operational failure so serious that Open Screen will soon call Break() to
+  // abort the current process. Examples: security/privacy risks, memory
+  // management issues, API contract violations.
+  kFatal = 4,
 };
 
-std::string LogLevelToString(LogLevel level);
+// Returns true if |level| is at or above the level where the embedder will
+// record/emit log entries from the code in |file|.
+bool IsLoggingOn(LogLevel level, absl::string_view file);
 
-//
-// PLATFORM IMPLEMENTATION
-// The following functions must be implemented by the platform.
-void LogInit(const char* filename);
-void SetLogLevel(LogLevel level);
+// Record a log entry, consisting of its logging level, location and message.
+// The embedder may filter-out entries according to its own policy, but this
+// function will not be called if IsLoggingOn(level, file) returns false.
+// Whenever |level| is kFatal, Open Screen will call Break() immediately after
+// this returns.
 void LogWithLevel(LogLevel level,
                   absl::string_view file,
                   int line,
                   absl::string_view msg);
+
+// Breaks into the debugger, if one is present. Otherwise, aborts the current
+// process (i.e., this function should not return). In production builds, an
+// embedder could invoke its infrastructure for performing "dumps," consisting
+// of thread stack traces and other relevant process state information, before
+// aborting the process.
 void Break();
-//
-// END PLATFORM IMPLEMENTATION
-//
-
-// The stream-based logging macros below are adapted from Chromium's
-// base/logging.h.
-class LogMessage {
- public:
-  LogMessage(LogLevel level, absl::string_view file, int line);
-  ~LogMessage();
-
-  std::ostream& stream() { return stream_; }
-
- private:
-  const LogLevel level_;
-
-  // The file here comes from the __FILE__ macro, which should persist while
-  // we are doing the logging. Hence, keeping it unmanaged here and not
-  // creating a copy should be safe.
-  absl::string_view const file_;
-  const int line_;
-  std::ostringstream stream_;
-};
-
-// OSP_LOG_* are defined as macros so we can access the handy
-// __FILE__ and __LINE__ expansions.
-
-#define OSP_VLOG                                                             \
-  openscreen::platform::LogMessage(openscreen::platform::LogLevel::kVerbose, \
-                                   __FILE__, __LINE__)                       \
-      .stream()
-
-#define OSP_LOG_INFO                                                      \
-  openscreen::platform::LogMessage(openscreen::platform::LogLevel::kInfo, \
-                                   __FILE__, __LINE__)                    \
-      .stream()
-#define OSP_LOG OSP_LOG_INFO
-
-#define OSP_LOG_WARN                                                         \
-  openscreen::platform::LogMessage(openscreen::platform::LogLevel::kWarning, \
-                                   __FILE__, __LINE__)                       \
-      .stream()
-#define OSP_LOG_ERROR                                                      \
-  openscreen::platform::LogMessage(openscreen::platform::LogLevel::kError, \
-                                   __FILE__, __LINE__)                     \
-      .stream()
-#define OSP_LOG_FATAL                                                      \
-  openscreen::platform::LogMessage(openscreen::platform::LogLevel::kFatal, \
-                                   __FILE__, __LINE__)                     \
-      .stream()
-
-namespace detail {
-
-class Voidify {
- public:
-  Voidify() = default;
-  void operator&(std::ostream&) {}
-};
-
-}  // namespace detail
-
-#define OSP_LAZY_STREAM(stream, condition) \
-  !(condition) ? (void)0 : openscreen::platform::detail::Voidify() & (stream)
-#define OSP_EAT_STREAM OSP_LAZY_STREAM(OSP_LOG, false)
-#define OSP_VLOG_IF(condition) OSP_LAZY_STREAM(OSP_VLOG, (condition))
-#define OSP_LOG_IF(level, condition) \
-  OSP_LAZY_STREAM(OSP_LOG_##level, (condition))
-
-// TODO(btolsch): Add tests for (D)OSP_CHECK and possibly logging.
-#define OSP_CHECK(condition)                   \
-  OSP_LAZY_STREAM(OSP_LOG_FATAL, !(condition)) \
-      << "OSP_CHECK(" << #condition << ") failed: "
-
-#define OSP_CHECK_EQ(a, b) \
-  OSP_CHECK((a) == (b)) << (a) << " vs. " << (b) << ": "
-#define OSP_CHECK_NE(a, b) \
-  OSP_CHECK((a) != (b)) << (a) << " vs. " << (b) << ": "
-#define OSP_CHECK_LT(a, b) OSP_CHECK((a) < (b)) << (a) << " vs. " << (b) << ": "
-#define OSP_CHECK_LE(a, b) \
-  OSP_CHECK((a) <= (b)) << (a) << " vs. " << (b) << ": "
-#define OSP_CHECK_GT(a, b) OSP_CHECK((a) > (b)) << (a) << " vs. " << (b) << ": "
-#define OSP_CHECK_GE(a, b) \
-  OSP_CHECK((a) >= (b)) << (a) << " vs. " << (b) << ": "
-
-#if defined(_DEBUG) || defined(DCHECK_ALWAYS_ON)
-#define OSP_DCHECK_IS_ON() 1
-#define OSP_DCHECK(condition) OSP_CHECK(condition)
-#define OSP_DCHECK_EQ(a, b) OSP_CHECK_EQ(a, b)
-#define OSP_DCHECK_NE(a, b) OSP_CHECK_NE(a, b)
-#define OSP_DCHECK_LT(a, b) OSP_CHECK_LT(a, b)
-#define OSP_DCHECK_LE(a, b) OSP_CHECK_LE(a, b)
-#define OSP_DCHECK_GT(a, b) OSP_CHECK_GT(a, b)
-#define OSP_DCHECK_GE(a, b) OSP_CHECK_GE(a, b)
-#else
-#define OSP_DCHECK_IS_ON() 0
-// When DCHECKs are off, nothing will be logged. Use that fact to make
-// references to the |condition| expression (or |a| and |b|) so the compiler
-// won't emit unused variable warnings/errors when DCHECKs are turned off.
-#define OSP_DCHECK(condition) OSP_EAT_STREAM << !(condition)
-#define OSP_DCHECK_EQ(a, b) OSP_EAT_STREAM << !((a) == (b))
-#define OSP_DCHECK_NE(a, b) OSP_EAT_STREAM << !((a) != (b))
-#define OSP_DCHECK_LT(a, b) OSP_EAT_STREAM << !((a) < (b))
-#define OSP_DCHECK_LE(a, b) OSP_EAT_STREAM << !((a) <= (b))
-#define OSP_DCHECK_GT(a, b) OSP_EAT_STREAM << !((a) > (b))
-#define OSP_DCHECK_GE(a, b) OSP_EAT_STREAM << !((a) >= (b))
-#endif
-
-#define OSP_DVLOG OSP_VLOG_IF(OSP_DCHECK_IS_ON())
-#define OSP_DLOG_INFO OSP_LOG_IF(INFO, OSP_DCHECK_IS_ON())
-#define OSP_DLOG_WARN OSP_LOG_IF(WARN, OSP_DCHECK_IS_ON())
-#define OSP_DLOG_ERROR OSP_LOG_IF(ERROR, OSP_DCHECK_IS_ON())
-#define OSP_DLOG_FATAL OSP_LOG_IF(FATAL, OSP_DCHECK_IS_ON())
-#define OSP_DVLOG_IF(condition) OSP_VLOG_IF(OSP_DCHECK_IS_ON() && (condition))
-#define OSP_DLOG_IF(level, condition) \
-  OSP_LOG_IF(level, OSP_DCHECK_IS_ON() && (condition))
-
-#define OSP_UNIMPLEMENTED() OSP_LOG_ERROR << __func__ << ": unimplemented"
-
-#define OSP_NOTREACHED() OSP_CHECK(false) << __func__ << ": NOTREACHED() hit."
 
 }  // namespace platform
 }  // namespace openscreen
 
+// Convenience macros and inline code that Open Screen code uses to invoke the
+// above embedder-implemented functions.
+//
+// TODO(crbug.com/openscreen/77): Remove this, move logging_macros.h to
+// util/logging.h, and search-and-replace all #includes throughout the code
+// base.
+#include "platform/api/internal/logging_macros.h"  // NOLINT
+
 #endif  // PLATFORM_API_LOGGING_H_