Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions base/cvd/cuttlefish/host/commands/cvd/cli/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@

#include "cuttlefish/host/commands/cvd/cli/commands/monitor/display.h"

#include <stdint.h>
#include <sys/types.h>
#include <stddef.h>

#include <algorithm>
#include <cstddef>
Expand All @@ -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"
Expand All @@ -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"
Expand All @@ -50,16 +51,21 @@ namespace cuttlefish {

namespace {

Result<std::vector<std::string>> 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<std::string> last_lines;
size_t total_size = 0;
};

Result<FileData> 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));
Expand All @@ -71,18 +77,18 @@ Result<std::vector<std::string>> GetLastNLines(ReaderSeeker& rs, size_t n) {
accumulated_data.Prepend(std::move(chunk));
}

std::vector<std::string> 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
Expand All @@ -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<std::string> lines;
Result<std::vector<std::string>> lines_result = GetLastNLines(rs, max_lines);
if (lines_result.ok()) {
lines = *lines_result;
Result<FileData> 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));
Expand All @@ -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,
Expand Down Expand Up @@ -151,7 +160,9 @@ void LogMonitorDisplay::DrawBorderedText(const std::vector<std::string>& 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);
Expand All @@ -169,21 +180,21 @@ void LogMonitorDisplay::DrawBorderedText(const std::vector<std::string>& lines,
}
}

if (title == kLogNameLogcat) {
if (absl::StrContains(title, kLogNameLogcat)) {
if (Result<LogcatLine> parsed = ParseLogcatLine(line); parsed.ok()) {
FormatAndDrawLine(FormatLogcatLine(*parsed));
continue;
}
}

if (title == kLogNameKernel) {
if (absl::StrContains(title, kLogNameKernel)) {
if (Result<KernelLine> parsed = ParseKernelLine(line); parsed.ok()) {
FormatAndDrawLine(FormatKernelLine(*parsed));
continue;
}
}

if (title == kLogNameLauncher) {
if (absl::StrContains(title, kLogNameLauncher)) {
if (Result<LauncherLine> parsed = ParseLauncherLine(line); parsed.ok()) {
FormatAndDrawLine(FormatLauncherLine(*parsed));
continue;
Expand Down
46 changes: 46 additions & 0 deletions base/cvd/cuttlefish/host/commands/cvd/cli/format_byte_size.cc
Original file line number Diff line number Diff line change
@@ -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 <stdint.h>

#include <string>

#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
26 changes: 26 additions & 0 deletions base/cvd/cuttlefish/host/commands/cvd/cli/format_byte_size.h
Original file line number Diff line number Diff line change
@@ -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 <stdint.h>

#include <string>

namespace cuttlefish {

std::string FormatByteSize(uint64_t size);

} // namespace cuttlefish
5 changes: 4 additions & 1 deletion base/cvd/cuttlefish/host/commands/cvd/fetch/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
22 changes: 2 additions & 20 deletions base/cvd/cuttlefish/host/commands/cvd/fetch/fetch_tracer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@

#include "fmt/format.h"

#include "cuttlefish/host/commands/cvd/cli/format_byte_size.h"

namespace cuttlefish {
namespace {

Expand Down Expand Up @@ -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());
Expand Down
Loading