Add LoggerNodes() utility

This makes it easy to find out what set of nodes were used to log the
logs that you have on hand (useful for some log analysis tooling).

Change-Id: I690c39b176e073addc59dc9ae75799b95d753300
Signed-off-by: James Kuszmaul <jabukuszmaul+collab@gmail.com>
diff --git a/aos/util/log_to_mcap.cc b/aos/util/log_to_mcap.cc
index 0d51e52..d0a2415 100644
--- a/aos/util/log_to_mcap.cc
+++ b/aos/util/log_to_mcap.cc
@@ -37,19 +37,19 @@
   const std::vector<aos::logger::LogFile> logfiles =
       aos::logger::SortParts(aos::logger::FindLogs(argc, argv));
   CHECK(!logfiles.empty());
-  const std::string logger_node = logfiles.at(0).logger_node;
-  bool all_logs_from_same_node = true;
-  for (const aos::logger::LogFile &log : logfiles) {
-    if (log.logger_node != logger_node) {
-      all_logs_from_same_node = false;
-      break;
-    }
-  }
+  const std::set<std::string> logger_nodes = aos::logger::LoggerNodes(logfiles);
+  CHECK_LT(0u, logger_nodes.size());
+  const std::string logger_node = *logger_nodes.begin();
   std::string replay_node = FLAGS_node;
-  if (replay_node.empty() && all_logs_from_same_node) {
-    LOG(INFO) << "Guessing \"" << logger_node
-              << "\" as node given that --node was not specified.";
-    replay_node = logger_node;
+  if (replay_node.empty()) {
+    if (logger_nodes.size() == 1u) {
+      LOG(INFO) << "Guessing \"" << logger_node
+                << "\" as node given that --node was not specified.";
+      replay_node = logger_node;
+    } else {
+      LOG(ERROR) << "Must supply a --node for log_to_mcap.";
+      return 1;
+    }
   }
 
   std::optional<aos::FlatbufferDetachedBuffer<aos::Configuration>> config;