Expose file size from log file reader classes
Change-Id: Ib826c4405ba78e9e1ab37dfd1893d67fc08a7522
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/events/logging/BUILD b/aos/events/logging/BUILD
index 4e58923..fa2f8ae 100644
--- a/aos/events/logging/BUILD
+++ b/aos/events/logging/BUILD
@@ -88,7 +88,7 @@
srcs = ["s3_file_operations.cc"],
hdrs = ["s3_file_operations.h"],
deps = [
- ":file_operations",
+ ":log_backend",
":s3_fetcher",
],
)
diff --git a/aos/events/logging/file_operations.cc b/aos/events/logging/file_operations.cc
index 75910e5..04e695e 100644
--- a/aos/events/logging/file_operations.cc
+++ b/aos/events/logging/file_operations.cc
@@ -11,13 +11,16 @@
absl::EndsWith(filename, ".bfbs.sz");
}
-void LocalFileOperations::FindLogs(std::vector<std::string> *files) {
- auto MaybeAddFile = [&files](std::string_view filename) {
+void LocalFileOperations::FindLogs(std::vector<File> *files) {
+ auto MaybeAddFile = [&files](std::string_view filename, size_t size) {
if (!IsValidFilename(filename)) {
VLOG(1) << "Ignoring " << filename << " with invalid extension.";
} else {
VLOG(1) << "Found log " << filename;
- files->emplace_back(filename);
+ files->emplace_back(File{
+ .name = std::string(filename),
+ .size = size,
+ });
}
};
if (std::filesystem::is_directory(filename_)) {
@@ -28,10 +31,10 @@
VLOG(1) << file << " is not file.";
continue;
}
- MaybeAddFile(file.path().string());
+ MaybeAddFile(file.path().string(), file.file_size());
}
} else {
- MaybeAddFile(filename_);
+ MaybeAddFile(filename_, std::filesystem::file_size(filename_));
}
}
diff --git a/aos/events/logging/file_operations.h b/aos/events/logging/file_operations.h
index faf63cb..538ae60 100644
--- a/aos/events/logging/file_operations.h
+++ b/aos/events/logging/file_operations.h
@@ -14,10 +14,15 @@
// associated with either a single file or directory that contains log files.
class FileOperations {
public:
+ struct File {
+ std::string name;
+ size_t size;
+ };
+
virtual ~FileOperations() = default;
virtual bool Exists() = 0;
- virtual void FindLogs(std::vector<std::string> *files) = 0;
+ virtual void FindLogs(std::vector<File> *files) = 0;
};
// Implements FileOperations with standard POSIX filesystem APIs. These work on
@@ -29,7 +34,7 @@
bool Exists() override { return std::filesystem::exists(filename_); }
- void FindLogs(std::vector<std::string> *files) override;
+ void FindLogs(std::vector<File> *files) override;
private:
std::string filename_;
diff --git a/aos/events/logging/log_backend.cc b/aos/events/logging/log_backend.cc
index 6cd9a7d..f8a6846 100644
--- a/aos/events/logging/log_backend.cc
+++ b/aos/events/logging/log_backend.cc
@@ -334,32 +334,35 @@
base_name_(base_name),
separator_(base_name_.back() == '/' ? "" : "_") {}
-std::unique_ptr<LogSink> FileBackend::RequestFile(std::string_view id) {
+std::unique_ptr<LogSink> FileBackend::RequestFile(const std::string_view id) {
const std::string filename = absl::StrCat(base_name_, separator_, id);
return std::make_unique<FileHandler>(filename, supports_odirect_);
}
-std::vector<std::string> FileBackend::ListFiles() const {
+std::vector<FileBackend::File> FileBackend::ListFiles() const {
std::filesystem::path directory(base_name_);
if (!is_directory(directory)) {
directory = directory.parent_path();
}
internal::LocalFileOperations operations(directory.string());
- std::vector<std::string> files;
+ std::vector<internal::FileOperations::File> files;
operations.FindLogs(&files);
- std::vector<std::string> names;
+ std::vector<File> names;
const std::string prefix = absl::StrCat(base_name_, separator_);
for (const auto &file : files) {
- CHECK(absl::StartsWith(file, prefix))
- << ": File " << file << ", prefix " << prefix;
- names.push_back(file.substr(prefix.size()));
+ CHECK(absl::StartsWith(file.name, prefix))
+ << ": File " << file.name << ", prefix " << prefix;
+ names.emplace_back(File{
+ .name = file.name.substr(prefix.size()),
+ .size = file.size,
+ });
}
return names;
}
std::unique_ptr<DataDecoder> FileBackend::GetDecoder(
- std::string_view id) const {
+ const std::string_view id) const {
const std::string filename = absl::StrCat(base_name_, separator_, id);
CHECK(std::filesystem::exists(filename));
return std::make_unique<DummyDecoder>(filename);
@@ -372,7 +375,7 @@
separator_(base_name_.back() == '/' ? "" : "_") {}
std::unique_ptr<LogSink> RenamableFileBackend::RequestFile(
- std::string_view id) {
+ const std::string_view id) {
const std::string filename =
absl::StrCat(base_name_, separator_, id, temp_suffix_);
return std::make_unique<RenamableFileHandler>(this, filename,
diff --git a/aos/events/logging/log_backend.h b/aos/events/logging/log_backend.h
index e75b632..3a47f42 100644
--- a/aos/events/logging/log_backend.h
+++ b/aos/events/logging/log_backend.h
@@ -238,6 +238,27 @@
int flags_ = 0;
};
+// Interface to decouple reading of logs and media (file system, memory or S3).
+class LogSource {
+ public:
+ struct File {
+ std::string name;
+ size_t size;
+ };
+
+ virtual ~LogSource() = default;
+
+ // Provides a list of readable sources for log reading.
+ virtual std::vector<File> ListFiles() const = 0;
+
+ // Entry point for reading the content of log file.
+ virtual std::unique_ptr<DataDecoder> GetDecoder(
+ const std::string_view id) const = 0;
+ std::unique_ptr<DataDecoder> GetDecoder(const LogSource::File &id) const {
+ return GetDecoder(id.name);
+ }
+};
+
// Interface to decouple log writing and media (file system or memory). It is
// handy to use for tests.
class LogBackend {
@@ -247,20 +268,11 @@
// 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<LogSink> RequestFile(std::string_view id) = 0;
-};
+ virtual std::unique_ptr<LogSink> RequestFile(const std::string_view id) = 0;
-// Interface to decouple reading of logs and media (file system, memory or S3).
-class LogSource {
- public:
- virtual ~LogSource() = default;
-
- // Provides a list of readable sources for log reading.
- virtual std::vector<std::string> ListFiles() const = 0;
-
- // Entry point for reading the content of log file.
- virtual std::unique_ptr<DataDecoder> GetDecoder(
- std::string_view id) const = 0;
+ std::unique_ptr<LogSink> RequestFile(const LogSource::File &id) {
+ return RequestFile(id.name);
+ }
};
// Implements requests log files from file system.
@@ -271,13 +283,14 @@
~FileBackend() override = default;
// Request file from a file system. It is not open yet.
- std::unique_ptr<LogSink> RequestFile(std::string_view id) override;
+ std::unique_ptr<LogSink> RequestFile(const std::string_view id) override;
// List all files that looks like log files under base_name.
- std::vector<std::string> ListFiles() const override;
+ std::vector<File> ListFiles() const override;
// Open decoder to read the content of the file.
- std::unique_ptr<DataDecoder> GetDecoder(std::string_view id) const override;
+ std::unique_ptr<DataDecoder> GetDecoder(
+ const std::string_view id) const override;
private:
const bool supports_odirect_;
@@ -309,7 +322,7 @@
~RenamableFileBackend() = default;
// Request file from a file system. It is not open yet.
- std::unique_ptr<LogSink> RequestFile(std::string_view id) override;
+ std::unique_ptr<LogSink> RequestFile(const 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 08b6f1e..d3c83cc 100644
--- a/aos/events/logging/log_backend_test.cc
+++ b/aos/events/logging/log_backend_test.cc
@@ -25,6 +25,8 @@
}
} // namespace
+MATCHER_P(FileEq, o, "") { return arg.name == o.name && arg.size == o.size; }
+
TEST(LogBackendTest, CreateSimpleFile) {
const std::string logevent = aos::testing::TestTmpDir() + "/logevent/";
const std::string filename = "test.bfbs";
@@ -37,7 +39,11 @@
EXPECT_EQ(file->Close(), WriteCode::kOk);
EXPECT_TRUE(std::filesystem::exists(logevent + filename));
- EXPECT_THAT(backend.ListFiles(), ::testing::ElementsAre(filename));
+ EXPECT_THAT(backend.ListFiles(),
+ ::testing::ElementsAre(FileEq(LogSource::File{
+ .name = filename,
+ .size = 4,
+ })));
auto decoder = backend.GetDecoder(filename);
std::vector<uint8_t> buffer;
diff --git a/aos/events/logging/log_reader_utils_test.cc b/aos/events/logging/log_reader_utils_test.cc
index 911c4eb..b61c9de 100644
--- a/aos/events/logging/log_reader_utils_test.cc
+++ b/aos/events/logging/log_reader_utils_test.cc
@@ -134,10 +134,10 @@
util::WriteStringToFileOrDie(log_file, "test");
internal::LocalFileOperations file_op(log_file);
EXPECT_TRUE(file_op.Exists());
- std::vector<std::string> logs;
+ std::vector<internal::LocalFileOperations::File> logs;
file_op.FindLogs(&logs);
ASSERT_EQ(logs.size(), 1);
- EXPECT_EQ(logs.front(), log_file);
+ EXPECT_EQ(logs.front().name, log_file);
}
// Verify that it is OK to list folder with log file.
@@ -148,10 +148,10 @@
util::WriteStringToFileOrDie(log_file, "test");
internal::LocalFileOperations file_op(log_folder);
EXPECT_TRUE(file_op.Exists());
- std::vector<std::string> logs;
+ std::vector<internal::LocalFileOperations::File> logs;
file_op.FindLogs(&logs);
ASSERT_EQ(logs.size(), 1);
- EXPECT_EQ(logs.front(), log_file);
+ EXPECT_EQ(logs.front().name, log_file);
}
} // namespace aos::logger::testing
diff --git a/aos/events/logging/log_stats.cc b/aos/events/logging/log_stats.cc
index e6913c1..bbed18f 100644
--- a/aos/events/logging/log_stats.cc
+++ b/aos/events/logging/log_stats.cc
@@ -287,16 +287,8 @@
LOG(FATAL) << "Expected at least 1 logfile as an argument.";
}
- // find logfiles
- std::vector<std::string> unsorted_logfiles =
- aos::logger::FindLogs(argc, argv);
-
- // sort logfiles
- const std::vector<aos::logger::LogFile> logfiles =
- aos::logger::SortParts(unsorted_logfiles);
-
- // open logfiles
- aos::logger::LogReader reader(logfiles);
+ aos::logger::LogReader reader(
+ aos::logger::SortParts(aos::logger::FindLogs(argc, argv)));
LogfileStats logfile_stats;
std::vector<ChannelStats> channel_stats;
diff --git a/aos/events/logging/logfile_sorting.cc b/aos/events/logging/logfile_sorting.cc
index a343356..59d18d0 100644
--- a/aos/events/logging/logfile_sorting.cc
+++ b/aos/events/logging/logfile_sorting.cc
@@ -110,18 +110,19 @@
} // namespace
-void FindLogs(std::vector<std::string> *files, std::string filename) {
+void FindLogs(std::vector<internal::FileOperations::File> *files,
+ std::string filename) {
MakeFileOperations(filename)->FindLogs(files);
}
-std::vector<std::string> FindLogs(std::string filename) {
- std::vector<std::string> files;
+std::vector<internal::FileOperations::File> FindLogs(std::string filename) {
+ std::vector<internal::FileOperations::File> files;
FindLogs(&files, filename);
return files;
}
-std::vector<std::string> FindLogs(int argc, char **argv) {
- std::vector<std::string> found_logfiles;
+std::vector<internal::FileOperations::File> FindLogs(int argc, char **argv) {
+ std::vector<internal::FileOperations::File> found_logfiles;
for (int i = 1; i < argc; i++) {
std::string filename = argv[i];
@@ -320,8 +321,9 @@
std::vector<UnsortedOldParts> old_parts;
// Populates the class's datastructures from the input file list.
- void PopulateFromFiles(ReadersPool *readers,
- const std::vector<std::string> &parts);
+ void PopulateFromFiles(
+ ReadersPool *readers,
+ const std::vector<internal::FileOperations::File> &parts);
// Wrangles everything into a map of boot uuids -> boot counts.
MapBoots ComputeBootCounts();
@@ -342,18 +344,19 @@
std::vector<LogFile> SortParts();
};
-void PartsSorter::PopulateFromFiles(ReadersPool *readers,
- const std::vector<std::string> &parts) {
+void PartsSorter::PopulateFromFiles(
+ ReadersPool *readers,
+ const std::vector<internal::FileOperations::File> &parts) {
// Now extract everything into our datastructures above for sorting.
- for (const std::string &part : parts) {
- SpanReader *reader = readers->BorrowReader(part);
+ for (const internal::FileOperations::File &part : parts) {
+ SpanReader *reader = readers->BorrowReader(part.name);
std::optional<SizePrefixedFlatbufferVector<LogFileHeader>> log_header =
ReadHeader(reader);
if (!log_header) {
if (!FLAGS_quiet_sorting) {
- LOG(WARNING) << "Skipping " << part << " without a header";
+ LOG(WARNING) << "Skipping " << part.name << " without a header";
}
- corrupted.emplace_back(part);
+ corrupted.emplace_back(part.name);
continue;
}
@@ -433,11 +436,12 @@
continue;
}
- VLOG(1) << "Header " << FlatbufferToJson(log_header.value()) << " " << part;
+ VLOG(1) << "Header " << FlatbufferToJson(log_header.value()) << " "
+ << part.name;
if (configuration_sha256.empty()) {
CHECK(log_header->message().has_configuration())
- << ": Failed to find header on " << part;
+ << ": Failed to find header on " << part.name;
// If we don't have a configuration_sha256, we need to have a
// configuration directly inside the header. This ends up being a bit
// unwieldy to deal with, so let's instead copy the configuration, hash
@@ -464,7 +468,7 @@
configuration_sha256 = std::move(config_copy_sha256);
} else {
CHECK(!log_header->message().has_configuration())
- << ": Found header where one shouldn't be on " << part;
+ << ": Found header where one shouldn't be on " << part.name;
config_sha256_list.emplace(configuration_sha256);
}
@@ -475,12 +479,12 @@
!log_header->message().has_parts_index() &&
!log_header->message().has_node()) {
std::optional<SizePrefixedFlatbufferVector<MessageHeader>> first_message =
- ReadNthMessage(part, 0);
+ ReadNthMessage(part.name, 0);
if (!first_message) {
if (!FLAGS_quiet_sorting) {
- LOG(WARNING) << "Skipping " << part << " without any messages";
+ LOG(WARNING) << "Skipping " << part.name << " without any messages";
}
- corrupted.emplace_back(part);
+ corrupted.emplace_back(part.name);
continue;
}
const monotonic_clock::time_point first_message_time(
@@ -500,11 +504,11 @@
old_parts.back().parts.realtime_start_time = realtime_start_time;
old_parts.back().parts.config_sha256 = configuration_sha256;
old_parts.back().unsorted_parts.emplace_back(
- std::make_pair(first_message_time, part));
+ std::make_pair(first_message_time, part.name));
old_parts.back().name = name;
} else {
result->unsorted_parts.emplace_back(
- std::make_pair(first_message_time, part));
+ std::make_pair(first_message_time, part.name));
CHECK_EQ(result->name, name);
CHECK_EQ(result->parts.config_sha256, configuration_sha256);
}
@@ -890,7 +894,7 @@
CHECK_EQ(it->second.realtime_start_time, realtime_start_time);
}
- it->second.parts.emplace_back(std::make_pair(part, parts_index));
+ it->second.parts.emplace_back(std::make_pair(part.name, parts_index));
}
}
@@ -1985,16 +1989,39 @@
}
std::vector<LogFile> SortParts(const std::vector<std::string> &parts) {
- LogReadersPool readers;
- PartsSorter sorter;
- sorter.PopulateFromFiles(&readers, parts);
- return sorter.SortParts();
+ std::vector<internal::FileOperations::File> full_parts;
+ full_parts.reserve(parts.size());
+ for (const auto &p : parts) {
+ full_parts.emplace_back(internal::FileOperations::File{
+ .name = p,
+ .size = 0u,
+ });
+ }
+ return SortParts(full_parts);
}
std::vector<LogFile> SortParts(const LogSource &log_source) {
LogReadersPool readers(&log_source);
PartsSorter sorter;
- sorter.PopulateFromFiles(&readers, log_source.ListFiles());
+ std::vector<LogSource::File> files = log_source.ListFiles();
+ std::vector<internal::FileOperations::File> arg;
+ arg.reserve(files.size());
+ for (LogSource::File &f : files) {
+ arg.emplace_back(internal::FileOperations::File{
+ .name = std::move(f.name),
+ .size = f.size,
+ });
+ }
+ sorter.PopulateFromFiles(&readers, arg);
+ return sorter.SortParts();
+}
+
+std::vector<LogFile> SortParts(
+ const std::vector<internal::FileOperations::File> &files) {
+ LogReadersPool readers;
+ PartsSorter sorter;
+
+ sorter.PopulateFromFiles(&readers, files);
return sorter.SortParts();
}
diff --git a/aos/events/logging/logfile_sorting.h b/aos/events/logging/logfile_sorting.h
index 7461e89..b7f8297 100644
--- a/aos/events/logging/logfile_sorting.h
+++ b/aos/events/logging/logfile_sorting.h
@@ -10,6 +10,7 @@
#include <vector>
#include "aos/configuration.h"
+#include "aos/events/logging/file_operations.h"
#include "aos/events/logging/log_backend.h"
#include "aos/time/time.h"
#include "aos/uuid.h"
@@ -136,20 +137,23 @@
// Takes a bunch of parts and sorts them based on part_uuid and part_index.
std::vector<LogFile> SortParts(const std::vector<std::string> &parts);
+std::vector<LogFile> SortParts(
+ const std::vector<internal::FileOperations::File> &parts);
// Sort parts of a single log.
std::vector<LogFile> SortParts(const LogSource &log_source);
// Recursively searches the file/folder for .bfbs and .bfbs.xz files and adds
// them to the vector.
-void FindLogs(std::vector<std::string> *files, std::string filename);
+void FindLogs(std::vector<internal::FileOperations::File> *files,
+ std::string filename);
// Recursively searches the file/folder for .bfbs and .bfbs.xz files and returns
// them in a vector.
-std::vector<std::string> FindLogs(std::string filename);
+std::vector<internal::FileOperations::File> FindLogs(std::string filename);
// Recursively searches for logfiles in argv[1] and onward.
-std::vector<std::string> FindLogs(int argc, char **argv);
+std::vector<internal::FileOperations::File> FindLogs(int argc, char **argv);
// Proxy container to bind log parts with log source. It helps with reading logs
// from virtual media such as memory or S3.
diff --git a/aos/events/logging/s3_fetcher.cc b/aos/events/logging/s3_fetcher.cc
index f44a20b..4207286 100644
--- a/aos/events/logging/s3_fetcher.cc
+++ b/aos/events/logging/s3_fetcher.cc
@@ -179,22 +179,25 @@
get_next_chunk_ = GetS3Client().GetObjectCallable(get_request);
}
-std::vector<std::string> ListS3Objects(std::string_view url) {
+std::vector<std::pair<std::string, size_t>> ListS3Objects(
+ std::string_view url) {
Aws::S3::Model::ListObjectsV2Request list_request;
const ObjectName object_name = ParseUrl(url);
list_request.SetBucket(object_name.bucket);
list_request.SetPrefix(object_name.key);
Aws::S3::Model::ListObjectsV2Outcome list_outcome =
GetS3Client().ListObjectsV2(list_request);
- std::vector<std::string> result;
+ std::vector<std::pair<std::string, size_t>> result;
while (true) {
CHECK(list_outcome.IsSuccess()) << ": Listing objects for " << url
<< " failed: " << list_outcome.GetError();
auto &list_result = list_outcome.GetResult();
for (const Aws::S3::Model::Object &object : list_result.GetContents()) {
- result.push_back(absl::StrCat("s3://", list_outcome.GetResult().GetName(),
- "/", object.GetKey()));
- VLOG(2) << "got " << result.back();
+ result.emplace_back(
+ absl::StrCat("s3://", list_outcome.GetResult().GetName(), "/",
+ object.GetKey()),
+ object.GetSize());
+ VLOG(2) << "got " << result.back().first;
}
if (!list_result.GetIsTruncated()) {
break;
diff --git a/aos/events/logging/s3_fetcher.h b/aos/events/logging/s3_fetcher.h
index 41bc114..73584cb 100644
--- a/aos/events/logging/s3_fetcher.h
+++ b/aos/events/logging/s3_fetcher.h
@@ -54,8 +54,8 @@
ObjectName ParseUrl(std::string_view url);
// Does an S3 object listing with the given URL prefix. Returns the URLs for all
-// the objects under it.
-std::vector<std::string> ListS3Objects(std::string_view url);
+// the objects under it, and the size.
+std::vector<std::pair<std::string, size_t>> ListS3Objects(std::string_view url);
} // namespace aos::logger
diff --git a/aos/events/logging/s3_file_operations.cc b/aos/events/logging/s3_file_operations.cc
index 8764d4a..129b7e2 100644
--- a/aos/events/logging/s3_file_operations.cc
+++ b/aos/events/logging/s3_file_operations.cc
@@ -4,17 +4,30 @@
namespace aos::logger::internal {
-S3FileOperations::S3FileOperations(std::string_view url)
- : object_urls_(ListS3Objects(url)) {}
+std::vector<FileOperations::File> Convert(
+ std::vector<std::pair<std::string, size_t>> &&input) {
+ std::vector<FileOperations::File> result;
+ result.reserve(input.size());
+ for (std::pair<std::string, size_t> &i : input) {
+ result.emplace_back(FileOperations::File{
+ .name = std::move(i.first),
+ .size = i.second,
+ });
+ }
+ return result;
+}
-void S3FileOperations::FindLogs(std::vector<std::string> *files) {
+S3FileOperations::S3FileOperations(std::string_view url)
+ : object_urls_(Convert(ListS3Objects(url))) {}
+
+void S3FileOperations::FindLogs(std::vector<File> *files) {
// We already have a recursive listing, so just grab all the objects from
// there.
- for (const std::string &object_url : object_urls_) {
- if (IsValidFilename(object_url)) {
+ for (const File &object_url : object_urls_) {
+ if (IsValidFilename(object_url.name)) {
files->push_back(object_url);
}
}
}
-} // namespace aos::logger::internal
\ No newline at end of file
+} // namespace aos::logger::internal
diff --git a/aos/events/logging/s3_file_operations.h b/aos/events/logging/s3_file_operations.h
index ae94f62..e75e56b 100644
--- a/aos/events/logging/s3_file_operations.h
+++ b/aos/events/logging/s3_file_operations.h
@@ -11,10 +11,10 @@
bool Exists() final { return !object_urls_.empty(); }
- void FindLogs(std::vector<std::string> *files) final;
+ void FindLogs(std::vector<File> *files) final;
private:
- const std::vector<std::string> object_urls_;
+ const std::vector<File> object_urls_;
};
} // namespace aos::logger::internal
diff --git a/aos/events/logging/single_node_merge.cc b/aos/events/logging/single_node_merge.cc
index afb88af..aee2c5e 100644
--- a/aos/events/logging/single_node_merge.cc
+++ b/aos/events/logging/single_node_merge.cc
@@ -20,8 +20,7 @@
namespace chrono = std::chrono;
int Main(int argc, char **argv) {
- const std::vector<std::string> unsorted_logfiles = FindLogs(argc, argv);
- const LogFilesContainer log_files(SortParts(unsorted_logfiles));
+ const LogFilesContainer log_files(SortParts(FindLogs(argc, argv)));
const Configuration *config = log_files.config();
// Haven't tested this on a single node log, and don't really see a need to
diff --git a/aos/events/logging/timestamp_extractor.cc b/aos/events/logging/timestamp_extractor.cc
index 72f9de8..0b22f93 100644
--- a/aos/events/logging/timestamp_extractor.cc
+++ b/aos/events/logging/timestamp_extractor.cc
@@ -18,8 +18,7 @@
namespace chrono = std::chrono;
int Main(int argc, char **argv) {
- const std::vector<std::string> unsorted_logfiles = FindLogs(argc, argv);
- const LogFilesContainer log_files(SortParts(unsorted_logfiles));
+ const LogFilesContainer log_files(SortParts(FindLogs(argc, argv)));
const Configuration *config = log_files.config();
CHECK(configuration::MultiNode(config))
diff --git a/aos/network/log_web_proxy_main.cc b/aos/network/log_web_proxy_main.cc
index f93c5a2..12276c3 100644
--- a/aos/network/log_web_proxy_main.cc
+++ b/aos/network/log_web_proxy_main.cc
@@ -25,11 +25,8 @@
int main(int argc, char **argv) {
aos::InitGoogle(&argc, &argv);
- const std::vector<std::string> unsorted_logfiles =
- aos::logger::FindLogs(argc, argv);
-
const std::vector<aos::logger::LogFile> logfiles =
- aos::logger::SortParts(unsorted_logfiles);
+ aos::logger::SortParts(aos::logger::FindLogs(argc, argv));
aos::logger::LogReader reader(logfiles);