Improve starter_cmd status output
This makes "starter_cmd status" output the time since an application
was started. If you specify an application, it outputs
the application name, time since last started, and state.
Change-Id: Ibccaa19f12c8e7c4cdde384f9594ab7c00ae5224
diff --git a/aos/starter/BUILD b/aos/starter/BUILD
index fbd29fd..683d23d 100644
--- a/aos/starter/BUILD
+++ b/aos/starter/BUILD
@@ -95,6 +95,7 @@
target_compatible_with = ["@platforms//os:linux"],
deps = [
":starter_rpc_lib",
+ "//aos/time:time",
"@com_github_google_glog//:glog",
"@com_google_absl//absl/strings:str_format",
],
diff --git a/aos/starter/starter_cmd.cc b/aos/starter/starter_cmd.cc
index 1381fa3..8f9e125 100644
--- a/aos/starter/starter_cmd.cc
+++ b/aos/starter/starter_cmd.cc
@@ -1,11 +1,13 @@
#include <chrono>
#include <functional>
#include <iostream>
+#include <optional>
#include <unordered_map>
#include "absl/strings/str_format.h"
#include "aos/init.h"
#include "aos/json_to_flatbuffer.h"
+#include "aos/time/time.h"
#include "gflags/gflags.h"
#include "starter_rpc_lib.h"
@@ -13,25 +15,49 @@
namespace {
+namespace chrono = std::chrono;
+
static const std::unordered_map<std::string, aos::starter::Command>
kCommandConversions{{"start", aos::starter::Command::START},
{"stop", aos::starter::Command::STOP},
{"restart", aos::starter::Command::RESTART}};
+void PrintKey() {
+ absl::PrintF("%-30s %-30s %s\n\n", "Name", "Time since last started", "State");
+}
+
+void PrintApplicationStatus(const aos::starter::ApplicationStatus *app_status,
+ const aos::monotonic_clock::time_point &time) {
+ const auto last_start_time =
+ aos::monotonic_clock::time_point(chrono::nanoseconds(app_status->last_start_time()));
+ const auto time_running =
+ chrono::duration_cast<chrono::seconds>(time - last_start_time);
+ absl::PrintF("%-30s %-30s %s\n", app_status->name()->string_view(),
+ std::to_string(time_running.count()) + 's',
+ aos::starter::EnumNameState(app_status->state()));
+}
+
bool GetStarterStatus(int argc, char **argv, const aos::Configuration *config) {
if (argc == 1) {
// Print status for all processes.
- auto status = aos::starter::GetStarterStatus(config);
- for (const aos::starter::ApplicationStatus *app_status :
- *status.message().statuses()) {
- absl::PrintF("%-30s %s\n", app_status->name()->string_view(),
- aos::starter::EnumNameState(app_status->state()));
+ const auto optional_status = aos::starter::GetStarterStatus(config);
+ if (optional_status) {
+ auto status = *optional_status;
+ const auto time = aos::monotonic_clock::now();
+ PrintKey();
+ for (const aos::starter::ApplicationStatus *app_status :
+ *status.message().statuses()) {
+ PrintApplicationStatus(app_status, time);
+ }
+ } else {
+ LOG(WARNING) << "No status found";
}
} else if (argc == 2) {
// Print status for the specified process.
const char *application_name = argv[1];
auto status = aos::starter::GetStatus(application_name, config);
- std::cout << aos::FlatbufferToJson(&status.message()) << '\n';
+ PrintKey();
+ PrintApplicationStatus(&status.message(), aos::monotonic_clock::now());
} else {
LOG(ERROR) << "The \"status\" command requires zero or one arguments.";
return true;
@@ -58,7 +84,7 @@
const char *application_name = argv[1];
if (aos::starter::SendCommandBlocking(command, application_name, config,
- std::chrono::seconds(3))) {
+ chrono::seconds(3))) {
switch (command) {
case aos::starter::Command::START:
std::cout << "Successfully started " << application_name << '\n';
diff --git a/aos/starter/starter_rpc_lib.cc b/aos/starter/starter_rpc_lib.cc
index 89fc2c2..20f6f5a 100644
--- a/aos/starter/starter_rpc_lib.cc
+++ b/aos/starter/starter_rpc_lib.cc
@@ -127,18 +127,15 @@
aos::starter::ApplicationStatus>::Empty();
}
-const aos::FlatbufferVector<aos::starter::Status> GetStarterStatus(
+std::optional<const aos::FlatbufferVector<aos::starter::Status>> GetStarterStatus(
const aos::Configuration *config) {
ShmEventLoop event_loop(config);
event_loop.SkipAosLog();
auto status_fetcher = event_loop.MakeFetcher<aos::starter::Status>("/aos");
status_fetcher.Fetch();
- if (status_fetcher) {
- return status_fetcher.CopyFlatBuffer();
- } else {
- return FlatbufferVector<aos::starter::Status>::Empty();
- }
+ return (status_fetcher ? std::make_optional(status_fetcher.CopyFlatBuffer()) :
+ std::nullopt);
}
} // namespace starter
diff --git a/aos/starter/starter_rpc_lib.h b/aos/starter/starter_rpc_lib.h
index 152016a..24c757e 100644
--- a/aos/starter/starter_rpc_lib.h
+++ b/aos/starter/starter_rpc_lib.h
@@ -2,6 +2,7 @@
#define AOS_STARTER_STARTER_RPC_LIB_H_
#include <chrono>
+#include <optional>
#include "aos/configuration.h"
#include "aos/starter/starter_generated.h"
@@ -32,7 +33,7 @@
// Fetches the entire status message of starter. Creates a temporary event loop
// from the provided config for fetching.
-const aos::FlatbufferVector<aos::starter::Status> GetStarterStatus(
+std::optional<const aos::FlatbufferVector<aos::starter::Status>> GetStarterStatus(
const aos::Configuration *config);
} // namespace starter