Make AOS logging per thread, not global

We noticed that if 2 threads use AOS_LOG, they occasionally crash.  The
stack trace looked like 2 messages were being constructed
simultaneously.  Digging in, this is possible because there is 1 global
logger which gets passed (patchily) to the per-thread context.

We've got a bunch of different cases and (reasonable) ways to handle
them when ShmEventLoop comes into play.

Simple single threaded appliction:
  * Outside Run() -> stderr
  * Inside Run() -> /aos

Single event loop appliction with extra threads
  * Outside Run() -> stderr
  * Inside Run() -> /aos
  * Other threads -> stderr

Multiple event loop appliction with extra threads
  * Outside Run() -> stderr
  * Inside Run() -> /aos
  * Other threads -> stderr

Simulation:
  * Inside Run -> /aos
  * Outside Run -> stderr

This pretty quickly quickly looks like a thread local logging handler
and a fallback to stderr.  We don't really need much more, and don't
want to worry about synchronization for much more, so lets just do the
simple thing for now and revise if there are better use cases.

Change-Id: I90d76516a55f0b01a8a0e27ad0434dac5921e261
diff --git a/aos/logging/interface.cc b/aos/logging/interface.cc
index b2f7b75..0cb0cd8 100644
--- a/aos/logging/interface.cc
+++ b/aos/logging/interface.cc
@@ -9,6 +9,8 @@
 
 #include "aos/die.h"
 #include "aos/logging/context.h"
+#include "aos/logging/implementations.h"
+#include "glog/logging.h"
 
 namespace aos {
 namespace logging {
@@ -21,8 +23,8 @@
   const int ret = vsnprintf(output, size, format, ap);
   typedef ::std::common_type<int, size_t>::type RetType;
   if (ret < 0) {
-    AOS_PLOG(FATAL, "vsnprintf(%p, %zd, %s, args) failed", output, size,
-             format);
+    PLOG(FATAL) << "vsnprintf(" << output << ", " << size << ", " << format
+                << ", args) failed";
   } else if (static_cast<RetType>(ret) >= static_cast<RetType>(size)) {
     // Overwrite the '\0' at the end of the existing data and
     // copy in the one on the end of continued.
@@ -31,39 +33,32 @@
   return ::std::min<RetType>(ret, size);
 }
 
-void RunWithCurrentImplementation(
-    ::std::function<void(LogImplementation *)> function) {
-  Context *context = Context::Get();
-
-  const std::shared_ptr<LogImplementation> implementation =
-      context->implementation;
-  if (implementation == NULL) {
-    Die("no logging implementation to use\n");
-  }
-  function(implementation.get());
-}
-
 }  // namespace internal
 
 using internal::Context;
 
-void LogImplementation::DoVLog(log_level level, const char *format,
-                               va_list ap) {
-  auto log_impl = [&](LogImplementation *implementation) {
-    va_list ap1;
-    va_copy(ap1, ap);
-    implementation->DoLog(level, format, ap1);
-    va_end(ap1);
-
-    if (level == FATAL) {
-      VDie(format, ap);
-    }
-  };
-  internal::RunWithCurrentImplementation(::std::ref(log_impl));
-}
-
 void VLog(log_level level, const char *format, va_list ap) {
-  LogImplementation::DoVLog(level, format, ap);
+  va_list ap1;
+  va_copy(ap1, ap);
+
+  Context *context = Context::Get();
+
+  const std::shared_ptr<LogImplementation> implementation =
+      context->implementation;
+  // Log to the implementation if we have it, and stderr as a backup.
+  if (implementation) {
+    implementation->DoLog(level, format, ap1);
+  } else {
+    aos::logging::LogMessage message;
+    aos::logging::internal::FillInMessage(level, aos::monotonic_clock::now(),
+                                          format, ap, &message);
+    aos::logging::internal::PrintMessage(stderr, message);
+  }
+  va_end(ap1);
+
+  if (level == FATAL) {
+    VDie(format, ap);
+  }
 }
 
 }  // namespace logging