Remove old logger

We don't need the old queue logger and log reader.

Change-Id: I108fbd3e3e6fdf3a87083ca42cb2deeedd2b5761
diff --git a/aos/logging/BUILD b/aos/logging/BUILD
index 68a493b..0ba9931 100644
--- a/aos/logging/BUILD
+++ b/aos/logging/BUILD
@@ -34,69 +34,6 @@
     ],
 )
 
-cc_binary(
-    name = "binary_log_writer",
-    srcs = [
-        "binary_log_writer.cc",
-    ],
-    visibility = ["//visibility:public"],
-    deps = [
-        ":binary_log_file",
-        ":implementations",
-        ":log_namer",
-        ":logging",
-        "//aos:configuration",
-        "//aos:die",
-        "//aos:init",
-        "//aos/ipc_lib:queue",
-        "//aos/time",
-    ],
-)
-
-cc_binary(
-    name = "log_streamer",
-    srcs = [
-        "log_streamer.cc",
-    ],
-    visibility = ["//visibility:public"],
-    deps = [
-        ":implementations",
-        ":logging",
-        "//aos:init",
-        "//aos/ipc_lib:queue",
-        "//aos/time",
-    ],
-)
-
-cc_binary(
-    name = "log_displayer",
-    srcs = [
-        "log_displayer.cc",
-    ],
-    visibility = ["//visibility:public"],
-    deps = [
-        ":binary_log_file",
-        ":implementations",
-        ":logging",
-        "//aos:configuration",
-        "//aos:init",
-        "//aos/util:string_to_num",
-    ],
-)
-
-cc_library(
-    name = "binary_log_file",
-    srcs = [
-        "binary_log_file.cc",
-    ],
-    hdrs = [
-        "binary_log_file.h",
-    ],
-    deps = [
-        ":implementations",
-    ],
-)
-
 cc_library(
     name = "sizes",
     hdrs = [
diff --git a/aos/logging/binary_log_file.cc b/aos/logging/binary_log_file.cc
deleted file mode 100644
index 9ea5c82..0000000
--- a/aos/logging/binary_log_file.cc
+++ /dev/null
@@ -1,265 +0,0 @@
-#include "aos/logging/binary_log_file.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <signal.h>
-#include <setjmp.h>
-
-namespace aos {
-namespace logging {
-namespace linux_code {
-namespace {
-
-unsigned long SystemPageSize() {
-  static unsigned long r = sysconf(_SC_PAGESIZE);
-  return r;
-}
-
-}  // namespace
-
-LogFileAccessor::LogFileAccessor(int fd, bool writable)
-    : fd_(fd), writable_(writable), offset_(0), current_(0), position_(0) {
-  // Check to make sure that mmap will allow mmaping in chunks of kPageSize.
-  if (SystemPageSize() > kPageSize || (kPageSize % SystemPageSize()) != 0) {
-    AOS_LOG(FATAL, "system page size (%lu) not factor of kPageSize (%zd).\n",
-            SystemPageSize(), kPageSize);
-  }
-
-  MapNextPage();
-}
-
-void LogFileAccessor::Sync() const {
-  msync(current_, kPageSize, MS_ASYNC | MS_INVALIDATE);
-}
-
-void LogFileAccessor::SkipToLastSeekablePage() {
-  AOS_CHECK(definitely_use_mmap());
-
-  struct stat info;
-  if (fstat(fd_, &info) == -1) {
-    AOS_PLOG(FATAL, "fstat(%d, %p) failed", fd_, &info);
-  }
-
-  AOS_CHECK((info.st_size % kPageSize) == 0);
-  const auto last_readable_page_number = (info.st_size / kPageSize) - 1;
-  const auto last_seekable_page_number =
-      last_readable_page_number / kSeekPages * kSeekPages;
-  const off_t new_offset = last_seekable_page_number * kPageSize;
-  // We don't want to go backwards...
-  if (new_offset > offset_) {
-    Unmap(current_);
-    offset_ = new_offset;
-    MapNextPage();
-  }
-}
-
-// The only way to tell is using fstat, but we don't really want to be making a
-// syscall every single time somebody wants to know the answer, so it gets
-// cached in is_last_page_.
-bool LogFileAccessor::IsLastPage() {
-  if (is_last_page_ != Maybe::kUnknown) {
-    return is_last_page_ == Maybe::kYes;
-  }
-
-  struct stat info;
-  if (fstat(fd_, &info) == -1) {
-    AOS_PLOG(FATAL, "fstat(%d, %p) failed", fd_, &info);
-  }
-  bool r = offset_ == static_cast<off_t>(info.st_size - kPageSize);
-  is_last_page_ = r ? Maybe::kYes : Maybe::kNo;
-  return r;
-}
-
-void LogFileAccessor::MapNextPage() {
-  if (writable_) {
-    if (ftruncate(fd_, offset_ + kPageSize) == -1) {
-      AOS_PLOG(FATAL, "ftruncate(%d, %zd) failed", fd_, kPageSize);
-    }
-  }
-
-  if (use_read_ == Maybe::kYes) {
-    ssize_t todo = kPageSize;
-    while (todo > 0) {
-      ssize_t result = read(fd_, current_ + (kPageSize - todo), todo);
-      if (result == -1) {
-        AOS_PLOG(FATAL, "read(%d, %p, %zu) failed", fd_,
-                 current_ + (kPageSize - todo), todo);
-      } else if (result == 0) {
-        memset(current_, 0, todo);
-        result = todo;
-      }
-      todo -= result;
-    }
-    AOS_CHECK_EQ(0, todo);
-  } else {
-    current_ = static_cast<char *>(
-        mmap(NULL, kPageSize, PROT_READ | (writable_ ? PROT_WRITE : 0),
-             MAP_SHARED, fd_, offset_));
-    if (current_ == MAP_FAILED) {
-      if (!writable_ && use_read_ == Maybe::kUnknown && errno == ENODEV) {
-        AOS_LOG(INFO, "Falling back to reading the file using read(2).\n");
-        use_read_ = Maybe::kYes;
-        current_ = new char[kPageSize];
-        MapNextPage();
-        return;
-      } else {
-        AOS_PLOG(
-            FATAL,
-            "mmap(NULL, %zd, PROT_READ [ | PROT_WRITE], MAP_SHARED, %d, %jd)"
-            " failed",
-            kPageSize, fd_, static_cast<intmax_t>(offset_));
-      }
-    } else {
-      use_read_ = Maybe::kNo;
-    }
-    if (madvise(current_, kPageSize, MADV_SEQUENTIAL | MADV_WILLNEED) == -1) {
-      AOS_PLOG(WARNING,
-               "madvise(%p, %zd, MADV_SEQUENTIAL | MADV_WILLNEED) failed",
-               current_, kPageSize);
-    }
-  }
-  offset_ += kPageSize;
-}
-
-void LogFileAccessor::Unmap(void *location) {
-  AOS_CHECK_NE(Maybe::kUnknown, use_read_);
-
-  if (use_read_ == Maybe::kNo) {
-    if (munmap(location, kPageSize) == -1) {
-      AOS_PLOG(FATAL, "munmap(%p, %zd) failed", location, kPageSize);
-    }
-  }
-  is_last_page_ = Maybe::kUnknown;
-  position_ = 0;
-}
-
-const LogFileMessageHeader *LogFileReader::ReadNextMessage(bool wait) {
-  LogFileMessageHeader *r;
-  do {
-    r = static_cast<LogFileMessageHeader *>(
-        static_cast<void *>(&current()[position()]));
-    if (wait) {
-      AOS_CHECK(definitely_use_mmap());
-      if (futex_wait(&r->marker) != 0) continue;
-    }
-    if (r->marker == 2) {
-      Unmap(current());
-      MapNextPage();
-      CheckCurrentPageReadable();
-      r = static_cast<LogFileMessageHeader *>(static_cast<void *>(current()));
-    }
-  } while (wait && r->marker == 0);
-  if (r->marker == 0) {
-    return NULL;
-  }
-  IncrementPosition(sizeof(LogFileMessageHeader) + r->name_size +
-                    r->message_size);
-  if (position() >= kPageSize) {
-    // It's a lot better to blow up here rather than getting SIGBUS errors the
-    // next time we try to read...
-    AOS_LOG(FATAL, "corrupt log file running over page size\n");
-  }
-  return r;
-}
-
-// This mess is because the only not completely hackish way to do this is to set
-// up a handler for SIGBUS/SIGSEGV that siglongjmps out to avoid either the
-// instruction being repeated infinitely (and more signals being delivered) or
-// (with SA_RESETHAND) the signal killing the process.
-namespace {
-
-void *volatile fault_address;
-sigjmp_buf jump_context;
-
-void CheckCurrentPageReadableHandler(int /*signal*/, siginfo_t *info, void *) {
-  fault_address = info->si_addr;
-
-  siglongjmp(jump_context, 1);
-}
-
-}  // namespace
-void LogFileReader::CheckCurrentPageReadable() {
-  if (definitely_use_read()) return;
-
-  if (sigsetjmp(jump_context, 1) == 0) {
-    struct sigaction action;
-    action.sa_sigaction = CheckCurrentPageReadableHandler;
-    sigemptyset(&action.sa_mask);
-    action.sa_flags = SA_RESETHAND | SA_SIGINFO;
-    struct sigaction previous_bus, previous_segv;
-    if (sigaction(SIGBUS, &action, &previous_bus) == -1) {
-      AOS_PLOG(FATAL, "sigaction(SIGBUS(=%d), %p, %p) failed", SIGBUS, &action,
-               &previous_bus);
-    }
-    if (sigaction(SIGSEGV, &action, &previous_segv) == -1) {
-      AOS_PLOG(FATAL, "sigaction(SIGSEGV(=%d), %p, %p) failed", SIGSEGV,
-               &action, &previous_segv);
-    }
-
-    char __attribute__((unused)) c = current()[0];
-
-    if (sigaction(SIGBUS, &previous_bus, NULL) == -1) {
-      AOS_PLOG(FATAL, "sigaction(SIGBUS(=%d), %p, NULL) failed", SIGBUS,
-               &previous_bus);
-    }
-    if (sigaction(SIGSEGV, &previous_segv, NULL) == -1) {
-      AOS_PLOG(FATAL, "sigaction(SIGSEGV(=%d), %p, NULL) failed", SIGSEGV,
-               &previous_segv);
-    }
-  } else {
-    if (fault_address == current()) {
-      AOS_LOG(FATAL, "could not read 1 byte at offset 0x%jx into log file\n",
-              static_cast<uintmax_t>(offset()));
-    } else {
-      AOS_LOG(FATAL, "faulted at %p, not %p like we were (maybe) supposed to\n",
-              fault_address, current());
-    }
-  }
-}
-
-LogFileMessageHeader *LogFileWriter::GetWritePosition(size_t message_size) {
-  if (NeedNewPageFor(message_size)) ForceNewPage();
-  LogFileMessageHeader *const r = static_cast<LogFileMessageHeader *>(
-      static_cast<void *>(&current()[position()]));
-  IncrementPosition(message_size);
-  return r;
-}
-
-// A number of seekable pages, not the actual file offset, is stored in *cookie.
-bool LogFileWriter::ShouldClearSeekableData(off_t *cookie,
-                                            size_t next_message_size) const {
-  off_t next_message_page = (offset() / kPageSize) - 1;
-  if (NeedNewPageFor(next_message_size)) {
-    ++next_message_page;
-  }
-  const off_t current_seekable_page = next_message_page / kSeekPages;
-  AOS_CHECK_LE(*cookie, current_seekable_page);
-  const bool r = *cookie != current_seekable_page;
-  *cookie = current_seekable_page;
-  return r;
-}
-
-bool LogFileWriter::NeedNewPageFor(size_t bytes) const {
-  return position() + bytes + (kAlignment - (bytes % kAlignment)) +
-             sizeof(aos_futex) >
-         kPageSize;
-}
-
-void LogFileWriter::ForceNewPage() {
-  char *const temp = current();
-  MapNextPage();
-  if (futex_set_value(
-          static_cast<aos_futex *>(static_cast<void *>(&temp[position()])),
-          2) == -1) {
-    AOS_PLOG(WARNING, "readers will hang because futex_set_value(%p, 2) failed",
-             &temp[position()]);
-  }
-  Unmap(temp);
-}
-
-}  // namespace linux_code
-}  // namespace logging
-}  // namespace aos
diff --git a/aos/logging/binary_log_file.h b/aos/logging/binary_log_file.h
deleted file mode 100644
index 79b580d..0000000
--- a/aos/logging/binary_log_file.h
+++ /dev/null
@@ -1,207 +0,0 @@
-#ifndef AOS_LOGGING_BINARY_LOG_FILE_H_
-#define AOS_LOGGING_BINARY_LOG_FILE_H_
-
-#include <sys/types.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#include <algorithm>
-
-#include "aos/logging/implementations.h"
-
-namespace aos {
-namespace logging {
-namespace linux_code {
-
-// What to align messages to. A macro because it gets used in attributes.
-// This definition gets #undefed later. Use LogFileAccessor::kAlignment instead.
-#define MESSAGE_ALIGNMENT 8
-
-// File format: {
-//   LogFileMessageHeader header;
-//   char *name;  // of the process that wrote the message
-//   void *message;
-// } not crossing kPageSize boundaries into the file and aligned to
-// MESSAGE_ALIGNMENT.
-//
-// Field sizes designed to fit the various values from LogMessage even on
-// other machines (hopefully) because they're baked into the files. They are
-// layed out so that all of the fields are aligned even though the whole thing
-// is packed.
-//
-// A lot of the fields don't have comments because they're the same as the
-// identically named fields in LogMessage.
-struct __attribute__((aligned(MESSAGE_ALIGNMENT))) __attribute__((packed))
-    LogFileMessageHeader {
-  // Represents the type of an individual message.
-  enum class MessageType : uint16_t {
-    // char[] (no '\0' on the end).
-    kString,
-    kStructType,
-    kStruct,
-    kMatrix,
-  };
-
-  // Gets futex_set once this one has been written
-  // for readers keeping up with a live writer.
-  //
-  // Gets initialized to 0 by ftruncate.
-  //
-  // There will be something here after the last message on a "page" set to 2
-  // (by the futex_set) to indicate that the next message is on the next page.
-  aos_futex marker;
-  static_assert(sizeof(marker) == 4, "mutex changed size!");
-  static_assert(MESSAGE_ALIGNMENT >= alignof(aos_futex),
-                "MESSAGE_ALIGNMENT is too small");
-
-  uint32_t time_sec;
-  static_assert(sizeof(time_sec) >= sizeof(LogMessage::seconds),
-                "tv_sec won't fit");
-  uint32_t time_nsec;
-  static_assert(sizeof(time_nsec) >= sizeof(LogMessage::nseconds),
-                "tv_nsec won't fit");
-
-  int32_t source;
-  static_assert(sizeof(source) >= sizeof(LogMessage::source), "PIDs won't fit");
-
-  // Both including all of the bytes in that part of the message.
-  uint32_t name_size, message_size;
-
-  uint16_t sequence;
-  static_assert(sizeof(sequence) == sizeof(LogMessage::sequence),
-                "something changed");
-
-  MessageType type;
-
-  log_level level;
-  static_assert(sizeof(level) == 1, "log_level changed size!");
-};
-static_assert(std::is_pod<LogFileMessageHeader>::value,
-              "LogFileMessageHeader will to get dumped to a file");
-static_assert(offsetof(LogFileMessageHeader, marker) == 0,
-              "marker has to be at the start so readers can find it");
-
-// Handles the mmapping and munmapping for reading and writing log files.
-class LogFileAccessor {
- public:
-  LogFileAccessor(int fd, bool writable);
-  ~LogFileAccessor() {
-    if (use_read_ == Maybe::kYes) {
-      delete[] current_;
-    }
-  }
-
-  // Asynchronously syncs all open mappings.
-  void Sync() const;
-
-  // Returns true iff we currently have the last page in the file mapped.
-  // This is fundamentally a racy question, so the return value may not be
-  // accurate by the time this method returns.
-  bool IsLastPage();
-
-  // Skips to the last page which is an even multiple of kSeekPages.
-  // This is fundamentally racy, so it may not actually be on the very last
-  // possible multiple of kSeekPages when it returns, but it should be close.
-  // This will never move backwards.
-  void SkipToLastSeekablePage();
-
-  size_t file_offset(const void *msg) {
-    return offset() + (static_cast<const char *>(msg) - current());
-  }
-
- protected:
-  // The size of the chunks that get mmaped/munmapped together. Large enough so
-  // that not too much space is wasted and it's hopefully bigger than and a
-  // multiple of the system page size but small enough so that really large
-  // chunks of memory don't have to get mapped at the same time.
-  static const size_t kPageSize = 16384;
-  // What to align messages to, copied into an actual constant.
-  static const size_t kAlignment = MESSAGE_ALIGNMENT;
-#undef MESSAGE_ALIGNMENT
-  // Pages which are multiples of this from the beginning of a file start with
-  // no saved state (ie struct types). This allows seeking immediately to the
-  // largest currently written interval of this number when following.
-  static const size_t kSeekPages = 256;
-
-  char *current() const { return current_; }
-  size_t position() const { return position_; }
-  off_t offset() const { return offset_; }
-
-  void IncrementPosition(size_t size) {
-    position_ += size;
-    AlignPosition();
-  }
-
-  void MapNextPage();
-  void Unmap(void *location);
-
-  // Advances position to the next (aligned) location.
-  void AlignPosition() {
-    position_ += kAlignment - (position_ % kAlignment);
-  }
-
- protected:
-  bool definitely_use_read() const { return use_read_ == Maybe::kYes; }
-  bool definitely_use_mmap() const { return use_read_ == Maybe::kNo; }
-
- private:
-  // Used for representing things that we might know to be true/false or we
-  // might not know (yet).
-  enum class Maybe { kUnknown, kYes, kNo };
-
-  const int fd_;
-  const bool writable_;
-
-  // Into the file. Always a multiple of kPageSize.
-  off_t offset_;
-  char *current_;
-  size_t position_;
-
-  Maybe is_last_page_ = Maybe::kUnknown;
-
-  // Use read instead of mmap (necessary for fds that don't support mmap).
-  Maybe use_read_ = Maybe::kUnknown;
-};
-
-class LogFileReader : public LogFileAccessor {
- public:
-  LogFileReader(int fd) : LogFileAccessor(fd, false) {}
-
-  // May return NULL iff wait is false.
-  const LogFileMessageHeader *ReadNextMessage(bool wait);
-
- private:
-  // Tries reading from the current page to see if it fails because the file
-  // isn't big enough.
-  void CheckCurrentPageReadable();
-};
-
-class LogFileWriter : public LogFileAccessor {
- public:
-  LogFileWriter(int fd) : LogFileAccessor(fd, true) {}
-
-  // message_size should be the total number of bytes needed for the message.
-  LogFileMessageHeader *GetWritePosition(size_t message_size);
-
-  // Returns true exactly once for each unique cookie on each page where cached
-  // data should be cleared.
-  // Call with a non-zero next_message_size to determine if cached data should
-  // be forgotten before writing a next_message_size-sized message.
-  // cookie should be initialized to 0.
-  bool ShouldClearSeekableData(off_t *cookie, size_t next_message_size) const;
-
-  // Forces a move to a new page for the next message.
-  // This is important when there is cacheable data that needs to be re-written
-  // before a message which will spill over onto the next page but the cacheable
-  // message being refreshed is smaller and won't get to a new page by itself.
-  void ForceNewPage();
-
- private:
-  bool NeedNewPageFor(size_t bytes) const;
-};
-
-}  // namespace linux_code
-}  // namespace logging
-}  // namespace aos
-
-#endif  // AOS_LOGGING_BINARY_LOG_FILE_H_
diff --git a/aos/logging/binary_log_writer.cc b/aos/logging/binary_log_writer.cc
deleted file mode 100644
index d4dea64..0000000
--- a/aos/logging/binary_log_writer.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <mntent.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-#include <string>
-
-#include <chrono>
-#include <map>
-#include <unordered_set>
-
-#include "aos/die.h"
-#include "aos/logging/binary_log_file.h"
-#include "aos/logging/implementations.h"
-#include "aos/logging/log_namer.h"
-#include "aos/time/time.h"
-#include "aos/configuration.h"
-#include "aos/init.h"
-#include "aos/ipc_lib/queue.h"
-
-namespace aos {
-namespace logging {
-namespace linux_code {
-namespace {
-
-int BinaryLogReaderMain() {
-  InitNRT();
-
-  const std::string file_name = GetLogName("aos_log");
-  int fd = open(file_name.c_str(), O_SYNC | O_APPEND | O_RDWR | O_CREAT,
-                S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
-  if (fd == -1) {
-    AOS_PLOG(FATAL, "opening file '%s' failed", file_name.c_str());
-  }
-  LogFileWriter writer(fd);
-
-  RawQueue *queue = GetLoggingQueue();
-
-  ::std::unordered_set<uint32_t> written_type_ids;
-
-  while (true) {
-    const LogMessage *const msg =
-        static_cast<const LogMessage *>(queue->ReadMessage(RawQueue::kNonBlock));
-    if (msg == NULL) {
-      // If we've emptied the queue, then wait for a bit before starting to read
-      // again so the queue can buffer up some logs. This avoids lots of context
-      // switches and mutex contention which happens if we're constantly reading
-      // new messages as they come in.
-      ::std::this_thread::sleep_for(::std::chrono::milliseconds(100));
-      continue;
-    }
-
-    const size_t raw_output_length =
-        sizeof(LogFileMessageHeader) + msg->name_length + msg->message_length;
-    size_t output_length = raw_output_length;
-    LogFileMessageHeader *const output = writer.GetWritePosition(output_length);
-    char *output_strings = reinterpret_cast<char *>(output) + sizeof(*output);
-    output->name_size = msg->name_length;
-    output->message_size = msg->message_length;
-    output->source = msg->source;
-    output->level = msg->level;
-    output->time_sec = msg->seconds;
-    output->time_nsec = msg->nseconds;
-    output->sequence = msg->sequence;
-    memcpy(output_strings, msg->name, msg->name_length);
-
-    switch (msg->type) {
-      case LogMessage::Type::kString:
-        memcpy(output_strings + msg->name_length, msg->message,
-               msg->message_length);
-        output->type = LogFileMessageHeader::MessageType::kString;
-        break;
-    }
-
-    if (output->message_size - msg->message_length !=
-        output_length - raw_output_length) {
-      AOS_LOG(FATAL, "%zu != %zu\n", output->message_size - msg->message_length,
-              output_length - raw_output_length);
-    }
-
-    futex_set(&output->marker);
-
-    queue->FreeMessage(msg);
-  }
-
-  Cleanup();
-  return 0;
-}
-
-}  // namespace
-}  // namespace linux_code
-}  // namespace logging
-}  // namespace aos
-
-int main() {
-  return ::aos::logging::linux_code::BinaryLogReaderMain();
-}
diff --git a/aos/logging/log_displayer.cc b/aos/logging/log_displayer.cc
deleted file mode 100644
index fa8fe6b..0000000
--- a/aos/logging/log_displayer.cc
+++ /dev/null
@@ -1,363 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <getopt.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <inttypes.h>
-
-#include <algorithm>
-#include <memory>
-#include <string>
-
-#include "aos/configuration.h"
-#include "aos/logging/binary_log_file.h"
-#include "aos/logging/logging.h"
-#include "aos/logging/implementations.h"
-#include "aos/logging/printf_formats.h"
-#include "aos/util/string_to_num.h"
-
-using ::aos::logging::linux_code::LogFileMessageHeader;
-
-namespace {
-
-const char *kArgsHelp = "[OPTION]... [FILE]\n"
-    "Display log file FILE (created by BinaryLogReader) to stdout.\n"
-    "FILE is \"aos_log-current\" by default.\n"
-    "FILE can also be \"-\" to read from standard input.\n"
-    "\n"
-    "  -n, --name-prefix NAME  "
-    "only display entries from processes which share NAME as a prefix\n"
-    "  -N, --name NAME         only display entries from processes named NAME\n"
-    "  -l, --level LEVEL       "
-      "only display log entries at least as important as LEVEL\n"
-    "  -p, --pid PID           only display log entries from process PID\n"
-    "  -f, --follow            "
-      "wait when the end of the file is reached (implies --end)\n"
-    "  -t, --terminate         stop when the end of file is reached (default)\n"
-    "  -b, --beginning         start at the beginning of the file (default)\n"
-    "  -e, --end               start at the end of the file\n"
-    "  -s, --skip NUMBER       skip NUMBER matching logs\n"
-    "  -m, --max NUMBER        only display up to NUMBER logs\n"
-    "  // -o, --format FORMAT  use FORMAT to display log entries\n"
-    "  -h, --help              display this help and exit\n"
-    "\n"
-    "LEVEL must be DEBUG, INFO, WARNING, ERROR, or FATAL.\n"
-    "  It defaults to INFO.\n"
-    "\n"
-    "TODO(brians) implement the commented out ones.\n";
-
-const char *kExampleUsages = "To view logs from the shooter:\n"
-    "\t`log_displayer -n shooter`\n"
-    "To view debug logs from the shooter:\n"
-    "\t`log_displayer -n shooter -l DEBUG`\n"
-    "To view what the shooter is logging in realtime:\n"
-    "\t`log_displayer -f -n shooter`\n"
-    "To view shooter logs from an old log file:\n"
-    "\t`log_displayer aos_log-<number> -n shooter`\n"
-    "To view the statuses of the shooter hall effects in realtime:\n"
-    "\t`log_displayer -f -n shooter -l DEBUG | grep .Position`\n";
-
-std::string GetRootDirectory() {
-  ssize_t size = 0;
-  std::unique_ptr<char[]> retu;
-  while (true) {
-    size += 256;
-    retu.reset(new char[size]);
-
-    ssize_t ret = readlink("/proc/self/exe", retu.get(), size);
-    if (ret < 0) {
-      if (ret != -1) {
-        LOG(WARNING) << "it returned " << ret << ", not -1";
-      }
-
-      PLOG(FATAL) << "readlink(\"/proc/self/exe\", " << retu.get() << ", " << size
-                  << ") failed";
-    }
-    if (ret < size) {
-      void *last_slash = memrchr(retu.get(), '/', ret);
-      if (last_slash == NULL) {
-        retu.get()[ret] = '\0';
-        LOG(FATAL) << "couldn't find a '/' in \"" << retu.get() << "\"";
-      }
-      *static_cast<char *>(last_slash) = '\0';
-      LOG(INFO) << "got a root dir of \"" << retu.get() << "\"";
-      return std::string(retu.get());
-    }
-  }
-}
-
-
-void PrintHelpAndExit() {
-  fprintf(stderr, "Usage: %s %s", program_invocation_name, kArgsHelp);
-  fprintf(stderr, "\nExample usages:\n\n%s", kExampleUsages);
-
-  // Get the possible executables from start_list.txt.
-  FILE *start_list = fopen("start_list.txt", "r");
-  if (!start_list) {
-    ::std::string path(GetRootDirectory());
-    path += "/start_list.txt";
-    start_list = fopen(path.c_str(), "r");
-    if (!start_list) {
-      printf(
-          "\nCannot open start_list.txt. This means that the\npossible "
-          "arguments for the -n option cannot be shown. log_displayer\nlooks "
-          "for start_list.txt in the current working directory and in\n%s.\n\n",
-          path.c_str());
-      AOS_PLOG(FATAL, "Unable to open start_list.txt");
-    }
-  }
-
-  // Get file size.
-  if (fseek(start_list, 0, SEEK_END)) {
-    AOS_PLOG(FATAL, "fseek() failed while reading start_list.txt");
-  }
-  int size = ftell(start_list);
-  if (size < 0) {
-    AOS_PLOG(FATAL, "ftell() failed while reading start_list.txt");
-  }
-  rewind(start_list);
-
-  ::std::unique_ptr<char[]> contents(new char[size + 1]);
-  if (contents == NULL) {
-    AOS_LOG(FATAL, "malloc() failed while reading start_list.txt.\n");
-  }
-  size_t bytes_read = fread(contents.get(), 1, size, start_list);
-  if (bytes_read < static_cast<size_t>(size)) {
-    AOS_LOG(FATAL, "Read %zu bytes from start_list.txt, expected %d.\n",
-            bytes_read, size);
-  }
-
-  // printf doesn't like strings without the \0.
-  contents[size] = '\0';
-  fprintf(stderr, "\nPossible arguments for the -n option:\n%s", contents.get());
-
-  if (fclose(start_list)) {
-    AOS_LOG(FATAL, "fclose() failed.\n");
-  }
-
-  exit(EXIT_SUCCESS);
-}
-
-}  // namespace
-
-int main(int argc, char **argv) {
-  const char *filter_name = nullptr, *filter_exact_name = nullptr;
-  size_t filter_length = 0;
-  log_level filter_level = INFO;
-  bool follow = false;
-  // Whether we need to skip everything until we get to the end of the file.
-  bool skip_to_end = false;
-  const char *filename = "aos_log-current";
-  int display_max = 0;
-  int32_t source_pid = -1;
-
-  ::aos::logging::Init();
-  ::aos::logging::SetImplementation(
-      new ::aos::logging::StreamLogImplementation(stdout));
-
-  while (true) {
-    static struct option long_options[] = {
-      {"name-prefix", required_argument, NULL, 'n'},
-      {"name", required_argument, NULL, 'N'},
-      {"level", required_argument, NULL, 'l'},
-      {"pid", required_argument, NULL, 'p'},
-
-      {"follow", no_argument, NULL, 'f'},
-      {"terminate", no_argument, NULL, 't'},
-      {"beginning", no_argument, NULL, 'b'},
-      {"end", no_argument, NULL, 'e'},
-      {"skip", required_argument, NULL, 's'},
-      {"max", required_argument, NULL, 'm'},
-
-      {"format", required_argument, NULL, 'o'},
-
-      {"help", no_argument, NULL, 'h'},
-      {0, 0, 0, 0}
-    };
-    int option_index = 0;
-
-    const int c = getopt_long(argc, argv, "N:n:l:p:fts:m:o:h",
-                    long_options, &option_index);
-    if (c == -1) { // if we're at the end
-      break;
-    }
-    switch (c) {
-      case 0:
-        fputs("LogDisplayer: got a 0 option but didn't set up any\n", stderr);
-        abort();
-      case 'n':
-        filter_name = optarg;
-        filter_exact_name = nullptr;
-        filter_length = strlen(filter_name);
-        break;
-      case 'N':
-        filter_exact_name = optarg;
-        filter_name = nullptr;
-        filter_length = strlen(filter_exact_name);
-        break;
-      case 'l':
-        filter_level = ::aos::logging::str_log(optarg);
-        if (filter_level == LOG_UNKNOWN) {
-          fprintf(stderr, "LogDisplayer: unknown log level '%s'\n", optarg);
-          exit(EXIT_FAILURE);
-        }
-        break;
-      case 'p':
-        if (!::aos::util::StringToNumber(::std::string(optarg), &source_pid)) {
-          fprintf(stderr, "ERROR: -p expects a number, not '%s'.\n", optarg);
-          exit(EXIT_FAILURE);
-        }
-        if (source_pid < 0) {
-          fprintf(stderr, "LogDisplayer: invalid pid '%s'\n", optarg);
-          exit(EXIT_FAILURE);
-        }
-        break;
-      case 'f':
-        follow = true;
-        skip_to_end = true;
-        break;
-      case 't':
-        follow = false;
-        break;
-      case 'b':
-        skip_to_end = false;
-        break;
-      case 'e':
-        skip_to_end = true;
-        break;
-      case 'm':
-        if (!::aos::util::StringToNumber(::std::string(optarg), &display_max)) {
-          fprintf(stderr, "ERROR: -m expects a number, not '%s'.\n", optarg);
-          exit(EXIT_FAILURE);
-        }
-        if (display_max <= 0) {
-          fprintf(stderr, "LogDisplayer: invalid max log number '%s'\n",
-              optarg);
-          exit(EXIT_FAILURE);
-        }
-        break;
-      case 'o':
-        abort();
-        break;
-      case 'h':
-        PrintHelpAndExit();
-        break;
-      case '?':
-        break;
-      default:
-        fprintf(stderr, "LogDisplayer: in a bad spot (%s: %d)\n",
-                __FILE__, __LINE__);
-        abort();
-    }
-  }
-
-  if (optind < argc) {
-    // We got a filename.
-    filename = argv[optind++];
-  }
-  if (optind < argc) {
-    fputs("non-option ARGV-elements: ", stderr);
-    while (optind < argc) {
-      fprintf(stderr, "%s\n", argv[optind++]);
-    }
-  }
-
-  int fd;
-  if (strcmp(filename, "-") == 0) {
-    if (skip_to_end) {
-      fputs("Can't skip to end of stdin!\n", stderr);
-      return EXIT_FAILURE;
-    }
-    fd = STDIN_FILENO;
-  } else {
-    fd = open(filename, O_RDONLY);
-  }
-
-  fprintf(stderr, "displaying down to level %s from file '%s'\n",
-      ::aos::logging::log_str(filter_level), filename);
-
-  if (fd == -1) {
-    AOS_PLOG(FATAL, "couldn't open file '%s' for reading", filename);
-  }
-  ::aos::logging::linux_code::LogFileReader reader(fd);
-
-  if (skip_to_end) {
-    fputs("skipping old logs...\n", stderr);
-    reader.SkipToLastSeekablePage();
-  }
-
-  const LogFileMessageHeader *msg;
-  int displayed = 0;
-  do {
-    msg = reader.ReadNextMessage(follow);
-    if (msg == NULL) {
-      fputs("reached end of file\n", stderr);
-      return 0;
-    }
-
-    if (source_pid >= 0 && msg->source != source_pid) {
-      // Message is from the wrong process.
-      continue;
-    }
-
-    if (skip_to_end) {
-      if (reader.IsLastPage()) {
-        fputs("done skipping old logs\n", stderr);
-        skip_to_end = false;
-      } else {
-        continue;
-      }
-    }
-
-    if (::aos::logging::log_gt_important(filter_level, msg->level)) continue;
-
-    const char *position =
-        reinterpret_cast<const char *>(msg + 1);
-
-    if (filter_name != nullptr) {
-      const size_t compare_length =
-          ::std::min<size_t>(filter_length, msg->name_size);
-      if (memcmp(filter_name, position, compare_length) != 0) {
-        continue;
-      }
-      if (compare_length < msg->name_size) {
-        if (position[compare_length] != '.') continue;
-      }
-    }
-
-    if (filter_exact_name != nullptr) {
-      if (filter_length != msg->name_size) continue;
-      if (memcmp(filter_exact_name, position, filter_length) != 0) {
-        continue;
-      }
-    }
-
-    if (display_max && displayed++ >= display_max) {
-      fputs("Not displaying the rest of the messages.\n", stderr);
-      return 0;
-    }
-
-    position += msg->name_size;
-
-#define BASE_ARGS                                                           \
-  AOS_LOGGING_BASE_ARGS(                                                    \
-      msg->name_size, reinterpret_cast<const char *>(msg + 1), msg->source, \
-      msg->sequence, msg->level, msg->time_sec, msg->time_nsec)
-    switch (msg->type) {
-      case LogFileMessageHeader::MessageType::kString:
-        fprintf(stdout, AOS_LOGGING_BASE_FORMAT "%.*s", BASE_ARGS,
-                static_cast<int>(msg->message_size), position);
-        break;
-      case LogFileMessageHeader::MessageType::kStruct:
-      case LogFileMessageHeader::MessageType::kMatrix:
-        AOS_LOG(FATAL, "Unsupported matrix or struct\n");
-        break;
-      case LogFileMessageHeader::MessageType::kStructType:
-        AOS_LOG(FATAL, "shouldn't get here\n");
-        break;
-    }
-#undef BASE_ARGS
-  } while (msg != NULL);
-}
diff --git a/aos/logging/log_streamer.cc b/aos/logging/log_streamer.cc
deleted file mode 100644
index 4477868..0000000
--- a/aos/logging/log_streamer.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-#include <chrono>
-#include <string>
-
-#include "aos/logging/implementations.h"
-#include "aos/logging/logging.h"
-#include "aos/time/time.h"
-#include "aos/init.h"
-#include "aos/ipc_lib/queue.h"
-
-namespace aos {
-namespace logging {
-namespace linux_code {
-namespace {
-
-namespace chrono = ::std::chrono;
-
-int LogStreamerMain() {
-  InitNRT();
-
-  RawQueue *queue = GetLoggingQueue();
-
-  const monotonic_clock::time_point now = monotonic_clock::now();
-  chrono::seconds sec =
-      chrono::duration_cast<chrono::seconds>(now.time_since_epoch());
-  chrono::nanoseconds nsec =
-      chrono::duration_cast<chrono::nanoseconds>(now.time_since_epoch() - sec);
-  printf("starting at %" PRId32 "s%" PRId32 "ns-----------------------------\n",
-         static_cast<int32_t>(sec.count()), static_cast<int32_t>(nsec.count()));
-
-  while (true) {
-    const LogMessage *const msg = static_cast<const LogMessage *>(
-        queue->ReadMessage(RawQueue::kNonBlock));
-    if (msg == NULL) {
-      ::std::this_thread::sleep_for(::std::chrono::milliseconds(100));
-    } else {
-      internal::PrintMessage(stdout, *msg);
-
-      queue->FreeMessage(msg);
-    }
-  }
-
-  Cleanup();
-  return 0;
-}
-
-}  // namespace
-}  // namespace linux_code
-}  // namespace logging
-}  // namespace aos
-
-int main() {
-  return ::aos::logging::linux_code::LogStreamerMain();
-}