Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,6 @@ cf_cc_library(
srcs = ["logs.cpp"],
hdrs = ["logs.h"],
deps = [
"//cuttlefish/common/libs/utils:files",
"//cuttlefish/common/libs/utils:flag_parser",
"//cuttlefish/host/commands/cvd/cli:command_request",
"//cuttlefish/host/commands/cvd/cli:types",
Expand Down
65 changes: 47 additions & 18 deletions base/cvd/cuttlefish/host/commands/cvd/cli/commands/logs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include <vector>

#include "absl/log/log.h"
#include "cuttlefish/common/libs/utils/files.h"
#include "cuttlefish/common/libs/utils/flag_parser.h"
#include "cuttlefish/host/commands/cvd/cli/command_request.h"
#include "cuttlefish/host/commands/cvd/cli/commands/command_handler.h"
Expand Down Expand Up @@ -42,8 +41,8 @@ struct LogsCmdOptions {
}
};

Result<void> PrintLogsList(const std::string& dir) {
auto callback = [](const std::string& filename) -> Result<void> {
void PrintLogsList(const std::vector<std::string>& filenames) {
for (auto& filename : filenames) {
std::string basename = android::base::Basename(filename);
std::cout << basename;
std::cout << " ";
Expand All @@ -55,10 +54,20 @@ Result<void> PrintLogsList(const std::string& dir) {
}
std::cout << filename;
std::cout << std::endl;
return {};
};
CF_EXPECT(WalkDirectory(dir, callback));
return {};
}

std::vector<std::string> RemoveInaccessibleFilenames(
std::vector<std::string> filenames) {
std::erase_if(filenames, [](const std::string& v) {
bool accessible = access(v.c_str(), F_OK) == 0;
if (!accessible) {
std::string basename = android::base::Basename(v);
VLOG(0) << "Logs file `" << basename << "` not found at \"" << v << "\"";
}
return !accessible;
});
return filenames;
}

Result<void> PrintLog(const std::string& filename) {
Expand All @@ -73,31 +82,51 @@ CvdLogsHandler::CvdLogsHandler(InstanceManager& instance_manager)
: instance_manager_(instance_manager) {}

Result<void> CvdLogsHandler::Handle(const CommandRequest& request) {
auto [instance, _] =
auto [instance, group] =
CF_EXPECT(selector::SelectInstance(instance_manager_, request),
"Unable to select an instance");

LogsCmdOptions opts;
std::vector<std::string> args = request.SubcommandArguments();
CF_EXPECT(ConsumeFlags(opts.Flags(), args));

std::string dir = instance.instance_dir();
std::string logs_dir = dir + "/logs";
if (!FileExists(logs_dir)) {
VLOG(0) << "Logs directory `" << logs_dir << "` does not exist.";
LOG(INFO) << "There are no logs files available";
return {};
std::vector<std::string> logs_filenames;

auto group_names = RemoveInaccessibleFilenames(group.LogsFilenames());
logs_filenames = group_names;
auto ins_names =
RemoveInaccessibleFilenames(CF_EXPECT(instance.LogsFilenames()));
// Avoid inserting instance log names that are already fetched at group level.
for (auto ins_filename : ins_names) {
std::string base = android::base::Basename(ins_filename);
auto p = [base](const auto& v) {
return base == android::base::Basename(v);
};
auto it = std::find_if(group_names.begin(), group_names.end(), p);
if (it == group_names.end()) {
logs_filenames.push_back(ins_filename);
}
}
CF_EXPECT(IsDirectory(logs_dir));

if (opts.print_target.empty()) {
CF_EXPECT(PrintLogsList(logs_dir));
if (logs_filenames.empty()) {
LOG(INFO) << "There are no log files available";
} else {
PrintLogsList(logs_filenames);
}
return {};
}

std::string print_target = logs_dir + "/" + opts.print_target;
CF_EXPECT(FileExists(print_target));
CF_EXPECT(PrintLog(print_target));
for (auto& filename : logs_filenames) {
std::string basename = android::base::Basename(filename);
if (basename == opts.print_target) {
CF_EXPECT(PrintLog(filename));
return {};
}
};

CF_EXPECTF(false, "Not found `{}` logs", opts.print_target);

return {};
}

Expand Down
18 changes: 15 additions & 3 deletions base/cvd/cuttlefish/host/commands/cvd/instances/local_instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@

#include "cuttlefish/host/commands/cvd/instances/local_instance.h"

#include <android-base/file.h>
#include <fmt/format.h>

#include <fstream>
#include <memory>
#include <string>
#include <utility>

#include <fmt/format.h>
#include "absl/log/log.h"

#include "cuttlefish/common/libs/utils/contains.h"
#include "cuttlefish/common/libs/utils/files.h"
#include "cuttlefish/common/libs/utils/subprocess.h"
#include "cuttlefish/common/libs/utils/subprocess_managed_stdio.h"
Expand Down Expand Up @@ -62,7 +64,7 @@ void LocalInstance::set_state(cvd::InstanceState state) {
std::string LocalInstance::instance_dir() const {
std::string to_ret = fmt::format("{}/cuttlefish/instances/cvd-{}",
group_proto_->home_directory(), id());
if(!FileExists(to_ret)) {
if (!FileExists(to_ret)) {
// Legacy launchers create cuttlefish_runtime.{$ID}
to_ret = fmt::format("{}/cuttlefish_runtime.{}",
group_proto_->home_directory(), id());
Expand Down Expand Up @@ -272,4 +274,14 @@ Result<SharedFD> LocalInstance::GetLauncherMonitor(
return monitor;
}

Result<std::vector<std::string>> LocalInstance::LogsFilenames() const {
std::vector<std::string> result = {};
auto callback = [&result](const std::string& filename) -> Result<void> {
result.push_back(filename);
return {};
};
CF_EXPECT(WalkDirectory(instance_dir() + "/logs", callback));
return result;
}

} // namespace cuttlefish
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@

#pragma once

#include <json/json.h>

#include <chrono>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <json/json.h>

#include "cuttlefish/common/libs/fs/shared_fd.h"
#include "cuttlefish/host/commands/cvd/instances/cvd_persistent_data.pb.h"
#include "cuttlefish/host/libs/config/cuttlefish_config.h"
Expand Down Expand Up @@ -74,6 +74,9 @@ class LocalInstance {
Result<void> StartRecording(std::chrono::seconds launcher_timeout);
Result<void> StopRecording(std::chrono::seconds launcher_timeout);

// Return list of filenames of instance-level log files.
Result<std::vector<std::string>> LogsFilenames() const;

private:
LocalInstance(std::shared_ptr<cvd::InstanceGroup> group_proto,
cvd::Instance* instance_proto);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

#include "cuttlefish/host/commands/cvd/instances/local_instance_group.h"

#include <android-base/file.h>
#include <json/json.h>

#include <algorithm>
#include <functional>
#include <iterator>
Expand All @@ -24,10 +27,7 @@
#include <utility>
#include <vector>

#include <android-base/file.h>
#include "absl/strings/str_join.h"
#include <json/json.h>

#include "cuttlefish/host/commands/cvd/instances/instance_database_types.h"
#include "cuttlefish/host/commands/cvd/instances/local_instance.h"
#include "cuttlefish/host/commands/cvd/utils/common.h"
Expand Down Expand Up @@ -131,8 +131,7 @@ Result<LocalInstanceGroup> LocalInstanceGroup::Builder::Build() {
product_out_paths.emplace_back(ProductDirFromBase(base_dir_, i));
}

group_proto_.set_product_out_path(
absl::StrJoin(product_out_paths, ","));
group_proto_.set_product_out_path(absl::StrJoin(product_out_paths, ","));
return CF_EXPECT(LocalInstanceGroup::Create(group_proto_));
}

Expand Down Expand Up @@ -204,6 +203,15 @@ std::string LocalInstanceGroup::BaseDir() const {
return android::base::Dirname(HomeDir());
}

std::vector<std::string> LocalInstanceGroup::LogsFilenames() const {
return {
AssemblyDir() + "/assemble_cvd.log",
AssemblyDir() + "/cuttlefish_config.json",
ArtifactsDir() + "/fetch.log",
MetricsDir() + "/metrics.log",
};
}

Result<Json::Value> LocalInstanceGroup::FetchStatus(
std::chrono::seconds timeout) {
Json::Value instances_json(Json::arrayValue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@

#pragma once

#include <json/json.h>

#include <memory>
#include <string>
#include <vector>

#include <json/json.h>

#include "cuttlefish/host/commands/cvd/instances/cvd_persistent_data.pb.h"
#include "cuttlefish/host/commands/cvd/instances/instance_database_types.h"
#include "cuttlefish/host/commands/cvd/instances/local_instance.h"
Expand Down Expand Up @@ -74,6 +74,9 @@ class LocalInstanceGroup {
std::string ArtifactsDir() const;
std::string ProductDir(int instance_index) const;

// Return list of filenames of group-level log files.
std::vector<std::string> LogsFilenames() const;

Result<LocalInstance> FindInstanceById(unsigned id) const;
/**
* Find by per-instance name.
Expand Down
Loading
Loading