AOS_LOG to messages

Change-Id: I0cb78a957a180f4472fc3e78a75eade63e4e43b8
diff --git a/aos/logging/BUILD b/aos/logging/BUILD
index 4931696..214df63 100644
--- a/aos/logging/BUILD
+++ b/aos/logging/BUILD
@@ -1,3 +1,5 @@
+load("@com_github_google_flatbuffers//:build_defs.bzl", "flatbuffer_cc_library")
+
 # The primary client logging interface.
 cc_library(
     name = "logging",
@@ -150,3 +152,10 @@
         "@com_google_absl//absl/base",
     ],
 )
+
+flatbuffer_cc_library(
+    name = "log_message_fbs",
+    srcs = ["log_message.fbs"],
+    visibility = ["//visibility:public"],
+    gen_reflections = 1,
+)
diff --git a/aos/logging/implementations.cc b/aos/logging/implementations.cc
index cfc14c0..04831a2 100644
--- a/aos/logging/implementations.cc
+++ b/aos/logging/implementations.cc
@@ -131,10 +131,6 @@
 void SetImplementation(LogImplementation *implementation, bool update_global) {
   internal::Context *context = internal::Context::Get();
 
-  if (implementation == nullptr) {
-    AOS_LOG(FATAL, "SetImplementation got invalid implementation");
-  }
-
   context->implementation = implementation;
   if (update_global) {
     SetGlobalImplementation(implementation);
@@ -150,6 +146,10 @@
   return old;
 }
 
+LogImplementation *GetImplementation() {
+  return internal::Context::Get()->implementation;
+}
+
 void Init() {
   static absl::once_flag once;
   absl::call_once(once, DoInit);
@@ -264,7 +264,7 @@
 
 void RegisterCallbackImplementation(
     const ::std::function<void(const LogMessage &)> &callback,
-    bool update_global = true) {
+    bool update_global) {
   Init();
   SetImplementation(new CallbackLogImplementation(callback), update_global);
 }
diff --git a/aos/logging/implementations.h b/aos/logging/implementations.h
index 78980ff..6cf8376 100644
--- a/aos/logging/implementations.h
+++ b/aos/logging/implementations.h
@@ -132,6 +132,7 @@
 // when needed or by calling Load()).
 // The logging system takes ownership of implementation. It will delete it if
 // necessary, so it must be created with new.
+// TODO: Log implementations are never deleted. Need means to safely deregister.
 void SetImplementation(LogImplementation *implementation,
                        bool update_global = true);
 
@@ -139,6 +140,8 @@
 // implementation.
 LogImplementation *SwapImplementation(LogImplementation *implementation);
 
+LogImplementation *GetImplementation();
+
 // Must be called at least once per process/load before anything else is
 // called. This function is safe to call multiple times from multiple
 // tasks/threads.
@@ -164,7 +167,18 @@
 void RegisterQueueImplementation();
 
 void RegisterCallbackImplementation(
-    const ::std::function<void(const LogMessage &)> &callback);
+    const ::std::function<void(const LogMessage &)> &callback,
+    bool update_global = true);
+
+class ScopedLogRestorer {
+ public:
+  ScopedLogRestorer() { prev_impl_ = GetImplementation(); }
+
+  ~ScopedLogRestorer() { SetImplementation(prev_impl_); }
+
+ private:
+  LogImplementation *prev_impl_;
+};
 
 // This is where all of the code that is only used by actual LogImplementations
 // goes.
diff --git a/aos/logging/implementations_test.cc b/aos/logging/implementations_test.cc
index a7b8b7d..272214a 100644
--- a/aos/logging/implementations_test.cc
+++ b/aos/logging/implementations_test.cc
@@ -244,6 +244,19 @@
   EXPECT_EQ(kExpected1, ::std::string(buffer));
 }
 
+TEST(ScopedLogRestorerTest, RestoreTest) {
+  LogImplementation *curr_impl = GetImplementation();
+
+  {
+    ScopedLogRestorer log_restorer;
+
+    logging::RegisterCallbackImplementation([] (const LogMessage&) {});
+    ASSERT_NE(curr_impl, GetImplementation());
+  }
+
+  ASSERT_EQ(curr_impl, GetImplementation());
+}
+
 }  // namespace testing
 }  // namespace logging
 }  // namespace aos
diff --git a/aos/logging/log_message.fbs b/aos/logging/log_message.fbs
new file mode 100644
index 0000000..789724f
--- /dev/null
+++ b/aos/logging/log_message.fbs
@@ -0,0 +1,27 @@
+namespace aos.logging;
+
+// Log level, corresponding to levels in logging.h
+enum Level : byte {
+  ERROR = -1,
+  DEBUG = 0,
+  INFO = 1,
+  WARNING = 2,
+  FATAL = 4,
+  LOG_UNKNOWN = 5
+}
+
+table LogMessageFbs {
+  // Text of the log message, includng file name and line
+  message:string (id: 0);
+
+  // Severity of the log message
+  level:Level (id: 1);
+
+  // Pid of the process creating the log message
+  source:int (id:2);
+
+  // Application name
+  name:string (id:3);
+}
+
+root_type LogMessageFbs;