Untangle and clean up the logging code
It was a mess before because of a combination of having code split out
for cRIO vs Linux and cruft.
Change-Id: Id282e1a7f7988be0441c669a573a5d022ed41fb9
diff --git a/aos/build/queues.bzl b/aos/build/queues.bzl
index 47a1b68..87d5b54 100644
--- a/aos/build/queues.bzl
+++ b/aos/build/queues.bzl
@@ -102,7 +102,7 @@
'//aos/common:once',
'//aos/common:queues',
'//aos/common:queue_types',
- '//aos/common/logging:logging_printf_formats',
+ '//aos/common/logging:printf_formats',
],
visibility = visibility,
)
diff --git a/aos/build/queues/compiler.rb b/aos/build/queues/compiler.rb
index 1f739e0..0b60b0e 100644
--- a/aos/build/queues/compiler.rb
+++ b/aos/build/queues/compiler.rb
@@ -107,7 +107,7 @@
cpp_tree.add_cc_include("<inttypes.h>")
cpp_tree.add_cc_include("aos/common/queue_types.h".inspect)
cpp_tree.add_cc_include("aos/common/once.h".inspect)
- cpp_tree.add_cc_include("aos/common/logging/logging_printf_formats.h".inspect)
+ cpp_tree.add_cc_include("aos/common/logging/printf_formats.h".inspect)
cpp_tree.add_cc_using("::aos::to_network")
cpp_tree.add_cc_using("::aos::to_host")
diff --git a/aos/build/queues/print_field.rb b/aos/build/queues/print_field.rb
index 4f0fe7d..5eb3712 100644
--- a/aos/build/queues/print_field.rb
+++ b/aos/build/queues/print_field.rb
@@ -17,7 +17,7 @@
#include "aos/common/byteorder.h"
#include "aos/common/time.h"
#include "aos/common/print_field_helpers.h"
-#include "aos/common/logging/logging_printf_formats.h"
+#include "aos/common/logging/printf_formats.h"
namespace aos {
diff --git a/aos/common/BUILD b/aos/common/BUILD
index 4d0127b..8e911de 100644
--- a/aos/common/BUILD
+++ b/aos/common/BUILD
@@ -28,7 +28,7 @@
':once',
':queues',
'//aos/testing:googletest',
- '//aos/common/logging',
+ '//aos/common/logging:implementations',
'//aos/linux_code/ipc_lib:shared_mem',
':mutex',
],
@@ -57,7 +57,7 @@
'time.h',
],
deps = [
- '//aos/common/logging:logging_interface',
+ '//aos/common/logging:logging',
':mutex',
':macros',
'//aos/linux_code/ipc_lib:shared_mem',
@@ -99,7 +99,7 @@
deps = [
'//aos/linux_code/ipc_lib:aos_sync',
':time',
- '//aos/common/logging:logging_interface',
+ '//aos/common/logging:logging',
],
)
@@ -125,7 +125,7 @@
'//aos/linux_code/ipc_lib:shared_mem',
'//aos/linux_code/ipc_lib:core_lib',
':mutex',
- '//aos/common/logging:logging_printf_formats',
+ '//aos/common/logging:printf_formats',
':time',
':byteorder'
],
@@ -323,7 +323,7 @@
deps = [
':mutex',
'//aos/linux_code/ipc_lib:aos_sync',
- '//aos/common/logging:logging_interface',
+ '//aos/common/logging:logging',
],
)
@@ -379,7 +379,7 @@
deps = [
'//aos/linux_code/ipc_lib:aos_sync',
':die',
- '//aos/common/logging:logging_interface',
+ '//aos/common/logging:logging',
':type_traits',
],
)
@@ -404,7 +404,7 @@
'transaction.h',
],
deps = [
- '//aos/common/logging:logging_interface',
+ '//aos/common/logging:logging',
'//aos/common/util:compiler_memory_barrier',
],
)
diff --git a/aos/common/controls/BUILD b/aos/common/controls/BUILD
index a5f3152..08cbd36 100644
--- a/aos/common/controls/BUILD
+++ b/aos/common/controls/BUILD
@@ -10,7 +10,7 @@
deps = [
'//aos/common:queues',
':control_loop',
- '//aos/common/logging:log_replay',
+ '//aos/common/logging:replay',
'//aos/common/logging:queue_logging',
'//aos/common:time',
],
diff --git a/aos/common/controls/replay_control_loop.h b/aos/common/controls/replay_control_loop.h
index fae3ad8..6921a0e 100644
--- a/aos/common/controls/replay_control_loop.h
+++ b/aos/common/controls/replay_control_loop.h
@@ -5,7 +5,7 @@
#include "aos/common/queue.h"
#include "aos/common/controls/control_loop.h"
-#include "aos/common/logging/log_replay.h"
+#include "aos/common/logging/replay.h"
#include "aos/common/logging/queue_logging.h"
#include "aos/common/time.h"
#include "aos/common/macros.h"
diff --git a/aos/common/libc/BUILD b/aos/common/libc/BUILD
index 5db9257..e2a87cb 100644
--- a/aos/common/libc/BUILD
+++ b/aos/common/libc/BUILD
@@ -9,7 +9,7 @@
'aos_strsignal.h',
],
deps = [
- '//aos/common/logging:logging_interface',
+ '//aos/common/logging',
],
)
diff --git a/aos/common/logging/BUILD b/aos/common/logging/BUILD
index b3e358d..adddb4b 100644
--- a/aos/common/logging/BUILD
+++ b/aos/common/logging/BUILD
@@ -1,30 +1,54 @@
-package(default_visibility = ['//visibility:public'])
+# The primary client logging interface.
+cc_library(
+ name = 'logging',
+ visibility = ['//visibility:public'],
+ hdrs = [
+ 'logging.h',
+ 'interface.h',
+ 'context.h',
+ ],
+ srcs = [
+ 'interface.cc',
+ 'context.cc',
+ ],
+ deps = [
+ '//aos/common:die',
+ '//aos/common/libc:aos_strerror',
+ '//aos/common:macros',
+ '//aos/linux_code:complex_thread_local',
+ ':sizes',
+ ],
+)
cc_library(
- name = 'log_replay',
+ name = 'replay',
+ visibility = ['//visibility:public'],
srcs = [
- 'log_replay.cc',
+ 'replay.cc',
],
hdrs = [
- 'log_replay.h',
+ 'replay.h',
],
deps = [
':binary_log_file',
'//aos/common:queues',
- '//aos/common/logging',
+ ':logging',
'//aos/linux_code/ipc_lib:queue',
],
)
cc_binary(
name = 'binary_log_writer',
+ visibility = ['//visibility:public'],
srcs = [
'binary_log_writer.cc',
],
deps = [
- '//aos/common/logging',
+ ':logging',
+ ':implementations',
'//aos/linux_code:init',
'//aos/linux_code:configuration',
+ '//aos/linux_code/ipc_lib:queue',
'//aos/common:die',
':binary_log_file',
'//aos/common:queue_types',
@@ -33,11 +57,13 @@
cc_binary(
name = 'log_streamer',
+ visibility = ['//visibility:public'],
srcs = [
'log_streamer.cc',
],
deps = [
- '//aos/common/logging',
+ ':logging',
+ ':implementations',
'//aos/linux_code:init',
'//aos/common:time',
'//aos/linux_code/ipc_lib:queue',
@@ -46,11 +72,13 @@
cc_binary(
name = 'log_displayer',
+ visibility = ['//visibility:public'],
srcs = [
'log_displayer.cc',
],
deps = [
- '//aos/common/logging',
+ ':logging',
+ ':implementations',
'//aos/linux_code:init',
':binary_log_file',
'//aos/common:queue_types',
@@ -68,65 +96,7 @@
'binary_log_file.h',
],
deps = [
- '//aos/common/logging',
- ],
-)
-
-cc_library(
- name = 'linux_interface',
- visibility = ['//aos/common/logging:__pkg__'],
- srcs = [
- 'linux_interface.cc',
- ],
- deps = [
- '//aos/linux_code:complex_thread_local',
- '//aos/common:die',
- '//aos/common/logging:context',
- ],
-)
-
-cc_library(
- name = 'linux_logging',
- visibility = [
- '//aos/linux_code:__subpackages__'
- ],
- hdrs = [
- 'linux_logging.h',
- ],
- srcs = [
- 'linux_logging.cc',
- ],
- deps = [
- '//aos/linux_code/ipc_lib:queue',
- '//aos/common:time',
- '//aos/common/logging:logging',
- ],
-)
-
-cc_test(
- name = 'logging_impl_test',
- srcs = [
- 'logging_impl_test.cc',
- ],
- deps = [
- '//aos/testing:googletest',
- '//aos/common/logging',
- ],
-)
-
-cc_library(
- name = 'queue_logging',
- srcs = [
- 'queue_logging.cc',
- 'queue_logging-tmpl.h',
- ],
- hdrs = [
- 'queue_logging.h',
- ],
- deps = [
- '//aos/common/logging',
- '//aos/common:die',
- '//aos/common:queue_types',
+ ':implementations',
],
)
@@ -137,18 +107,48 @@
],
)
+cc_test(
+ name = 'implementations_test',
+ srcs = [
+ 'implementations_test.cc',
+ ],
+ deps = [
+ '//aos/testing:googletest',
+ ':logging',
+ ':implementations',
+ ],
+)
+
+cc_library(
+ name = 'queue_logging',
+ visibility = ['//visibility:public'],
+ srcs = [
+ 'queue_logging.cc',
+ ],
+ hdrs = [
+ 'queue_logging.h',
+ ],
+ deps = [
+ ':logging',
+ ':sizes',
+ '//aos/common:die',
+ '//aos/common:queue_types',
+ ],
+)
+
cc_library(
name = 'matrix_logging',
+ visibility = ['//visibility:public'],
srcs = [
'matrix_logging.cc',
- 'matrix_logging-tmpl.h',
],
hdrs = [
'matrix_logging.h',
],
deps = [
'//aos/common:generated_queue_headers',
- '//aos/common/logging',
+ ':logging',
+ ':sizes',
'//aos/common:die',
'//aos/common:queue_types',
'//third_party/eigen',
@@ -156,9 +156,10 @@
)
cc_library(
- name = 'logging_printf_formats',
+ name = 'printf_formats',
+ visibility = ['//visibility:public'],
hdrs = [
- 'logging_printf_formats.h',
+ 'printf_formats.h',
],
deps = [
'//aos/common:macros',
@@ -166,46 +167,24 @@
)
cc_library(
- name = 'logging_interface',
- hdrs = [
- 'logging.h',
- 'logging_interface.h',
- ],
+ name = 'implementations',
+ visibility = ['//visibility:public'],
srcs = [
- 'logging_interface.cc',
+ 'implementations.cc',
+ ],
+ hdrs = [
+ 'implementations.h',
],
deps = [
'//aos/common:die',
- '//aos/common/libc:aos_strerror',
- '//aos/common/logging:linux_interface',
- '//aos/common:macros',
- ],
-)
-
-cc_library(
- name = 'context',
- hdrs = [
- 'context.h',
- ],
- srcs = [
- 'context.cc',
- ],
- deps = [
- ':sizes',
- ],
-)
-
-cc_library(
- name = 'logging',
- srcs = [
- 'logging_impl.cc',
- ],
- hdrs = [
- 'logging_impl.h',
- ],
- deps = [
'//aos/common:time',
'//aos/common:once',
'//aos/common:queue_types',
+ ':logging',
+ '//aos/common:type_traits',
+ '//aos/common:mutex',
+ '//aos/common:macros',
+ ':sizes',
+ '//aos/linux_code/ipc_lib:queue',
],
)
diff --git a/aos/common/logging/binary_log_file.h b/aos/common/logging/binary_log_file.h
index b753699..7f9506e 100644
--- a/aos/common/logging/binary_log_file.h
+++ b/aos/common/logging/binary_log_file.h
@@ -7,7 +7,7 @@
#include <algorithm>
-#include "aos/common/logging/logging_impl.h"
+#include "aos/common/logging/implementations.h"
namespace aos {
namespace logging {
diff --git a/aos/common/logging/binary_log_writer.cc b/aos/common/logging/binary_log_writer.cc
index d4e6685..56949b5 100644
--- a/aos/common/logging/binary_log_writer.cc
+++ b/aos/common/logging/binary_log_writer.cc
@@ -14,10 +14,11 @@
#include <map>
#include <unordered_set>
-#include "aos/common/logging/linux_logging.h"
+#include "aos/common/logging/implementations.h"
#include "aos/common/logging/binary_log_file.h"
#include "aos/linux_code/init.h"
#include "aos/linux_code/configuration.h"
+#include "aos/linux_code/ipc_lib/queue.h"
#include "aos/common/queue_types.h"
#include "aos/common/die.h"
@@ -198,11 +199,14 @@
}
LogFileWriter writer(fd);
+ RawQueue *queue = GetLoggingQueue();
+
::std::unordered_set<uint32_t> written_type_ids;
off_t clear_type_ids_cookie = 0;
while (true) {
- const LogMessage *const msg = ReadNext();
+ const LogMessage *const msg =
+ static_cast<const LogMessage *>(queue->ReadMessage(RawQueue::kBlock));
if (msg == NULL) continue;
const size_t raw_output_length =
@@ -294,7 +298,7 @@
futex_set(&output->marker);
- logging::linux_code::Free(msg);
+ queue->FreeMessage(msg);
}
Cleanup();
diff --git a/aos/common/logging/context.cc b/aos/common/logging/context.cc
index 8874edb..aebee02 100644
--- a/aos/common/logging/context.cc
+++ b/aos/common/logging/context.cc
@@ -1,10 +1,59 @@
#include "aos/common/logging/context.h"
#include <string.h>
+#include <sys/prctl.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <string>
+
+#include "aos/common/die.h"
+#include "aos/linux_code/complex_thread_local.h"
namespace aos {
namespace logging {
namespace internal {
+namespace {
+
+// TODO(brians): Differentiate between threads with the same name in the same
+// process.
+
+::std::string GetMyName() {
+ // The maximum number of characters that can make up a thread name.
+ // The docs are unclear if it can be 16 characters with no '\0', so we'll be
+ // safe by adding our own where necessary.
+ static const size_t kThreadNameLength = 16;
+
+ ::std::string process_name(program_invocation_short_name);
+
+ char thread_name_array[kThreadNameLength + 1];
+ if (prctl(PR_GET_NAME, thread_name_array) != 0) {
+ PDie("prctl(PR_GET_NAME, %p) failed", thread_name_array);
+ }
+ thread_name_array[sizeof(thread_name_array) - 1] = '\0';
+ ::std::string thread_name(thread_name_array);
+
+ // If the first bunch of characters are the same.
+ // We cut off comparing at the shorter of the 2 strings because one or the
+ // other often ends up cut off.
+ if (strncmp(thread_name.c_str(), process_name.c_str(),
+ ::std::min(thread_name.length(), process_name.length())) == 0) {
+ // This thread doesn't have an actual name.
+ return process_name;
+ }
+
+ return process_name + '.' + thread_name;
+}
+
+::aos::ComplexThreadLocal<Context> my_context;
+
+// True if we're going to delete the current Context object ASAP. The
+// reason for doing this instead of just deleting them is that tsan (at least)
+// doesn't like it when pthread_atfork handlers do complicated stuff and it's
+// not a great idea anyways.
+thread_local bool delete_current_context(false);
+
+} // namespace
::std::atomic<LogImplementation *> global_top_implementation(NULL);
@@ -14,6 +63,36 @@
cork_data.Reset();
}
+// Used in aos/linux_code/init.cc when a thread's name is changed.
+void ReloadThreadName() {
+ if (my_context.created()) {
+ ::std::string my_name = GetMyName();
+ if (my_name.size() + 1 > sizeof(Context::name)) {
+ Die("logging: process/thread name '%s' is too long\n",
+ my_name.c_str());
+ }
+ strcpy(my_context->name, my_name.c_str());
+ my_context->name_size = my_name.size();
+ }
+}
+
+Context *Context::Get() {
+ if (__builtin_expect(delete_current_context, false)) {
+ my_context.Clear();
+ delete_current_context = false;
+ }
+ if (__builtin_expect(!my_context.created(), false)) {
+ my_context.Create();
+ ReloadThreadName();
+ my_context->source = getpid();
+ }
+ return my_context.get();
+}
+
+void Context::Delete() {
+ delete_current_context = true;
+}
+
} // namespace internal
} // namespace logging
} // namespace aos
diff --git a/aos/common/logging/logging_impl.cc b/aos/common/logging/implementations.cc
similarity index 73%
rename from aos/common/logging/logging_impl.cc
rename to aos/common/logging/implementations.cc
index 34c3816..2f17f7a 100644
--- a/aos/common/logging/logging_impl.cc
+++ b/aos/common/logging/implementations.cc
@@ -1,35 +1,36 @@
-#include "aos/common/logging/logging_impl.h"
+#include "aos/common/logging/implementations.h"
#include <stdarg.h>
#include <inttypes.h>
+#include <algorithm>
+
+#include "aos/common/die.h"
#include "aos/common/once.h"
#include "aos/common/time.h"
#include "aos/common/queue_types.h"
-#include "aos/common/logging/logging_printf_formats.h"
+#include "aos/common/logging/printf_formats.h"
+#include "aos/linux_code/ipc_lib/queue.h"
namespace aos {
namespace logging {
namespace {
-using internal::Context;
-using internal::global_top_implementation;
-
// The root LogImplementation. It only logs to stderr/stdout.
// Some of the things specified in the LogImplementation documentation doesn't
// apply here (mostly the parts about being able to use LOG) because this is the
// root one.
-class RootLogImplementation : public LogImplementation {
+class RootLogImplementation : public SimpleLogImplementation {
public:
void have_other_implementation() { only_implementation_ = false; }
private:
- virtual void set_next(LogImplementation *) {
+ void set_next(LogImplementation *) override {
LOG(FATAL, "can't have a next logger from here\n");
}
__attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 0)))
- virtual void DoLog(log_level level, const char *format, va_list ap) {
+ void DoLog(log_level level, const char *format, va_list ap) override {
LogMessage message;
internal::FillInMessage(level, format, ap, &message);
internal::PrintMessage(stderr, message);
@@ -49,14 +50,14 @@
abort();
}
- Context *context = Context::Get();
+ internal::Context *context = internal::Context::Get();
context->implementation = implementation;
- global_top_implementation.store(implementation);
+ internal::global_top_implementation.store(implementation);
}
void NewContext() {
- Context::Delete();
+ internal::Context::Delete();
}
void *DoInit() {
@@ -215,7 +216,7 @@
} // namespace internal
-void LogImplementation::LogStruct(
+void SimpleLogImplementation::LogStruct(
log_level level, const ::std::string &message, size_t size,
const MessageType *type, const ::std::function<size_t(char *)> &serialize) {
char serialized[1024];
@@ -236,7 +237,7 @@
static_cast<int>(sizeof(printed) - printed_bytes), printed);
}
-void LogImplementation::LogMatrix(
+void SimpleLogImplementation::LogMatrix(
log_level level, const ::std::string &message, uint32_t type_id,
int rows, int cols, const void *data) {
char serialized[1024];
@@ -290,15 +291,8 @@
internal::PrintMessage(stream_, message);
}
-void LogNext(log_level level, const char *format, ...) {
- va_list ap;
- va_start(ap, format);
- LogImplementation::DoVLog(level, format, ap, 2);
- va_end(ap);
-}
-
void AddImplementation(LogImplementation *implementation) {
- Context *context = Context::Get();
+ internal::Context *context = internal::Context::Get();
if (implementation->next() != NULL) {
LOG(FATAL, "%p already has a next implementation, but it's not"
@@ -319,11 +313,109 @@
}
void Load() {
- Context::Get();
+ internal::Context::Get();
}
void Cleanup() {
- Context::Delete();
+ internal::Context::Delete();
+}
+
+namespace {
+
+RawQueue *queue = NULL;
+
+int dropped_messages = 0;
+::aos::time::Time dropped_start, backoff_start;
+// Wait this long after dropping a message before even trying to write any more.
+constexpr ::aos::time::Time kDropBackoff = ::aos::time::Time::InSeconds(0.1);
+
+LogMessage *GetMessageOrDie() {
+ LogMessage *message = static_cast<LogMessage *>(queue->GetMessage());
+ if (message == NULL) {
+ LOG(FATAL, "%p->GetMessage() failed\n", queue);
+ } else {
+ return message;
+ }
+}
+
+void Write(LogMessage *msg) {
+ if (__builtin_expect(dropped_messages > 0, false)) {
+ ::aos::time::Time message_time =
+ ::aos::time::Time(msg->seconds, msg->nseconds);
+ if (message_time - backoff_start < kDropBackoff) {
+ ++dropped_messages;
+ queue->FreeMessage(msg);
+ return;
+ }
+
+ LogMessage *dropped_message = GetMessageOrDie();
+ internal::FillInMessageVarargs(
+ ERROR, dropped_message,
+ "%d logs starting at %" PRId32 ".%" PRId32 " dropped\n",
+ dropped_messages, dropped_start.sec(), dropped_start.nsec());
+ if (queue->WriteMessage(dropped_message, RawQueue::kNonBlock)) {
+ dropped_messages = 0;
+ } else {
+ // Don't even bother trying to write this message because it's not likely
+ // to work and it would be confusing to have one log in the middle of a
+ // string of failures get through.
+ ++dropped_messages;
+ backoff_start = message_time;
+ queue->FreeMessage(msg);
+ return;
+ }
+ }
+ if (!queue->WriteMessage(msg, RawQueue::kNonBlock)) {
+ if (dropped_messages == 0) {
+ dropped_start = backoff_start =
+ ::aos::time::Time(msg->seconds, msg->nseconds);
+ }
+ ++dropped_messages;
+ }
+}
+
+class LinuxQueueLogImplementation : public LogImplementation {
+ __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 0)))
+ void DoLog(log_level level, const char *format, va_list ap) override {
+ LogMessage *message = GetMessageOrDie();
+ internal::FillInMessage(level, format, ap, message);
+ Write(message);
+ }
+
+ void LogStruct(log_level level, const ::std::string &message_string,
+ size_t size, const MessageType *type,
+ const ::std::function<size_t(char *)> &serialize) override {
+ LogMessage *message = GetMessageOrDie();
+ internal::FillInMessageStructure(level, message_string, size, type,
+ serialize, message);
+ Write(message);
+ }
+
+ void LogMatrix(log_level level, const ::std::string &message_string,
+ uint32_t type_id, int rows, int cols,
+ const void *data) override {
+ LogMessage *message = GetMessageOrDie();
+ internal::FillInMessageMatrix(level, message_string, type_id, rows, cols,
+ data, message);
+ Write(message);
+ }
+};
+
+} // namespace
+
+RawQueue *GetLoggingQueue() {
+ return RawQueue::Fetch("LoggingQueue", sizeof(LogMessage), 1323, 40000);
+}
+
+void RegisterQueueImplementation() {
+ Init();
+
+ queue = GetLoggingQueue();
+ if (queue == NULL) {
+ Die("logging: couldn't fetch queue\n");
+ }
+
+ AddImplementation(new LinuxQueueLogImplementation());
}
} // namespace logging
diff --git a/aos/common/logging/logging_impl.h b/aos/common/logging/implementations.h
similarity index 75%
rename from aos/common/logging/logging_impl.h
rename to aos/common/logging/implementations.h
index 5fdeec7..48b5f0b 100644
--- a/aos/common/logging/logging_impl.h
+++ b/aos/common/logging/implementations.h
@@ -1,5 +1,5 @@
-#ifndef AOS_COMMON_LOGGING_LOGGING_IMPL_H_
-#define AOS_COMMON_LOGGING_LOGGING_IMPL_H_
+#ifndef AOS_COMMON_LOGGING_IMPLEMENTATIONS_H_
+#define AOS_COMMON_LOGGING_IMPLEMENTATIONS_H_
#include <sys/types.h>
#include <unistd.h>
@@ -18,25 +18,18 @@
#include "aos/common/mutex.h"
#include "aos/common/macros.h"
#include "aos/common/logging/sizes.h"
-#include "aos/common/logging/logging_interface.h"
+#include "aos/common/logging/interface.h"
#include "aos/common/logging/context.h"
#include "aos/common/once.h"
namespace aos {
struct MessageType;
+class RawQueue;
} // namespace aos
-// This file has all of the logging implementation. It can't be #included by C
-// code like logging.h can.
-// It is useful for the rest of the logging implementation and other C++ code
-// that needs to do special things with logging.
-//
-// It is implemented in logging_impl.cc and logging_interface.cc. They are
-// separate so that code used by logging_impl.cc can link in
-// logging_interface.cc to use logging without creating a circular dependency.
-// However, any executables with such code still need logging_impl.cc linked in.
+// This file has various concrete LogImplementations.
namespace aos {
namespace logging {
@@ -44,9 +37,9 @@
// Unless explicitly stated otherwise, format must always be a string constant,
// args are printf-style arguments for format, and ap is a va_list of args.
// The validity of format and args together will be checked at compile time
-// using a gcc function attribute.
+// using a function attribute.
-// The struct that the code uses for making logging calls.
+// Contains all of the information about a given logging call.
struct LogMessage {
enum class Type : uint8_t {
kString, kStruct, kMatrix
@@ -106,31 +99,30 @@
return LOG_UNKNOWN;
}
-// Will call VLog with the given arguments for the next logger in the chain.
-void LogNext(log_level level, const char *format, ...)
- __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 2, 3)));
-
-// Takes a structure and log it.
-template <class T>
-void DoLogStruct(log_level, const ::std::string &, const T &);
-// Takes a matrix and logs it.
-template <class T>
-void DoLogMatrix(log_level, const ::std::string &, const T &);
-
+// A LogImplementation where LogStruct and LogMatrix just create a string with
+// PrintMessage and then forward on to DoLog.
+class SimpleLogImplementation : public LogImplementation {
+ private:
+ void LogStruct(log_level level, const ::std::string &message, size_t size,
+ const MessageType *type,
+ const ::std::function<size_t(char *)> &serialize) override;
+ void LogMatrix(log_level level, const ::std::string &message,
+ uint32_t type_id, int rows, int cols,
+ const void *data) override;
+};
// Implements all of the DoLog* methods in terms of a (pure virtual in this
// class) HandleMessage method that takes a pointer to the message.
class HandleMessageLogImplementation : public LogImplementation {
- public:
+ private:
__attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 0)))
- virtual void DoLog(log_level level, const char *format, va_list ap) override;
- virtual void LogStruct(log_level level, const ::std::string &message_string,
- size_t size, const MessageType *type,
- const ::std::function<size_t(char *)> &serialize)
- override;
- virtual void LogMatrix(log_level level, const ::std::string &message_string,
- uint32_t type_id, int rows, int cols, const void *data)
- override;
+ void DoLog(log_level level, const char *format, va_list ap) override;
+ void LogStruct(log_level level, const ::std::string &message_string,
+ size_t size, const MessageType *type,
+ const ::std::function<size_t(char *)> &serialize) override;
+ void LogMatrix(log_level level, const ::std::string &message_string,
+ uint32_t type_id, int rows, int cols,
+ const void *data) override;
virtual void HandleMessage(const LogMessage &message) = 0;
};
@@ -141,7 +133,7 @@
StreamLogImplementation(FILE *stream);
private:
- virtual void HandleMessage(const LogMessage &message) override;
+ void HandleMessage(const LogMessage &message) override;
FILE *const stream_;
};
@@ -163,11 +155,22 @@
// Forces all of the state that is usually lazily created when first needed to
// be created when called. Cleanup() will delete it.
void Load();
+
// Resets all information in this task/thread to its initial state.
// NOTE: This is not the opposite of Init(). The state that this deletes is
// lazily created when needed. It is actually the opposite of Load().
void Cleanup();
+// Returns a queue which deals with LogMessage-sized messages.
+// The caller takes ownership.
+RawQueue *GetLoggingQueue();
+
+// Calls AddImplementation to register the standard linux logging implementation
+// which sends the messages through a queue. This implementation relies on
+// another process(es) to read the log messages that it puts into the queue.
+// This function is usually called by aos::Init*.
+void RegisterQueueImplementation();
+
// This is where all of the code that is only used by actual LogImplementations
// goes.
namespace internal {
@@ -209,4 +212,4 @@
} // namespace logging
} // namespace aos
-#endif // AOS_COMMON_LOGGING_LOGGING_IMPL_H_
+#endif // AOS_COMMON_LOGGING_IMPLEMENTATIONS_H_
diff --git a/aos/common/logging/logging_impl_test.cc b/aos/common/logging/implementations_test.cc
similarity index 95%
rename from aos/common/logging/logging_impl_test.cc
rename to aos/common/logging/implementations_test.cc
index dec962b..bbee5b7 100644
--- a/aos/common/logging/logging_impl_test.cc
+++ b/aos/common/logging/implementations_test.cc
@@ -4,9 +4,9 @@
#include "gtest/gtest.h"
-#include "aos/common/logging/logging_impl.h"
+#include "aos/common/logging/implementations.h"
#include "aos/common/time.h"
-#include "aos/common/logging/logging_printf_formats.h"
+#include "aos/common/logging/printf_formats.h"
using ::testing::AssertionResult;
using ::testing::AssertionSuccess;
@@ -16,9 +16,9 @@
namespace logging {
namespace testing {
-class TestLogImplementation : public LogImplementation {
+class TestLogImplementation : public SimpleLogImplementation {
__attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 0)))
- virtual void DoLog(log_level level, const char *format, va_list ap) {
+ void DoLog(log_level level, const char *format, va_list ap) override {
internal::FillInMessage(level, format, ap, &message_);
if (level == FATAL) {
@@ -83,7 +83,7 @@
}
private:
- virtual void SetUp() {
+ void SetUp() override {
static bool first = true;
if (first) {
first = false;
@@ -94,7 +94,7 @@
log_implementation->reset_used();
}
- virtual void TearDown() {
+ void TearDown() override {
Cleanup();
}
@@ -128,7 +128,7 @@
static const int end_line = __LINE__;
LOG_UNCORK(WARNING, "last part %d\n", 5);
std::stringstream expected;
- expected << "logging_impl_test.cc: ";
+ expected << "implementations_test.cc: ";
expected << (begin_line + 1);
expected << "-";
expected << (end_line + 1);
diff --git a/aos/common/logging/logging_interface.cc b/aos/common/logging/interface.cc
similarity index 95%
rename from aos/common/logging/logging_interface.cc
rename to aos/common/logging/interface.cc
index 0a6c968..72431e8 100644
--- a/aos/common/logging/logging_interface.cc
+++ b/aos/common/logging/interface.cc
@@ -1,4 +1,4 @@
-#include "aos/common/logging/logging_interface.h"
+#include "aos/common/logging/interface.h"
#include <stdarg.h>
#include <stdio.h>
@@ -10,9 +10,6 @@
#include "aos/common/die.h"
#include "aos/common/logging/context.h"
-// This file only contains the code necessary to link (ie no implementations).
-// See logging_impl.h for why this is necessary.
-
namespace aos {
namespace logging {
namespace internal {
diff --git a/aos/common/logging/logging_interface.h b/aos/common/logging/interface.h
similarity index 74%
rename from aos/common/logging/logging_interface.h
rename to aos/common/logging/interface.h
index 97587bf..dc59858 100644
--- a/aos/common/logging/logging_interface.h
+++ b/aos/common/logging/interface.h
@@ -1,5 +1,5 @@
-#ifndef AOS_COMMON_LOGGING_LOGGING_INTERFACE_H_
-#define AOS_COMMON_LOGGING_LOGGING_INTERFACE_H_
+#ifndef AOS_COMMON_LOGGING_INTERFACE_H_
+#define AOS_COMMON_LOGGING_INTERFACE_H_
#include <stdarg.h>
@@ -9,14 +9,26 @@
#include "aos/common/logging/logging.h"
#include "aos/common/macros.h"
+// This file has the non-C-compatible parts of the logging client interface.
+
namespace aos {
struct MessageType;
-} // namespace aos
-
-namespace aos {
namespace logging {
+namespace internal {
+
+// Defined in queue_logging.cc.
+void DoLogStruct(log_level level, const ::std::string &message, size_t size,
+ const MessageType *type,
+ const ::std::function<size_t(char *)> &serialize, int levels);
+
+// Defined in matrix_logging.cc.
+void DoLogMatrix(log_level level, const ::std::string &message,
+ uint32_t type_id, int rows, int cols, const void *data,
+ int levels);
+
+} // namespace internal
// Takes a message and logs it. It will set everything up and then call DoLog
// for the current LogImplementation.
@@ -48,7 +60,7 @@
// logger other than this one available while this is called.
virtual void set_next(LogImplementation *next) { next_ = next; }
- private:
+ protected:
// Actually logs the given message. Implementations should somehow create a
// LogMessage and then call internal::FillInMessage.
__attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 0)))
@@ -61,44 +73,36 @@
va_end(ap);
}
- // Logs the contents of an auto-generated structure. The implementation here
- // just converts it to a string with PrintMessage and then calls DoLog with
- // that, however some implementations can be a lot more efficient than that.
+ // Logs the contents of an auto-generated structure.
// size and type are the result of calling Size() and Type() on the type of
// the message.
// serialize will call Serialize on the message.
virtual void LogStruct(log_level level, const ::std::string &message,
size_t size, const MessageType *type,
- const ::std::function<size_t(char *)> &serialize);
+ const ::std::function<size_t(char *)> &serialize) = 0;
// Similiar to LogStruct, except for matrixes.
// type_id is the type of the elements of the matrix.
// data points to rows*cols*type_id.Size() bytes of data in row-major order.
virtual void LogMatrix(log_level level, const ::std::string &message,
uint32_t type_id, int rows, int cols,
- const void *data);
+ const void *data) = 0;
+ private:
// These functions call similar methods on the "current" LogImplementation or
// Die if they can't find one.
// levels is how many LogImplementations to not use off the stack.
static void DoVLog(log_level, const char *format, va_list ap, int levels)
__attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 2, 0)));
- // This one is implemented in queue_logging.cc.
- static void DoLogStruct(log_level level, const ::std::string &message,
- size_t size, const MessageType *type,
- const ::std::function<size_t(char *)> &serialize,
- int levels);
- // This one is implemented in matrix_logging.cc.
- static void DoLogMatrix(log_level level, const ::std::string &message,
- uint32_t type_id, int rows, int cols,
- const void *data, int levels);
- // Friends so that they can access the static Do* functions.
friend void VLog(log_level, const char *, va_list);
- friend void LogNext(log_level, const char *, ...);
- template <class T>
- friend void DoLogStruct(log_level, const ::std::string &, const T &);
- template <class T>
- friend void DoLogMatrix(log_level, const ::std::string &, const T &);
+ friend void internal::DoLogStruct(
+ log_level level, const ::std::string &message, size_t size,
+ const MessageType *type, const ::std::function<size_t(char *)> &serialize,
+ int levels);
+ friend void internal::DoLogMatrix(log_level level,
+ const ::std::string &message,
+ uint32_t type_id, int rows, int cols,
+ const void *data, int levels);
LogImplementation *next_;
};
@@ -121,4 +125,4 @@
} // namespace logging
} // namespace aos
-#endif // AOS_COMMON_LOGGING_LOGGING_INTERFACE_H_
+#endif // AOS_COMMON_LOGGING_INTERFACE_H_
diff --git a/aos/common/logging/linux_interface.cc b/aos/common/logging/linux_interface.cc
deleted file mode 100644
index dff48e1..0000000
--- a/aos/common/logging/linux_interface.cc
+++ /dev/null
@@ -1,89 +0,0 @@
-#include "aos/common/logging/context.h"
-
-#include <string>
-#include <string.h>
-#include <sys/prctl.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "aos/linux_code/complex_thread_local.h"
-#include "aos/common/die.h"
-
-namespace aos {
-namespace logging {
-namespace internal {
-namespace {
-
-// TODO(brians): Differentiate between threads with the same name in the same
-// process.
-
-::std::string GetMyName() {
- // The maximum number of characters that can make up a thread name.
- // The docs are unclear if it can be 16 characters with no '\0', so we'll be
- // safe by adding our own where necessary.
- static const size_t kThreadNameLength = 16;
-
- ::std::string process_name(program_invocation_short_name);
-
- char thread_name_array[kThreadNameLength + 1];
- if (prctl(PR_GET_NAME, thread_name_array) != 0) {
- PDie("prctl(PR_GET_NAME, %p) failed", thread_name_array);
- }
- thread_name_array[sizeof(thread_name_array) - 1] = '\0';
- ::std::string thread_name(thread_name_array);
-
- // If the first bunch of characters are the same.
- // We cut off comparing at the shorter of the 2 strings because one or the
- // other often ends up cut off.
- if (strncmp(thread_name.c_str(), process_name.c_str(),
- ::std::min(thread_name.length(), process_name.length())) == 0) {
- // This thread doesn't have an actual name.
- return process_name;
- }
-
- return process_name + '.' + thread_name;
-}
-
-::aos::ComplexThreadLocal<Context> my_context;
-
-// True if we're going to delete the current Context object ASAP. The
-// reason for doing this instead of just deleting them is that tsan (at least)
-// doesn't like it when pthread_atfork handlers do complicated stuff and it's
-// not a great idea anyways.
-thread_local bool delete_current_context(false);
-
-} // namespace
-
-// Used in aos/linux_code/init.cc when a thread's name is changed.
-void ReloadThreadName() {
- if (my_context.created()) {
- ::std::string my_name = GetMyName();
- if (my_name.size() + 1 > sizeof(Context::name)) {
- Die("logging: process/thread name '%s' is too long\n",
- my_name.c_str());
- }
- strcpy(my_context->name, my_name.c_str());
- my_context->name_size = my_name.size();
- }
-}
-
-Context *Context::Get() {
- if (__builtin_expect(delete_current_context, false)) {
- my_context.Clear();
- delete_current_context = false;
- }
- if (__builtin_expect(!my_context.created(), false)) {
- my_context.Create();
- ReloadThreadName();
- my_context->source = getpid();
- }
- return my_context.get();
-}
-
-void Context::Delete() {
- delete_current_context = true;
-}
-
-} // namespace internal
-} // namespace logging
-} // namespace aos
diff --git a/aos/common/logging/linux_logging.cc b/aos/common/logging/linux_logging.cc
deleted file mode 100644
index 14ce72b..0000000
--- a/aos/common/logging/linux_logging.cc
+++ /dev/null
@@ -1,145 +0,0 @@
-#include "aos/common/logging/linux_logging.h"
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <unistd.h>
-#include <limits.h>
-#include <inttypes.h>
-
-#include <algorithm>
-
-#include "aos/common/die.h"
-#include "aos/common/logging/logging_interface.h"
-#include "aos/linux_code/ipc_lib/queue.h"
-#include "aos/common/time.h"
-
-namespace aos {
-namespace logging {
-namespace linux_code {
-namespace {
-
-RawQueue *queue = NULL;
-
-int dropped_messages = 0;
-::aos::time::Time dropped_start, backoff_start;
-// Wait this long after dropping a message before even trying to write any more.
-constexpr ::aos::time::Time kDropBackoff = ::aos::time::Time::InSeconds(0.1);
-
-LogMessage *GetMessageOrDie() {
- LogMessage *message = static_cast<LogMessage *>(queue->GetMessage());
- if (message == NULL) {
- LOG(FATAL, "%p->GetMessage() failed\n", queue);
- } else {
- return message;
- }
-}
-
-class LinuxQueueLogImplementation : public LogImplementation {
- __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 0)))
- virtual void DoLog(log_level level, const char *format, va_list ap) override {
- LogMessage *message = GetMessageOrDie();
- internal::FillInMessage(level, format, ap, message);
- Write(message);
- }
-
- virtual void LogStruct(log_level level, const ::std::string &message_string,
- size_t size, const MessageType *type,
- const ::std::function<size_t(char *)> &serialize)
- override {
- LogMessage *message = GetMessageOrDie();
- internal::FillInMessageStructure(level, message_string, size, type,
- serialize, message);
- Write(message);
- }
-
- virtual void LogMatrix(log_level level, const ::std::string &message_string,
- uint32_t type_id, int rows, int cols, const void *data)
- override {
- LogMessage *message = GetMessageOrDie();
- internal::FillInMessageMatrix(level, message_string, type_id, rows, cols,
- data, message);
- Write(message);
- }
-};
-
-} // namespace
-
-void Register() {
- Init();
-
- queue = RawQueue::Fetch("LoggingQueue", sizeof(LogMessage), 1323, 40000);
- if (queue == NULL) {
- Die("logging: couldn't fetch queue\n");
- }
-
- AddImplementation(new LinuxQueueLogImplementation());
-}
-
-const LogMessage *ReadNext(Options<RawQueue> flags, int *index) {
- return static_cast<const LogMessage *>(queue->ReadMessageIndex(flags, index));
-}
-
-const LogMessage *ReadNext() {
- return ReadNext(RawQueue::kBlock);
-}
-
-const LogMessage *ReadNext(Options<RawQueue> flags) {
- const LogMessage *r = NULL;
- do {
- r = static_cast<const LogMessage *>(queue->ReadMessage(flags));
- // not blocking means return a NULL if that's what it gets
- } while ((flags & RawQueue::kBlock) && r == NULL);
- return r;
-}
-
-LogMessage *Get() {
- return static_cast<LogMessage *>(queue->GetMessage());
-}
-
-void Free(const LogMessage *msg) {
- queue->FreeMessage(msg);
-}
-
-void Write(LogMessage *msg) {
- if (__builtin_expect(dropped_messages > 0, false)) {
- ::aos::time::Time message_time =
- ::aos::time::Time(msg->seconds, msg->nseconds);
- if (message_time - backoff_start < kDropBackoff) {
- ++dropped_messages;
- queue->FreeMessage(msg);
- return;
- }
-
- LogMessage *dropped_message = GetMessageOrDie();
- internal::FillInMessageVarargs(
- ERROR, dropped_message,
- "%d logs starting at %" PRId32 ".%" PRId32 " dropped\n",
- dropped_messages, dropped_start.sec(), dropped_start.nsec());
- if (queue->WriteMessage(dropped_message, RawQueue::kNonBlock)) {
- dropped_messages = 0;
- } else {
- // Don't even bother trying to write this message because it's not likely
- // to work and it would be confusing to have one log in the middle of a
- // string of failures get through.
- ++dropped_messages;
- backoff_start = message_time;
- queue->FreeMessage(msg);
- return;
- }
- }
- if (!queue->WriteMessage(msg, RawQueue::kNonBlock)) {
- if (dropped_messages == 0) {
- dropped_start = backoff_start =
- ::aos::time::Time(msg->seconds, msg->nseconds);
- }
- ++dropped_messages;
- }
-}
-
-} // namespace linux_code
-} // namespace logging
-} // namespace aos
diff --git a/aos/common/logging/linux_logging.h b/aos/common/logging/linux_logging.h
deleted file mode 100644
index 3f74fa8..0000000
--- a/aos/common/logging/linux_logging.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef AOS_COMMON_LOGGING_LINUX_LOGGING_H_
-#define AOS_COMMON_LOGGING_LINUX_LOGGING_H_
-
-#include "aos/common/logging/logging_impl.h"
-#include "aos/common/util/options.h"
-
-namespace aos {
-
-class RawQueue;
-
-namespace logging {
-namespace linux_code {
-
-// Calls AddImplementation to register the usual linux logging implementation
-// which sends the messages through a queue. This implementation relies on
-// another process(es) to read the log messages that it puts into the queue.
-// This function is usually called by aos::Init*.
-void Register();
-
-// Fairly simple wrappers around the raw queue calls.
-
-// This one never returns NULL if flags contains BLOCK.
-const LogMessage *ReadNext(Options<RawQueue> flags);
-const LogMessage *ReadNext(Options<RawQueue> flags, int *index);
-const LogMessage *ReadNext();
-LogMessage *Get();
-void Free(const LogMessage *msg);
-void Write(LogMessage *msg);
-
-} // namespace linux_code
-} // namespace logging
-} // namespace aos
-
-#endif // AOS_COMMON_LOGGING_LINUX_LOGGING_H_
diff --git a/aos/common/logging/log_displayer.cc b/aos/common/logging/log_displayer.cc
index 70d2ad5..fba48c4 100644
--- a/aos/common/logging/log_displayer.cc
+++ b/aos/common/logging/log_displayer.cc
@@ -14,8 +14,9 @@
#include "aos/linux_code/configuration.h"
#include "aos/common/logging/binary_log_file.h"
#include "aos/common/queue_types.h"
-#include "aos/common/logging/logging_impl.h"
-#include "aos/common/logging/logging_printf_formats.h"
+#include "aos/common/logging/logging.h"
+#include "aos/common/logging/implementations.h"
+#include "aos/common/logging/printf_formats.h"
#include "aos/common/util/string_to_num.h"
using ::aos::logging::linux_code::LogFileMessageHeader;
diff --git a/aos/common/logging/log_streamer.cc b/aos/common/logging/log_streamer.cc
index 506a92b..f214d99 100644
--- a/aos/common/logging/log_streamer.cc
+++ b/aos/common/logging/log_streamer.cc
@@ -10,10 +10,10 @@
#include <fcntl.h>
#include <inttypes.h>
-#include "aos/common/logging/linux_logging.h"
#include "aos/linux_code/init.h"
#include "aos/linux_code/ipc_lib/queue.h"
-#include "aos/common/logging/logging_impl.h"
+#include "aos/common/logging/logging.h"
+#include "aos/common/logging/implementations.h"
#include "aos/common/time.h"
namespace aos {
@@ -24,17 +24,20 @@
int LogStreamerMain() {
InitNRT();
+ RawQueue *queue = GetLoggingQueue();
+
const time::Time now = time::Time::Now();
printf("starting at %" PRId32 "s%" PRId32 "ns-----------------------------\n",
now.sec(), now.nsec());
while (true) {
- const LogMessage *const msg = ReadNext();
+ const LogMessage *const msg =
+ static_cast<const LogMessage *>(queue->ReadMessage(RawQueue::kBlock));
if (msg == NULL) continue;
internal::PrintMessage(stdout, *msg);
- logging::linux_code::Free(msg);
+ queue->FreeMessage(msg);
}
Cleanup();
diff --git a/aos/common/logging/matrix_logging-tmpl.h b/aos/common/logging/matrix_logging-tmpl.h
deleted file mode 100644
index 9e458fb..0000000
--- a/aos/common/logging/matrix_logging-tmpl.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#include "aos/common/logging/logging_impl.h"
-
-#include <functional>
-
-#include "aos/common/queue_primitives.h"
-
-namespace aos {
-namespace logging {
-
-template <class T>
-void DoLogMatrix(log_level level, const ::std::string &message,
- const T &matrix) {
- static_assert(!T::IsRowMajor, "we only handle column-major storage");
- LogImplementation::DoLogMatrix(level, message, TypeID<typename T::Scalar>::id,
- matrix.rows(), matrix.cols(), matrix.data(),
- 1);
-}
-
-} // namespace logging
-} // namespace aos
diff --git a/aos/common/logging/matrix_logging.cc b/aos/common/logging/matrix_logging.cc
index 6173074..7c90632 100644
--- a/aos/common/logging/matrix_logging.cc
+++ b/aos/common/logging/matrix_logging.cc
@@ -1,18 +1,21 @@
#include "aos/common/logging/matrix_logging.h"
#include "aos/common/queue_types.h"
+#include "aos/common/logging/sizes.h"
namespace aos {
namespace logging {
+namespace internal {
-void LogImplementation::DoLogMatrix(log_level level,
- const ::std::string &message,
- uint32_t type_id, int rows, int cols,
- const void *data, int levels) {
- internal::RunWithCurrentImplementation(
- levels, [&](LogImplementation * implementation) {
- implementation->LogMatrix(level, message, type_id, rows, cols, data);
- });
+void DoLogMatrix(log_level level, const ::std::string &message,
+ uint32_t type_id, int rows, int cols, const void *data,
+ int levels) {
+ {
+ auto fn = [&](LogImplementation *implementation) {
+ implementation->LogMatrix(level, message, type_id, rows, cols, data);
+ };
+ RunWithCurrentImplementation(levels, ::std::ref(fn));
+ }
if (level == FATAL) {
char serialized[1024];
@@ -31,5 +34,6 @@
}
}
+} // namespace internal
} // namespace logging
} // namespace aos
diff --git a/aos/common/logging/matrix_logging.h b/aos/common/logging/matrix_logging.h
index 6efaa06..e763ed5 100644
--- a/aos/common/logging/matrix_logging.h
+++ b/aos/common/logging/matrix_logging.h
@@ -2,35 +2,39 @@
#define AOS_COMMON_LOGGING_MATRIX_LOGGING_H_
#include <string>
+#include <functional>
#include "Eigen/Dense"
-#include "aos/common/logging/logging.h"
+#include "aos/common/logging/interface.h"
#include "aos/common/die.h"
+#include "aos/common/queue_primitives.h"
namespace aos {
namespace logging {
// Logs the contents of a matrix and a constant string.
// matrix must be an instance of an Eigen matrix (or something similar).
-#define LOG_MATRIX(level, message, matrix) \
- do { \
- static const ::std::string kAosLoggingMessage( \
- LOG_SOURCENAME ": " STRINGIFY(__LINE__) ": " message); \
- ::aos::logging::DoLogMatrix(level, kAosLoggingMessage, matrix); \
- /* so that GCC knows that it won't return */ \
- if (level == FATAL) { \
- ::aos::Die("DoLogStruct(FATAL) fell through!!!!!\n"); \
- } \
+#define LOG_MATRIX(level, message, matrix) \
+ do { \
+ static const ::std::string kAosLoggingMessage( \
+ LOG_SOURCENAME ": " STRINGIFY(__LINE__) ": " message); \
+ ::aos::logging::DoLogMatrixTemplated(level, kAosLoggingMessage, matrix); \
+ /* so that GCC knows that it won't return */ \
+ if (level == FATAL) { \
+ ::aos::Die("DoLogStruct(FATAL) fell through!!!!!\n"); \
+ } \
} while (false)
template <class T>
-void DoLogMatrix(log_level level, const ::std::string &message,
- const T &matrix);
+void DoLogMatrixTemplated(log_level level, const ::std::string &message,
+ const T &matrix) {
+ static_assert(!T::IsRowMajor, "we only handle column-major storage");
+ internal::DoLogMatrix(level, message, TypeID<typename T::Scalar>::id,
+ matrix.rows(), matrix.cols(), matrix.data(), 1);
+}
} // namespace logging
} // namespace aos
-#include "aos/common/logging/matrix_logging-tmpl.h"
-
#endif // AOS_COMMON_LOGGING_MATRIX_LOGGING_H_
diff --git a/aos/common/logging/logging_printf_formats.h b/aos/common/logging/printf_formats.h
similarity index 86%
rename from aos/common/logging/logging_printf_formats.h
rename to aos/common/logging/printf_formats.h
index 57a83c3..b098865 100644
--- a/aos/common/logging/logging_printf_formats.h
+++ b/aos/common/logging/printf_formats.h
@@ -1,5 +1,5 @@
-#ifndef AOS_COMMON_LOGGING_LOGGING_PRINTF_FORMATS_H_
-#define AOS_COMMON_LOGGING_LOGGING_PRINTF_FORMATS_H_
+#ifndef AOS_COMMON_LOGGING_PRINTF_FORMATS_H_
+#define AOS_COMMON_LOGGING_PRINTF_FORMATS_H_
#include "aos/common/macros.h"
@@ -7,7 +7,7 @@
// times and log messages.
// They are all split out as macros because there are 2 things that want to
// print using the same format: log_displayer and PrintMessage in
-// logging_impl.cc.
+// implementations.cc.
#define AOS_TIME_FORMAT \
"%010" PRId32 ".%0" STRINGIFY(AOS_TIME_NSECONDS_DIGITS) PRId32 "s"
@@ -27,4 +27,4 @@
#define AOS_TIME_NSECONDS_DIGITS 6
#define AOS_TIME_NSECONDS_DENOMINATOR 1000
-#endif // AOS_COMMON_LOGGING_LOGGING_PRINTF_FORMATS_H_
+#endif // AOS_COMMON_LOGGING_PRINTF_FORMATS_H_
diff --git a/aos/common/logging/queue_logging-tmpl.h b/aos/common/logging/queue_logging-tmpl.h
deleted file mode 100644
index b4c3696..0000000
--- a/aos/common/logging/queue_logging-tmpl.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#include "aos/common/logging/logging_impl.h"
-
-#include <functional>
-
-namespace aos {
-namespace logging {
-
-template <class T>
-void DoLogStruct(log_level level, const ::std::string &message,
- const T &structure) {
- auto fn = [&structure](char *buffer)
- -> size_t { return structure.Serialize(buffer); };
-
- LogImplementation::DoLogStruct(level, message, T::Size(), T::GetType(),
- ::std::ref(fn), 1);
-}
-
-} // namespace logging
-} // namespace aos
diff --git a/aos/common/logging/queue_logging.cc b/aos/common/logging/queue_logging.cc
index 14559fb..0f1227c 100644
--- a/aos/common/logging/queue_logging.cc
+++ b/aos/common/logging/queue_logging.cc
@@ -1,21 +1,21 @@
#include "aos/common/logging/queue_logging.h"
-#include "aos/common/logging/logging_impl.h"
+#include "aos/common/logging/interface.h"
+#include "aos/common/logging/sizes.h"
#include "aos/common/queue_types.h"
namespace aos {
namespace logging {
+namespace internal {
-void LogImplementation::DoLogStruct(
- log_level level, const ::std::string &message, size_t size,
- const MessageType *type, const ::std::function<size_t(char *)> &serialize,
- int levels) {
-
+void DoLogStruct(log_level level, const ::std::string &message, size_t size,
+ const MessageType *type,
+ const ::std::function<size_t(char *)> &serialize, int levels) {
{
auto fn = [&](LogImplementation *implementation) {
implementation->LogStruct(level, message, size, type, serialize);
};
- internal::RunWithCurrentImplementation(levels, ::std::ref(fn));
+ RunWithCurrentImplementation(levels, ::std::ref(fn));
}
if (level == FATAL) {
@@ -34,5 +34,6 @@
}
}
+} // namespace internal
} // namespace logging
} // namespace aos
diff --git a/aos/common/logging/queue_logging.h b/aos/common/logging/queue_logging.h
index ff0167a..888f808 100644
--- a/aos/common/logging/queue_logging.h
+++ b/aos/common/logging/queue_logging.h
@@ -4,9 +4,10 @@
#include <stdio.h>
#include <stdlib.h>
+#include <functional>
#include <string>
-#include "aos/common/logging/logging.h"
+#include "aos/common/logging/interface.h"
#include "aos/common/die.h"
namespace aos {
@@ -14,24 +15,29 @@
// Logs the contents of a structure (or Queue message) and a constant string.
// structure must be an instance of one of the generated queue types.
-#define LOG_STRUCT(level, message, structure) \
- do { \
- static const ::std::string kAosLoggingMessage( \
- LOG_SOURCENAME ": " STRINGIFY(__LINE__) ": " message); \
- ::aos::logging::DoLogStruct(level, kAosLoggingMessage, structure); \
- /* so that GCC knows that it won't return */ \
- if (level == FATAL) { \
- ::aos::Die("DoLogStruct(FATAL) fell through!!!!!\n"); \
- } \
+#define LOG_STRUCT(level, message, structure) \
+ do { \
+ static const ::std::string kAosLoggingMessage( \
+ LOG_SOURCENAME ": " STRINGIFY(__LINE__) ": " message); \
+ ::aos::logging::DoLogStructTemplated(level, kAosLoggingMessage, \
+ structure); \
+ /* so that GCC knows that it won't return */ \
+ if (level == FATAL) { \
+ ::aos::Die("DoLogStruct(FATAL) fell through!!!!!\n"); \
+ } \
} while (false)
template <class T>
-void DoLogStruct(log_level level, const ::std::string &message,
- const T &structure);
+void DoLogStructTemplated(log_level level, const ::std::string &message,
+ const T &structure) {
+ auto fn = [&structure](char *buffer)
+ -> size_t { return structure.Serialize(buffer); };
+
+ internal::DoLogStruct(level, message, T::Size(), T::GetType(), ::std::ref(fn),
+ 1);
+}
} // namespace logging
} // namespace aos
-#include "aos/common/logging/queue_logging-tmpl.h"
-
#endif // AOS_COMMON_LOGGING_QUEUE_LOGGING_H_
diff --git a/aos/common/logging/log_replay.cc b/aos/common/logging/replay.cc
similarity index 96%
rename from aos/common/logging/log_replay.cc
rename to aos/common/logging/replay.cc
index a1efcca..7180c96 100644
--- a/aos/common/logging/log_replay.cc
+++ b/aos/common/logging/replay.cc
@@ -1,4 +1,4 @@
-#include "aos/common/logging/log_replay.h"
+#include "aos/common/logging/replay.h"
namespace aos {
namespace logging {
diff --git a/aos/common/logging/log_replay.h b/aos/common/logging/replay.h
similarity index 97%
rename from aos/common/logging/log_replay.h
rename to aos/common/logging/replay.h
index 6fb230c..38f7120 100644
--- a/aos/common/logging/log_replay.h
+++ b/aos/common/logging/replay.h
@@ -1,5 +1,5 @@
-#ifndef AOS_COMMON_LOGGING_LOG_REPLAY_H_
-#define AOS_COMMON_LOGGING_LOG_REPLAY_H_
+#ifndef AOS_COMMON_LOGGING_REPLAY_H_
+#define AOS_COMMON_LOGGING_REPLAY_H_
#include <unordered_map>
#include <string>
@@ -161,4 +161,4 @@
} // namespace logging
} // namespace aos
-#endif // AOS_COMMON_LOGGING_LOG_REPLAY_H_
+#endif // AOS_COMMON_LOGGING_REPLAY_H_
diff --git a/aos/common/queue_testutils.cc b/aos/common/queue_testutils.cc
index a40b5e9..5843e67 100644
--- a/aos/common/queue_testutils.cc
+++ b/aos/common/queue_testutils.cc
@@ -8,7 +8,7 @@
#include "gtest/gtest.h"
#include "aos/common/queue.h"
-#include "aos/common/logging/logging_impl.h"
+#include "aos/common/logging/implementations.h"
#include "aos/common/once.h"
#include "aos/common/mutex.h"
diff --git a/aos/common/util/BUILD b/aos/common/util/BUILD
index d176733..35d8e87 100644
--- a/aos/common/util/BUILD
+++ b/aos/common/util/BUILD
@@ -9,7 +9,7 @@
'run_command.h',
],
deps = [
- '//aos/common/logging:logging_interface',
+ '//aos/common/logging',
],
)
@@ -32,7 +32,7 @@
'death_test_log_implementation.h',
],
deps = [
- '//aos/common/logging',
+ '//aos/common/logging:implementations',
],
)
@@ -104,7 +104,7 @@
],
deps = [
'//aos/common:macros',
- '//aos/common/logging:logging_interface',
+ '//aos/common/logging',
],
)
diff --git a/aos/common/util/death_test_log_implementation.h b/aos/common/util/death_test_log_implementation.h
index c1b12c0..c1b1da2 100644
--- a/aos/common/util/death_test_log_implementation.h
+++ b/aos/common/util/death_test_log_implementation.h
@@ -3,7 +3,7 @@
#include <stdlib.h>
-#include "aos/common/logging/logging_impl.h"
+#include "aos/common/logging/implementations.h"
namespace aos {
namespace util {
diff --git a/aos/linux_code/BUILD b/aos/linux_code/BUILD
index b0c88b5..7adb3d6 100644
--- a/aos/linux_code/BUILD
+++ b/aos/linux_code/BUILD
@@ -7,6 +7,7 @@
],
deps = [
'//aos/common/logging',
+ '//aos/common/logging:implementations',
'//aos/common:time',
],
)
@@ -58,7 +59,7 @@
deps = [
'//aos/linux_code/ipc_lib:shared_mem',
'//aos/common:die',
- '//aos/common/logging:linux_logging',
+ '//aos/common/logging:implementations',
],
)
diff --git a/aos/linux_code/dump_rtprio.cc b/aos/linux_code/dump_rtprio.cc
index cae69f1..2bfb9c1 100644
--- a/aos/linux_code/dump_rtprio.cc
+++ b/aos/linux_code/dump_rtprio.cc
@@ -17,7 +17,7 @@
#include <string>
#include "aos/common/logging/logging.h"
-#include "aos/common/logging/logging_impl.h"
+#include "aos/common/logging/implementations.h"
#include "aos/common/time.h"
namespace {
diff --git a/aos/linux_code/init.cc b/aos/linux_code/init.cc
index cf54fb9..80c71e3 100644
--- a/aos/linux_code/init.cc
+++ b/aos/linux_code/init.cc
@@ -14,7 +14,7 @@
#include <malloc.h>
#include "aos/common/die.h"
-#include "aos/common/logging/linux_logging.h"
+#include "aos/common/logging/implementations.h"
#include "aos/linux_code/ipc_lib/shared_mem.h"
namespace FLAG__namespace_do_not_use_directly_use_DECLARE_double_instead {
@@ -27,7 +27,7 @@
namespace logging {
namespace internal {
-// Implemented in aos/common/logging/linux_interface.cc.
+// Implemented in aos/common/logging/context.cc.
void ReloadThreadName();
} // namespace internal
@@ -98,13 +98,13 @@
void InitNRT() {
InitStart();
aos_core_create_shared_mem(false, false);
- logging::linux_code::Register();
+ logging::RegisterQueueImplementation();
}
void InitCreate() {
InitStart();
aos_core_create_shared_mem(true, false);
- logging::linux_code::Register();
+ logging::RegisterQueueImplementation();
}
void Init(int relative_priority) {
@@ -133,7 +133,7 @@
InitStart();
aos_core_create_shared_mem(false, realtime);
- logging::linux_code::Register();
+ logging::RegisterQueueImplementation();
}
void Cleanup() {
diff --git a/aos/linux_code/ipc_lib/BUILD b/aos/linux_code/ipc_lib/BUILD
index 2b90c34..8f26882 100644
--- a/aos/linux_code/ipc_lib/BUILD
+++ b/aos/linux_code/ipc_lib/BUILD
@@ -9,7 +9,7 @@
'aos_sync.h',
],
deps = [
- '//aos/common/logging:logging_interface',
+ '//aos/common/logging',
'//aos/common:once',
'//aos/common:macros',
],
@@ -41,7 +41,7 @@
':aos_sync',
':core_lib',
':shared_mem_types',
- '//aos/common/logging:logging_interface',
+ '//aos/common/logging',
'//debian:librt',
],
)
@@ -71,7 +71,7 @@
'//aos/common:mutex',
':core_lib',
':shared_mem',
- '//aos/common/logging:logging_interface',
+ '//aos/common/logging',
'//debian:librt',
'//aos/common/util:options',
],
diff --git a/aos/linux_code/starter/BUILD b/aos/linux_code/starter/BUILD
index 5e3ac38..ec6ce7f 100644
--- a/aos/linux_code/starter/BUILD
+++ b/aos/linux_code/starter/BUILD
@@ -17,6 +17,7 @@
'//aos/linux_code:init',
'//third_party/libevent',
'//aos/common/logging',
+ '//aos/common/logging:implementations',
'//aos/common:once',
'//aos/common:time',
'//aos/common/libc:aos_strsignal',
diff --git a/aos/linux_code/starter/starter.cc b/aos/linux_code/starter/starter.cc
index a2545c2..855653d 100644
--- a/aos/linux_code/starter/starter.cc
+++ b/aos/linux_code/starter/starter.cc
@@ -30,7 +30,7 @@
#include "third_party/libevent/event.h"
#include "aos/common/logging/logging.h"
-#include "aos/common/logging/logging_impl.h"
+#include "aos/common/logging/implementations.h"
#include "aos/linux_code/init.h"
#include "aos/common/unique_malloc_ptr.h"
#include "aos/common/time.h"
diff --git a/y2015/actors/BUILD b/y2015/actors/BUILD
index 86a29d1..e561440 100644
--- a/y2015/actors/BUILD
+++ b/y2015/actors/BUILD
@@ -73,7 +73,7 @@
'fridge_profile_lib.h',
],
deps = [
- '//aos/common/logging:logging_interface',
+ '//aos/common/logging',
'//aos/common/actions:action_lib',
'//y2015/control_loops/fridge:fridge_queue',
],