Add ability to write log to abstract log sink

It completely decouples log writing and file system.

Change-Id: Iae3b881826e04500f4862a16c237e0f7c37c9536
Signed-off-by: Austin Schuh <austin.schuh@bluerivertech.com>
Signed-off-by: Alexei Strots <alexei.strots@bluerivertech.com>
diff --git a/aos/events/logging/log_backend.cc b/aos/events/logging/log_backend.cc
index 2700c4d..07bb780 100644
--- a/aos/events/logging/log_backend.cc
+++ b/aos/events/logging/log_backend.cc
@@ -135,7 +135,7 @@
     }
 
     flags_ = fcntl(fd_, F_GETFL, 0);
-    PCHECK(flags_ >= 0) << ": Failed to get flags for " << this->filename();
+    PCHECK(flags_ >= 0) << ": Failed to get flags for " << filename_;
 
     EnableDirect();
 
@@ -151,10 +151,10 @@
     // Track if we failed to set O_DIRECT.  Note: Austin hasn't seen this call
     // fail.  The write call tends to fail instead.
     if (fcntl(fd_, F_SETFL, new_flags) == -1) {
-      PLOG(WARNING) << "Failed to set O_DIRECT on " << filename();
+      PLOG(WARNING) << "Failed to set O_DIRECT on " << filename_;
       supports_odirect_ = false;
     } else {
-      VLOG(1) << "Enabled O_DIRECT on " << filename();
+      VLOG(1) << "Enabled O_DIRECT on " << filename_;
       flags_ = new_flags;
     }
   }
@@ -164,7 +164,7 @@
   if (supports_odirect_ && ODirectEnabled()) {
     flags_ = flags_ & (~O_DIRECT);
     PCHECK(fcntl(fd_, F_SETFL, flags_) != -1) << ": Failed to disable O_DIRECT";
-    VLOG(1) << "Disabled O_DIRECT on " << filename();
+    VLOG(1) << "Disabled O_DIRECT on " << filename_;
   }
 }
 
@@ -296,7 +296,6 @@
       posix_fadvise(fd_, last_synced_bytes_,
                     total_write_bytes_ - last_synced_bytes_,
                     POSIX_FADV_DONTNEED);
-
     }
     last_synced_bytes_ = total_write_bytes_;
   }
@@ -305,7 +304,7 @@
   if (aligned) {
     written_aligned_ += written;
   }
-  write_stats_.UpdateStats(end - start, written, iovec.size());
+  WriteStatistics()->UpdateStats(end - start, written, iovec.size());
   return WriteCode::kOk;
 }
 
@@ -329,7 +328,7 @@
 FileBackend::FileBackend(std::string_view base_name)
     : base_name_(base_name), separator_(base_name_.back() == '/' ? "" : "_") {}
 
