blob: 01ceaf415f58e7ca3b2e6eb5589c1439460ea0ea [file] [log] [blame]
#include <sys/resource.h>
#include <sys/time.h>
#include "absl/flags/flag.h"
#include "absl/flags/usage.h"
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "aos/configuration.h"
#include "aos/events/logging/log_writer.h"
#include "aos/events/shm_event_loop.h"
#include "aos/init.h"
#include "aos/logging/log_namer.h"
#include "aos/util/filesystem_generated.h"
#include "frc971/input/joystick_state_generated.h"
ABSL_FLAG(std::string, config, "aos_config.json", "Config file to use.");
ABSL_FLAG(double, rotate_every, 0.0,
"If set, rotate the logger after this many seconds");
ABSL_DECLARE_FLAG(int32_t, flush_size);
ABSL_FLAG(double, disabled_time, 5.0,
"Continue logging if disabled for this amount of time or less");
ABSL_FLAG(bool, direct, false,
"If true, write using O_DIRECT and write 512 byte aligned blocks "
"whenever possible.");
std::unique_ptr<aos::logger::MultiNodeFilesLogNamer> MakeLogNamer(
aos::EventLoop *event_loop) {
std::optional<std::string> log_name =
aos::logging::MaybeGetLogName("image_log");
if (!log_name.has_value()) {
return nullptr;
}
return std::make_unique<aos::logger::MultiNodeFilesLogNamer>(
event_loop,
std::make_unique<aos::logger::RenamableFileBackend>(
absl::StrCat(log_name.value(), "/"), absl::GetFlag(FLAGS_direct)));
}
int main(int argc, char *argv[]) {
absl::SetProgramUsageMessage(
"This program provides a simple logger binary that logs all SHMEM data "
"directly to a file specified at the command line when the robot is "
"enabled and for a bit of time after.");
aos::InitGoogle(&argc, &argv);
aos::FlatbufferDetachedBuffer<aos::Configuration> config =
aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
aos::ShmEventLoop event_loop(&config.message());
aos::Fetcher<aos::util::FilesystemStatus> filesystem_status =
event_loop.MakeFetcher<aos::util::FilesystemStatus>("/aos");
bool logging = false;
bool enabled = false;
aos::monotonic_clock::time_point last_disable_time =
aos::monotonic_clock::min_time;
aos::monotonic_clock::time_point last_rotation_time =
event_loop.monotonic_now();
aos::logger::Logger logger(&event_loop);
if (absl::GetFlag(FLAGS_rotate_every) != 0.0) {
logger.set_on_logged_period([&](aos::monotonic_clock::time_point) {
const auto now = event_loop.monotonic_now();
if (logging &&
now > last_rotation_time + std::chrono::duration<double>(
absl::GetFlag(FLAGS_rotate_every))) {
logger.Rotate();
last_rotation_time = now;
}
});
}
LOG(INFO) << "Starting image_logger; will wait on joystick enabled to start "
"logging";
event_loop.OnRun([]() {
errno = 0;
setpriority(PRIO_PROCESS, 0, -20);
PCHECK(errno == 0) << ": Renicing to -20 failed.";
});
event_loop.MakeWatcher(
"/imu/aos", [&](const aos::JoystickState &joystick_state) {
const auto timestamp = event_loop.context().monotonic_event_time;
filesystem_status.Fetch();
// Store the last time we got disabled
if (enabled && !joystick_state.enabled()) {
last_disable_time = timestamp;
}
enabled = joystick_state.enabled();
bool enough_space = true;
if (filesystem_status.get() != nullptr) {
enough_space = false;
for (const aos::util::Filesystem *fs :
*filesystem_status->filesystems()) {
CHECK(fs->has_path());
if (fs->path()->string_view() == "/") {
if (fs->free_space() > 50ull * 1024ull * 1024ull * 1024ull) {
enough_space = true;
}
}
}
}
const bool should_be_logging =
(enabled ||
timestamp <
last_disable_time + std::chrono::duration<double>(
absl::GetFlag(FLAGS_disabled_time))) &&
enough_space;
if (!logging && should_be_logging) {
auto log_namer = MakeLogNamer(&event_loop);
if (log_namer == nullptr) {
return;
}
// Start logging if we just got enabled
LOG(INFO) << "Starting logging";
logger.StartLogging(std::move(log_namer));
logging = true;
last_rotation_time = event_loop.monotonic_now();
} else if (logging && !should_be_logging) {
// Stop logging if we've been disabled for a non-negligible amount of
// time
LOG(INFO) << "Stopping logging";
logger.StopLogging(event_loop.monotonic_now());
logging = false;
}
});
event_loop.Run();
LOG(INFO) << "Shutting down";
return 0;
}