From c40d61950ed6e596c8c221a7f6011f708b391f02 Mon Sep 17 00:00:00 2001 From: "A. Cody Schuffelen" Date: Thu, 16 Jul 2026 18:00:13 -0700 Subject: [PATCH 1/2] Extract `format_byte_size` from `fetch_tracer` Bug: b/535754069 --- .../host/commands/cvd/cli/BUILD.bazel | 7 +++ .../host/commands/cvd/cli/format_byte_size.cc | 46 +++++++++++++++++++ .../host/commands/cvd/cli/format_byte_size.h | 26 +++++++++++ .../host/commands/cvd/fetch/BUILD.bazel | 5 +- .../host/commands/cvd/fetch/fetch_tracer.cpp | 22 +-------- 5 files changed, 85 insertions(+), 21 deletions(-) create mode 100644 base/cvd/cuttlefish/host/commands/cvd/cli/format_byte_size.cc create mode 100644 base/cvd/cuttlefish/host/commands/cvd/cli/format_byte_size.h diff --git a/base/cvd/cuttlefish/host/commands/cvd/cli/BUILD.bazel b/base/cvd/cuttlefish/host/commands/cvd/cli/BUILD.bazel index d796556a93b..190c5f5a14b 100644 --- a/base/cvd/cuttlefish/host/commands/cvd/cli/BUILD.bazel +++ b/base/cvd/cuttlefish/host/commands/cvd/cli/BUILD.bazel @@ -16,6 +16,13 @@ cf_cc_library( ], ) +cf_cc_library( + name = "format_byte_size", + srcs = ["format_byte_size.cc"], + hdrs = ["format_byte_size.h"], + deps = ["@fmt"], +) + cf_cc_library( name = "frontline_parser", srcs = ["frontline_parser.cpp"], diff --git a/base/cvd/cuttlefish/host/commands/cvd/cli/format_byte_size.cc b/base/cvd/cuttlefish/host/commands/cvd/cli/format_byte_size.cc new file mode 100644 index 00000000000..5edf6ea6ba4 --- /dev/null +++ b/base/cvd/cuttlefish/host/commands/cvd/cli/format_byte_size.cc @@ -0,0 +1,46 @@ +// +// Copyright (C) 2024 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "cuttlefish/host/commands/cvd/cli/format_byte_size.h" + +#include + +#include + +#include "fmt/format.h" + +namespace cuttlefish { + +std::string FormatByteSize(uint64_t size) { + if (size < 10240) { + return fmt::format("{} B", size); + } + size /= 1024; + if (size < 10240) { + return fmt::format("{} KiB", size); + } + size /= 1024; + if (size < 10240) { + return fmt::format("{} MiB", size); + } + size /= 1024; + if (size < 10240) { + return fmt::format("{} GiB", size); + } + size /= 1024; + return fmt::format("{} TiB", size); +} + +} // namespace cuttlefish diff --git a/base/cvd/cuttlefish/host/commands/cvd/cli/format_byte_size.h b/base/cvd/cuttlefish/host/commands/cvd/cli/format_byte_size.h new file mode 100644 index 00000000000..5edb92704fb --- /dev/null +++ b/base/cvd/cuttlefish/host/commands/cvd/cli/format_byte_size.h @@ -0,0 +1,26 @@ +// +// Copyright (C) 2024 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include + +#include + +namespace cuttlefish { + +std::string FormatByteSize(uint64_t size); + +} // namespace cuttlefish diff --git a/base/cvd/cuttlefish/host/commands/cvd/fetch/BUILD.bazel b/base/cvd/cuttlefish/host/commands/cvd/fetch/BUILD.bazel index 1fef0f6fc3d..42f2b9178c3 100644 --- a/base/cvd/cuttlefish/host/commands/cvd/fetch/BUILD.bazel +++ b/base/cvd/cuttlefish/host/commands/cvd/fetch/BUILD.bazel @@ -270,7 +270,10 @@ cf_cc_library( name = "fetch_tracer", srcs = ["fetch_tracer.cpp"], hdrs = ["fetch_tracer.h"], - deps = ["@fmt"], + deps = [ + "//cuttlefish/host/commands/cvd/cli:format_byte_size", + "@fmt", + ], ) cf_cc_library( diff --git a/base/cvd/cuttlefish/host/commands/cvd/fetch/fetch_tracer.cpp b/base/cvd/cuttlefish/host/commands/cvd/fetch/fetch_tracer.cpp index 91743395c10..52bfa62a948 100644 --- a/base/cvd/cuttlefish/host/commands/cvd/fetch/fetch_tracer.cpp +++ b/base/cvd/cuttlefish/host/commands/cvd/fetch/fetch_tracer.cpp @@ -28,6 +28,8 @@ #include "fmt/format.h" +#include "cuttlefish/host/commands/cvd/cli/format_byte_size.h" + namespace cuttlefish { namespace { @@ -57,26 +59,6 @@ std::chrono::milliseconds FullDuration(const FetchTracer::TraceImpl& trace) { return total_duration; } -std::string FormatByteSize(uint64_t size) { - if (size < 10240) { - return fmt::format("{} B", size); - } - size /= 1024; - if (size < 10240) { - return fmt::format("{} KiB", size); - } - size /= 1024; - if (size < 10240) { - return fmt::format("{} MiB", size); - } - size /= 1024; - if (size < 10240) { - return fmt::format("{} GiB", size); - } - size /= 1024; - return fmt::format("{} TiB", size); -} - std::string FormatDuration(std::chrono::milliseconds duration_ms) { if (duration_ms < std::chrono::milliseconds(1000)) { return fmt::format("{} ms", duration_ms.count()); From ad3b8403cf3f82e78e212fea55d9af1251898e96 Mon Sep 17 00:00:00 2001 From: "A. Cody Schuffelen" Date: Thu, 16 Jul 2026 18:00:29 -0700 Subject: [PATCH 2/2] Show the file size of the tracked files in the monitor Bug: b/535754069 --- .../cvd/cli/commands/monitor/BUILD.bazel | 1 + .../cvd/cli/commands/monitor/display.cc | 57 +++++++++++-------- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/base/cvd/cuttlefish/host/commands/cvd/cli/commands/monitor/BUILD.bazel b/base/cvd/cuttlefish/host/commands/cvd/cli/commands/monitor/BUILD.bazel index 2a086a08247..2e305692afb 100644 --- a/base/cvd/cuttlefish/host/commands/cvd/cli/commands/monitor/BUILD.bazel +++ b/base/cvd/cuttlefish/host/commands/cvd/cli/commands/monitor/BUILD.bazel @@ -37,6 +37,7 @@ cf_cc_library( "//cuttlefish/ansi_codes:should_color", "//cuttlefish/common/libs/utils:environment", "//cuttlefish/common/libs/utils:tee_logging", + "//cuttlefish/host/commands/cvd/cli:format_byte_size", "//cuttlefish/host/libs/log_names", "//cuttlefish/io", "//cuttlefish/io:read_exact", diff --git a/base/cvd/cuttlefish/host/commands/cvd/cli/commands/monitor/display.cc b/base/cvd/cuttlefish/host/commands/cvd/cli/commands/monitor/display.cc index 6db7f6481b1..861d8c443c0 100644 --- a/base/cvd/cuttlefish/host/commands/cvd/cli/commands/monitor/display.cc +++ b/base/cvd/cuttlefish/host/commands/cvd/cli/commands/monitor/display.cc @@ -16,8 +16,7 @@ #include "cuttlefish/host/commands/cvd/cli/commands/monitor/display.h" -#include -#include +#include #include #include @@ -30,6 +29,7 @@ #include "absl/log/check.h" #include "absl/strings/cord.h" +#include "absl/strings/match.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_replace.h" #include "absl/strings/str_split.h" @@ -41,6 +41,7 @@ #include "cuttlefish/host/commands/cvd/cli/commands/monitor/log_tee.h" #include "cuttlefish/host/commands/cvd/cli/commands/monitor/logcat.h" #include "cuttlefish/host/commands/cvd/cli/commands/monitor/truncate.h" +#include "cuttlefish/host/commands/cvd/cli/format_byte_size.h" #include "cuttlefish/host/libs/log_names/log_names.h" #include "cuttlefish/io/io.h" #include "cuttlefish/io/read_exact.h" @@ -50,16 +51,21 @@ namespace cuttlefish { namespace { -Result> GetLastNLines(ReaderSeeker& rs, size_t n) { - uint64_t file_size = CF_EXPECT(rs.SeekEnd(0)); - CF_EXPECT(file_size != -1, "Failed to seek to end of file"); +struct FileData { + std::vector last_lines; + size_t total_size = 0; +}; + +Result GetLastNLines(ReaderSeeker& rs, size_t n) { + FileData ret; + ret.total_size = CF_EXPECT(rs.SeekEnd(0)); absl::Cord accumulated_data; - off_t offset = file_size; + size_t offset = ret.total_size; size_t newline_count = 0; while (offset > 0 && newline_count < n + 1) { - static constexpr off_t kChunkSize = 4096; + static constexpr size_t kChunkSize = 4096; size_t to_read = std::min(kChunkSize, offset); offset -= to_read; CF_EXPECT(rs.SeekSet(offset)); @@ -71,18 +77,18 @@ Result> GetLastNLines(ReaderSeeker& rs, size_t n) { accumulated_data.Prepend(std::move(chunk)); } - std::vector all_lines = - absl::StrSplit(std::string(accumulated_data), '\n'); + ret.last_lines = absl::StrSplit(std::string(accumulated_data), '\n'); // Handle trailing newline - if (!all_lines.empty() && all_lines.back().empty()) { - all_lines.pop_back(); + if (!ret.last_lines.empty() && ret.last_lines.back().empty()) { + ret.last_lines.pop_back(); } - size_t start_idx = all_lines.size() > n ? all_lines.size() - n : 0; - all_lines.erase(all_lines.begin(), all_lines.begin() + start_idx); + size_t start_idx = ret.last_lines.size() > n ? ret.last_lines.size() - n : 0; + ret.last_lines.erase(ret.last_lines.begin(), + ret.last_lines.begin() + start_idx); - return all_lines; + return ret; } } // namespace @@ -95,13 +101,16 @@ void LogMonitorDisplay::DrawFile(ReaderSeeker& rs, const std::string& title, if (max_lines == 0) { return; } + std::string title_with_size = title; std::vector lines; - Result> lines_result = GetLastNLines(rs, max_lines); - if (lines_result.ok()) { - lines = *lines_result; + Result file_data = GetLastNLines(rs, max_lines); + if (file_data.ok()) { + lines = file_data->last_lines; + absl::StrAppend(&title_with_size, " (", + FormatByteSize(file_data->total_size), ")"); } else { lines.push_back(absl::StrCat("Failed to read ", title, ":")); - std::string error_str = lines_result.error().FormatForEnv(/*color=*/false); + std::string error_str = file_data.error().FormatForEnv(/*color=*/false); for (const auto& el : absl::StrSplit(error_str, '\n')) { if (!el.empty()) { lines.push_back(std::string(el)); @@ -116,7 +125,7 @@ void LogMonitorDisplay::DrawFile(ReaderSeeker& rs, const std::string& title, lines.push_back(""); } - DrawBorderedText(lines, title); + DrawBorderedText(lines, title_with_size); } void LogMonitorDisplay::DrawFile(ReaderSeeker&& rs, const std::string& title, @@ -151,7 +160,9 @@ void LogMonitorDisplay::DrawBorderedText(const std::vector& lines, line = sanitized_holder; } - if (title == kLogNameLauncher && line.find("log_tee(") == 0) { + const bool cf_log = absl::StrContains(title, kLogNameAssembleCvd) || + absl::StrContains(title, kLogNameLauncher); + if (cf_log && line.find("log_tee(") == 0) { const size_t bracket = line.find(']'); if (bracket != std::string_view::npos) { line.remove_prefix(bracket + 1); @@ -169,21 +180,21 @@ void LogMonitorDisplay::DrawBorderedText(const std::vector& lines, } } - if (title == kLogNameLogcat) { + if (absl::StrContains(title, kLogNameLogcat)) { if (Result parsed = ParseLogcatLine(line); parsed.ok()) { FormatAndDrawLine(FormatLogcatLine(*parsed)); continue; } } - if (title == kLogNameKernel) { + if (absl::StrContains(title, kLogNameKernel)) { if (Result parsed = ParseKernelLine(line); parsed.ok()) { FormatAndDrawLine(FormatKernelLine(*parsed)); continue; } } - if (title == kLogNameLauncher) { + if (absl::StrContains(title, kLogNameLauncher)) { if (Result parsed = ParseLauncherLine(line); parsed.ok()) { FormatAndDrawLine(FormatLauncherLine(*parsed)); continue;