-std::unique_ptr<FileHandler> FileBackend::RequestFile(std::string_view id) {
+std::unique_ptr<LogSink> FileBackend::RequestFile(std::string_view id) {
   const std::string filename = absl::StrCat(base_name_, separator_, id);
   return std::make_unique<FileHandler>(filename);
 }
@@ -337,7 +336,7 @@
 RenamableFileBackend::RenamableFileBackend(std::string_view base_name)
     : base_name_(base_name), separator_(base_name_.back() == '/' ? "" : "_") {}
 
-std::unique_ptr<FileHandler> RenamableFileBackend::RequestFile(
+std::unique_ptr<LogSink> RenamableFileBackend::RequestFile(
     std::string_view id) {
   const std::string filename =
       absl::StrCat(base_name_, separator_, id, temp_suffix_);
diff --git a/aos/events/logging/log_backend.h b/aos/events/logging/log_backend.h
index b3cea6c..1b1417e 100644
--- a/aos/events/logging/log_backend.h
+++ b/aos/events/logging/log_backend.h
@@ -77,7 +77,42 @@
   size_t messages_written = 0;
 };
 
-// Source for iovec with additional flag that pointer and size of data is
+// Interface that abstract writing to log from media.
+class LogSink {
+ public:
+  LogSink() = default;
+  virtual ~LogSink() = default;
+
+  LogSink(const LogSink &) = delete;
+  LogSink &operator=(const LogSink &) = delete;
+
+  // Try to open file. App will crash if there are other than out-of-space
+  // problems with backend media.
+  virtual WriteCode OpenForWrite() = 0;
+
+  // Close the file handler.
+  virtual WriteCode Close() = 0;
+
+  // Returns true if sink is open and need to be closed.
+  virtual bool is_open() const = 0;
+
+  // Peeks messages from queue and writes it to file. Returns code when
+  // out-of-space problem occurred along with number of messages from queue that
+  // was written.
+  virtual WriteResult Write(
+      const absl::Span<const absl::Span<const uint8_t>> &queue) = 0;
+
+  // Get access to statistics related to the write operations.
+  WriteStats *WriteStatistics() { return &write_stats_; }
+
+  // Name of the log sink.
+  virtual std::string_view name() const = 0;
+
+ private:
+  WriteStats write_stats_;
+};
+
+// Source for iovec with an additional flag that pointer and size of data is
 // aligned and be ready for O_DIRECT operation.
 struct AlignedIovec {
   const uint8_t *data;
@@ -124,28 +159,28 @@
 //  4) Not all filesystems support O_DIRECT, and different sizes may be optimal
 //     for different machines.  The defaults should work decently anywhere and
 //     be tunable for faster systems.
-class FileHandler {
+class FileHandler : public LogSink {
  public:
   // Size of an aligned sector used to detect when the data is aligned enough to
   // use O_DIRECT instead.
   static constexpr size_t kSector = 512u;
 
   explicit FileHandler(std::string filename);
-  virtual ~FileHandler();
+  ~FileHandler() override;
 
   FileHandler(const FileHandler &) = delete;
   FileHandler &operator=(const FileHandler &) = delete;
 
   // Try to open file. App will crash if there are other than out-of-space
   // problems with backend media.
-  virtual WriteCode OpenForWrite();
+  WriteCode OpenForWrite() override;
 
   // Close the file handler.
-  virtual WriteCode Close();
+  WriteCode Close() override;
 
   // This will be true until Close() is called, unless the file couldn't be
   // created due to running out of space.
-  bool is_open() const { return fd_ != -1; }
+  bool is_open() const override { return fd_ != -1; }
 
   // Peeks messages from queue and writes it to file. Returns code when
   // out-of-space problem occurred along with number of messages from queue that
@@ -155,21 +190,19 @@
   // write faster if the spans passed in start at aligned addresses, and are
   // multiples of kSector long (and the data written so far is also a multiple
   // of kSector length).
-  virtual WriteResult Write(
-      const absl::Span<const absl::Span<const uint8_t>> &queue);
+  WriteResult Write(
+      const absl::Span<const absl::Span<const uint8_t>> &queue) override;
 
-  // TODO (Alexei): it is rather leaked abstraction.
-  // Path to the concrete log file.
-  std::string_view filename() const { return filename_; }
-
-  int fd() const { return fd_; }
-
-  // Get access to statistics related to the write operations.
-  WriteStats *WriteStatistics() { return &write_stats_; }
+  // Name of the log sink mostly for informational purposes.
+  std::string_view name() const override { return filename_; }
 
   // Number of bytes written in aligned mode. It is mostly for testing.
   size_t written_aligned() const { return written_aligned_; }
 
+ protected:
+  // This is used by subclasses who need to access filename.
+  std::string_view filename() const { return filename_; }
+
  private:
   // Enables O_DIRECT on the open file if it is supported.  Cheap to call if it
   // is already enabled.
@@ -201,8 +234,6 @@
 
   bool supports_odirect_ = true;
   int flags_ = 0;
-
-  WriteStats write_stats_;
 };
 
 // Class that decouples log writing and media (file system or memory). It is
@@ -214,7 +245,7 @@
   // Request file-like object from the log backend. It maybe a file on a disk or
   // in memory. id is usually generated by log namer and looks like name of the
   // file within a log folder.
-  virtual std::unique_ptr<FileHandler> RequestFile(std::string_view id) = 0;
+  virtual std::unique_ptr<LogSink> RequestFile(std::string_view id) = 0;
 };
 
 // Implements requests log files from file system.
@@ -225,7 +256,7 @@
   ~FileBackend() override = default;
 
   // Request file from a file system. It is not open yet.
-  std::unique_ptr<FileHandler> RequestFile(std::string_view id) override;
+  std::unique_ptr<LogSink> RequestFile(std::string_view id) override;
 
  private:
   const std::string base_name_;
@@ -254,7 +285,7 @@
   ~RenamableFileBackend() = default;
 
   // Request file from a file system. It is not open yet.
-  std::unique_ptr<FileHandler> RequestFile(std::string_view id) override;
+  std::unique_ptr<LogSink> RequestFile(std::string_view id) override;
 
   // TODO (Alexei): it is called by Logger, and left here for compatibility.
   // Logger should not call it.
diff --git a/aos/events/logging/log_backend_test.cc b/aos/events/logging/log_backend_test.cc
index b969218..928bb24 100644
--- a/aos/events/logging/log_backend_test.cc
+++ b/aos/events/logging/log_backend_test.cc
@@ -14,13 +14,24 @@
 #include "gtest/gtest.h"
 
 namespace aos::logger::testing {
+namespace {
+// Helper to write simple string to the log sink
+WriteResult Write(LogSink *log_sink, std::string_view content) {
+  auto span = absl::Span<const uint8_t>(
+      reinterpret_cast<const unsigned char *>(content.data()), content.size());
+  auto queue = absl::Span<const absl::Span<const uint8_t>>(&span, 1);
+  return log_sink->Write(queue);
+}
+}  // namespace
+
 TEST(LogBackendTest, CreateSimpleFile) {
   const std::string logevent = aos::testing::TestTmpDir() + "/logevent/";
   FileBackend backend(logevent);
   auto file = backend.RequestFile("test.log");
   ASSERT_EQ(file->OpenForWrite(), WriteCode::kOk);
-  auto result = write(file->fd(), "test", 4);
-  EXPECT_GT(result, 0);
+  auto result = Write(file.get(), "test");
+  EXPECT_EQ(result.code, WriteCode::kOk);
+  EXPECT_EQ(result.messages_written, 1);
   EXPECT_EQ(file->Close(), WriteCode::kOk);
   EXPECT_TRUE(std::filesystem::exists(logevent + "test.log"));
 }
@@ -30,8 +41,9 @@
   RenamableFileBackend backend(logevent);
   auto file = backend.RequestFile("test.log");
   ASSERT_EQ(file->OpenForWrite(), WriteCode::kOk);
-  auto result = write(file->fd(), "testtest", 8);
-  EXPECT_GT(result, 0);
+  auto result = Write(file.get(), "test");
+  EXPECT_EQ(result.code, WriteCode::kOk);
+  EXPECT_EQ(result.messages_written, 1);
   EXPECT_EQ(file->Close(), WriteCode::kOk);
   EXPECT_TRUE(std::filesystem::exists(logevent + "test.log"));
 }
@@ -42,8 +54,9 @@
   backend.EnableTempFiles();
   auto file = backend.RequestFile("test.log");
   ASSERT_EQ(file->OpenForWrite(), WriteCode::kOk);
-  auto result = write(file->fd(), "testtest", 8);
-  EXPECT_GT(result, 0);
+  auto result = Write(file.get(), "test");
+  EXPECT_EQ(result.code, WriteCode::kOk);
+  EXPECT_EQ(result.messages_written, 1);
   EXPECT_TRUE(std::filesystem::exists(logevent + "test.log.tmp"));
 
   EXPECT_EQ(file->Close(), WriteCode::kOk);
@@ -56,8 +69,9 @@
   RenamableFileBackend backend(logevent);
   auto file = backend.RequestFile("test.log");
   ASSERT_EQ(file->OpenForWrite(), WriteCode::kOk);
-  auto result = write(file->fd(), "testtest", 8);
-  EXPECT_GT(result, 0);
+  auto result = Write(file.get(), "test");
+  EXPECT_EQ(result.code, WriteCode::kOk);
+  EXPECT_EQ(result.messages_written, 1);
   EXPECT_TRUE(std::filesystem::exists(logevent + "test.log"));
 
   std::string renamed = aos::testing::TestTmpDir() + "/renamed/";
@@ -77,8 +91,9 @@
   backend.EnableTempFiles();
   auto file = backend.RequestFile("test.log");
   ASSERT_EQ(file->OpenForWrite(), WriteCode::kOk);
-  auto result = write(file->fd(), "testtest", 8);
-  EXPECT_GT(result, 0);
+  auto result = Write(file.get(), "test");
+  EXPECT_EQ(result.code, WriteCode::kOk);
+  EXPECT_EQ(result.messages_written, 1);
   EXPECT_TRUE(std::filesystem::exists(logevent + "test.log.tmp"));
 
   std::string renamed = aos::testing::TestTmpDir() + "/renamed/";
@@ -364,7 +379,8 @@
   auto result = handler->Write(queue);
   EXPECT_EQ(result.code, WriteCode::kOk);
   EXPECT_EQ(result.messages_written, queue.size());
-  EXPECT_GT(handler->written_aligned(), 0);
+  FileHandler *file_handler = reinterpret_cast<FileHandler *>(handler.get());
+  EXPECT_GT(file_handler->written_aligned(), 0);
 
   ASSERT_EQ(handler->Close(), WriteCode::kOk);
   EXPECT_TRUE(std::filesystem::exists(file));
diff --git a/aos/events/logging/log_namer.cc b/aos/events/logging/log_namer.cc
index 10e08db..4b23268 100644
--- a/aos/events/logging/log_namer.cc
+++ b/aos/events/logging/log_namer.cc
@@ -45,7 +45,7 @@
 void NewDataWriter::Rotate() {
   // No need to rotate if nothing has been written.
   if (header_written_) {
-    VLOG(1) << "Rotated " << filename();
+    VLOG(1) << "Rotated " << name();
     ++parts_index_;
     reopen_(this);
     header_written_ = false;
@@ -77,7 +77,7 @@
 
   state_[node_index_].boot_uuid = source_node_boot_uuid;
 
-  VLOG(1) << "Rebooted " << filename();
+  VLOG(1) << "Rebooted " << name();
 }
 
 void NewDataWriter::UpdateBoot(const UUID &source_node_boot_uuid) {
@@ -101,7 +101,7 @@
 
   // Did the remote boot UUID change?
   if (state.boot_uuid != remote_node_boot_uuid) {
-    VLOG(1) << filename() << " Remote " << remote_node_index << " updated to "
+    VLOG(1) << name() << " Remote " << remote_node_index << " updated to "
             << remote_node_boot_uuid << " from " << state.boot_uuid;
     state.boot_uuid = remote_node_boot_uuid;
     state.oldest_remote_monotonic_timestamp = monotonic_clock::max_time;
@@ -124,7 +124,7 @@
   if (!reliable) {
     if (state.oldest_remote_unreliable_monotonic_timestamp >
         monotonic_remote_time) {
-      VLOG(1) << filename() << " Remote " << remote_node_index
+      VLOG(1) << name() << " Remote " << remote_node_index
               << " oldest_remote_unreliable_monotonic_timestamp updated from "
               << state.oldest_remote_unreliable_monotonic_timestamp << " to "
               << monotonic_remote_time;
@@ -136,7 +136,7 @@
   } else {
     if (state.oldest_remote_reliable_monotonic_timestamp >
         monotonic_remote_time) {
-      VLOG(1) << filename() << " Remote " << remote_node_index
+      VLOG(1) << name() << " Remote " << remote_node_index
               << " oldest_remote_reliable_monotonic_timestamp updated from "
               << state.oldest_remote_reliable_monotonic_timestamp << " to "
               << monotonic_remote_time;
@@ -153,7 +153,7 @@
     if (monotonic_event_time <
         logger_state.oldest_logger_remote_unreliable_monotonic_timestamp) {
       VLOG(1)
-          << filename() << " Remote " << node_index_
+          << name() << " Remote " << node_index_
           << " oldest_logger_remote_unreliable_monotonic_timestamp updated "
              "from "
           << logger_state.oldest_logger_remote_unreliable_monotonic_timestamp
@@ -169,7 +169,7 @@
 
   // Did any of the timestamps change?
   if (state.oldest_remote_monotonic_timestamp > monotonic_remote_time) {
-    VLOG(1) << filename() << " Remote " << remote_node_index
+    VLOG(1) << name() << " Remote " << remote_node_index
             << " oldest_remote_monotonic_timestamp updated from "
             << state.oldest_remote_monotonic_timestamp << " to "
             << monotonic_remote_time;
@@ -205,7 +205,7 @@
   CHECK_EQ(state_[node_index_].boot_uuid, source_node_boot_uuid);
   CHECK(writer);
   CHECK(header_written_) << ": Attempting to write message before header to "
-                         << writer->filename();
+                         << writer->name();
   writer->CopyMessage(coppier, now);
 }
 
@@ -214,7 +214,7 @@
   const size_t logger_node_index = log_namer_->logger_node_index();
   const UUID &logger_node_boot_uuid = log_namer_->logger_node_boot_uuid();
   if (state_[logger_node_index].boot_uuid == UUID::Zero()) {
-    VLOG(1) << filename() << " Logger node is " << logger_node_index
+    VLOG(1) << name() << " Logger node is " << logger_node_index
             << " and uuid is " << logger_node_boot_uuid;
     state_[logger_node_index].boot_uuid = logger_node_boot_uuid;
   } else {
@@ -227,7 +227,7 @@
 void NewDataWriter::QueueHeader(
     aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> &&header) {
   CHECK(!header_written_) << ": Attempting to write duplicate header to "
-                          << writer->filename();
+                          << writer->name();
   CHECK(header.message().has_source_node_boot_uuid());
   CHECK_EQ(state_[node_index_].boot_uuid,
            UUID::FromString(header.message().source_node_boot_uuid()));
@@ -245,7 +245,7 @@
     reopen_(this);
   }
 
-  VLOG(1) << "Writing to " << filename() << " "
+  VLOG(1) << "Writing to " << name() << " "
           << aos::FlatbufferToJson(
                  header, {.multi_line = false, .max_vector_size = 100});
 
@@ -560,14 +560,14 @@
   return result;
 }
 
-MultiNodeLogNamer::MultiNodeLogNamer(
-    std::unique_ptr<LogBackend> log_backend, EventLoop *event_loop)
+MultiNodeLogNamer::MultiNodeLogNamer(std::unique_ptr<LogBackend> log_backend,
+                                     EventLoop *event_loop)
     : MultiNodeLogNamer(std::move(log_backend), event_loop->configuration(),
                         event_loop, event_loop->node()) {}
 
-MultiNodeLogNamer::MultiNodeLogNamer(
-    std::unique_ptr<LogBackend> log_backend,
-    const Configuration *configuration, EventLoop *event_loop, const Node *node)
+MultiNodeLogNamer::MultiNodeLogNamer(std::unique_ptr<LogBackend> log_backend,
+                                     const Configuration *configuration,
+                                     EventLoop *event_loop, const Node *node)
     : LogNamer(configuration, event_loop, node),
       log_backend_(std::move(log_backend)),
       encoder_factory_([](size_t max_message_size) {
@@ -826,7 +826,6 @@
     return;
   }
   DetachedBufferWriter *const writer = writer_pointer->get();
-  const bool was_open = writer->is_open();
   writer->Close();
 
   const auto *stats = writer->WriteStatistics();
@@ -844,11 +843,6 @@
     ran_out_of_space_ = true;
     writer->acknowledge_out_of_space();
   }
-
-  if (!was_open) {
-    CHECK(access(std::string(writer->filename()).c_str(), F_OK) == -1)
-        << ": File should not exist: " << writer->filename();
-  }
 }
 
 }  // namespace logger
diff --git a/aos/events/logging/log_namer.h b/aos/events/logging/log_namer.h
index fcb3f87..8842f4e 100644
--- a/aos/events/logging/log_namer.h
+++ b/aos/events/logging/log_namer.h
@@ -43,7 +43,8 @@
 
   void UpdateMaxMessageSize(size_t new_size) {
     if (new_size > max_message_size_) {
-      CHECK(!header_written_);
+      CHECK(!header_written_) << ": Tried to update to " << new_size << ", was "
+                              << max_message_size_ << " for " << name();
       max_message_size_ = new_size;
     }
   }
@@ -77,10 +78,8 @@
   // update the remote timestamps.
   void UpdateBoot(const UUID &source_node_boot_uuid);
 
-  // Returns the filename of the writer.
-  std::string_view filename() const {
-    return writer ? writer->filename() : "(closed)";
-  }
+  // Returns the name of the writer. It may be a filename, but assume it is not.
+  std::string_view name() const { return writer ? writer->name() : "(closed)"; }
 
   void Close();
 
diff --git a/aos/events/logging/log_writer.cc b/aos/events/logging/log_writer.cc
index b6ee4a5..d559311 100644
--- a/aos/events/logging/log_writer.cc
+++ b/aos/events/logging/log_writer.cc
@@ -230,8 +230,6 @@
   }
 }
 
-
-
 std::string Logger::WriteConfiguration(LogNamer *log_namer) {
   std::string config_sha256;
 
@@ -348,8 +346,7 @@
   // Make sure we read up until "now" and log it.  This sets us up so that we
   // are unlikely to fetch a message far in the future and have a ton of data
   // before the offical start time.
-  monotonic_clock::time_point newest_record =
-      monotonic_clock::min_time;
+  monotonic_clock::time_point newest_record = monotonic_clock::min_time;
   while (true) {
     aos::monotonic_clock::time_point next_time =
         last_synchronized_time_ + polling_period_;
@@ -737,7 +734,7 @@
     VLOG(2) << "Wrote data as node " << FlatbufferToJson(node_)
             << " for channel "
             << configuration::CleanedChannelToString(f.fetcher->channel())
-            << " to " << writer->filename();
+            << " to " << writer->name();
   }
 }
 
@@ -762,7 +759,7 @@
     VLOG(2) << "Wrote timestamps as node " << FlatbufferToJson(node_)
             << " for channel "
             << configuration::CleanedChannelToString(f.fetcher->channel())
-            << " to " << timestamp_writer->filename() << " timestamp";
+            << " to " << timestamp_writer->name() << " timestamp";
   }
 }
 
diff --git a/aos/events/logging/logfile_utils.cc b/aos/events/logging/logfile_utils.cc
index 27c6c3b..490393d 100644
--- a/aos/events/logging/logfile_utils.cc
+++ b/aos/events/logging/logfile_utils.cc
@@ -80,12 +80,11 @@
 }
 }  // namespace
 
-DetachedBufferWriter::DetachedBufferWriter(
-    std::unique_ptr<FileHandler> file_handler,
-    std::unique_ptr<DataEncoder> encoder)
-    : file_handler_(std::move(file_handler)), encoder_(std::move(encoder)) {
-  CHECK(file_handler_);
-  ran_out_of_space_ = file_handler_->OpenForWrite() == WriteCode::kOutOfSpace;
+DetachedBufferWriter::DetachedBufferWriter(std::unique_ptr<LogSink> log_sink,
+                                           std::unique_ptr<DataEncoder> encoder)
+    : log_sink_(std::move(log_sink)), encoder_(std::move(encoder)) {
+  CHECK(log_sink_);
+  ran_out_of_space_ = log_sink_->OpenForWrite() == WriteCode::kOutOfSpace;
   if (ran_out_of_space_) {
     LOG(WARNING) << "And we are out of space";
   }
@@ -108,7 +107,7 @@
 // (because that data will then be its data).
 DetachedBufferWriter &DetachedBufferWriter::operator=(
     DetachedBufferWriter &&other) {
-  std::swap(file_handler_, other.file_handler_);
+  std::swap(log_sink_, other.log_sink_);
   std::swap(encoder_, other.encoder_);
   std::swap(ran_out_of_space_, other.ran_out_of_space_);
   std::swap(acknowledge_ran_out_of_space_, other.acknowledge_ran_out_of_space_);
@@ -147,7 +146,7 @@
 }
 
 void DetachedBufferWriter::Close() {
-  if (!file_handler_->is_open()) {
+  if (!log_sink_->is_open()) {
     return;
   }
   encoder_->Finish();
@@ -155,7 +154,7 @@
     Flush(monotonic_clock::max_time);
   }
   encoder_.reset();
-  ran_out_of_space_ = file_handler_->Close() == WriteCode::kOutOfSpace;
+  ran_out_of_space_ = log_sink_->Close() == WriteCode::kOutOfSpace;
 }
 
 void DetachedBufferWriter::Flush(aos::monotonic_clock::time_point now) {
@@ -178,7 +177,7 @@
     return;
   }
 
-  const WriteResult result = file_handler_->Write(queue);
+  const WriteResult result = log_sink_->Write(queue);
   encoder_->Clear(result.messages_written);
   ran_out_of_space_ = result.code == WriteCode::kOutOfSpace;
 }
diff --git a/aos/events/logging/logfile_utils.h b/aos/events/logging/logfile_utils.h
index c75c8fb..8415efe 100644
--- a/aos/events/logging/logfile_utils.h
+++ b/aos/events/logging/logfile_utils.h
@@ -51,7 +51,7 @@
   // Marker struct for one of our constructor overloads.
   struct already_out_of_space_t {};
 
-  DetachedBufferWriter(std::unique_ptr<FileHandler> file_handler,
+  DetachedBufferWriter(std::unique_ptr<LogSink> log_sink,
                        std::unique_ptr<DataEncoder> encoder);
   // Creates a dummy instance which won't even open a file. It will act as if
   // opening the file ran out of space immediately.
@@ -64,11 +64,11 @@
   DetachedBufferWriter &operator=(DetachedBufferWriter &&other);
   DetachedBufferWriter &operator=(const DetachedBufferWriter &) = delete;
 
-  std::string_view filename() const { return file_handler_->filename(); }
+  std::string_view name() const { return log_sink_->name(); }
 
   // This will be true until Close() is called, unless the file couldn't be
   // created due to running out of space.
-  bool is_open() const { return file_handler_->is_open(); }
+  bool is_open() const { return log_sink_->is_open(); }
 
   // Queues up a finished FlatBufferBuilder to be encoded and written.
   //
@@ -106,7 +106,7 @@
     return encoder_->total_bytes();
   }
 
-  WriteStats* WriteStatistics() const { return file_handler_->WriteStatistics(); }
+  WriteStats *WriteStatistics() const { return log_sink_->WriteStatistics(); }
 
  private:
   // Performs a single writev call with as much of the data we have queued up as
@@ -124,7 +124,7 @@
   // the current time.  It just needs to be close.
   void FlushAtThreshold(aos::monotonic_clock::time_point now);
 
-  std::unique_ptr<FileHandler> file_handler_;
+  std::unique_ptr<LogSink> log_sink_;
   std::unique_ptr<DataEncoder> encoder_;
 
   bool ran_out_of_space_ = false;