blob: 2984824c2673ba5ed7e6dc14d6ed80d4f3e19b1e [file] [log] [blame]
Niko Sohmers3860f8a2024-01-12 21:05:19 -08001#include <sys/resource.h>
2#include <sys/time.h>
3
4#include "gflags/gflags.h"
5#include "glog/logging.h"
6
7#include "aos/configuration.h"
8#include "aos/events/logging/log_writer.h"
9#include "aos/events/shm_event_loop.h"
10#include "aos/init.h"
11#include "aos/logging/log_namer.h"
Austin Schuh19731b02024-03-02 16:53:19 -080012#include "aos/util/filesystem_generated.h"
Niko Sohmers3860f8a2024-01-12 21:05:19 -080013#include "frc971/input/joystick_state_generated.h"
14
15DEFINE_string(config, "aos_config.json", "Config file to use.");
16
17DEFINE_double(rotate_every, 0.0,
18 "If set, rotate the logger after this many seconds");
19DECLARE_int32(flush_size);
20DEFINE_double(disabled_time, 5.0,
21 "Continue logging if disabled for this amount of time or less");
22DEFINE_bool(direct, false,
23 "If true, write using O_DIRECT and write 512 byte aligned blocks "
24 "whenever possible.");
25
26std::unique_ptr<aos::logger::MultiNodeFilesLogNamer> MakeLogNamer(
27 aos::EventLoop *event_loop) {
28 std::optional<std::string> log_name =
James Kuszmaulecafe1f2024-02-27 20:29:53 -080029 aos::logging::MaybeGetLogName("image_log");
Niko Sohmers3860f8a2024-01-12 21:05:19 -080030
31 if (!log_name.has_value()) {
32 return nullptr;
33 }
34
35 return std::make_unique<aos::logger::MultiNodeFilesLogNamer>(
36 event_loop, std::make_unique<aos::logger::RenamableFileBackend>(
37 absl::StrCat(log_name.value(), "/"), FLAGS_direct));
38}
39
40int main(int argc, char *argv[]) {
41 gflags::SetUsageMessage(
42 "This program provides a simple logger binary that logs all SHMEM data "
43 "directly to a file specified at the command line when the robot is "
44 "enabled and for a bit of time after.");
45 aos::InitGoogle(&argc, &argv);
46
47 aos::FlatbufferDetachedBuffer<aos::Configuration> config =
48 aos::configuration::ReadConfig(FLAGS_config);
49
50 aos::ShmEventLoop event_loop(&config.message());
51
Austin Schuh19731b02024-03-02 16:53:19 -080052 aos::Fetcher<aos::util::FilesystemStatus> filesystem_status =
53 event_loop.MakeFetcher<aos::util::FilesystemStatus>("/aos");
54
Niko Sohmers3860f8a2024-01-12 21:05:19 -080055 bool logging = false;
56 bool enabled = false;
57 aos::monotonic_clock::time_point last_disable_time =
Austin Schuh19731b02024-03-02 16:53:19 -080058 aos::monotonic_clock::min_time;
Niko Sohmers3860f8a2024-01-12 21:05:19 -080059 aos::monotonic_clock::time_point last_rotation_time =
60 event_loop.monotonic_now();
61 aos::logger::Logger logger(&event_loop);
62
63 if (FLAGS_rotate_every != 0.0) {
64 logger.set_on_logged_period([&](aos::monotonic_clock::time_point) {
65 const auto now = event_loop.monotonic_now();
66 if (logging && now > last_rotation_time + std::chrono::duration<double>(
67 FLAGS_rotate_every)) {
68 logger.Rotate();
69 last_rotation_time = now;
70 }
71 });
72 }
73
74 event_loop.OnRun([]() {
75 errno = 0;
76 setpriority(PRIO_PROCESS, 0, -20);
77 PCHECK(errno == 0) << ": Renicing to -20 failed.";
78 });
79
80 event_loop.MakeWatcher(
81 "/imu/aos", [&](const aos::JoystickState &joystick_state) {
82 const auto timestamp = event_loop.context().monotonic_event_time;
Austin Schuh19731b02024-03-02 16:53:19 -080083 filesystem_status.Fetch();
84
Niko Sohmers3860f8a2024-01-12 21:05:19 -080085 // Store the last time we got disabled
86 if (enabled && !joystick_state.enabled()) {
87 last_disable_time = timestamp;
88 }
89 enabled = joystick_state.enabled();
90
Austin Schuh19731b02024-03-02 16:53:19 -080091 bool enough_space = true;
92
93 if (filesystem_status.get() != nullptr) {
94 enough_space = false;
95 for (const aos::util::Filesystem *fs :
96 *filesystem_status->filesystems()) {
97 CHECK(fs->has_path());
98 if (fs->path()->string_view() == "/") {
99 if (fs->free_space() > 50ull * 1024ull * 1024ull * 1024ull) {
100 enough_space = true;
101 }
102 }
103 }
104 }
105
106 const bool should_be_logging =
107 (enabled ||
108 timestamp < last_disable_time + std::chrono::duration<double>(
109 FLAGS_disabled_time)) &&
110 enough_space;
111
112 if (!logging && should_be_logging) {
Niko Sohmers3860f8a2024-01-12 21:05:19 -0800113 auto log_namer = MakeLogNamer(&event_loop);
114 if (log_namer == nullptr) {
115 return;
116 }
117
118 // Start logging if we just got enabled
119 LOG(INFO) << "Starting logging";
120 logger.StartLogging(std::move(log_namer));
121 logging = true;
122 last_rotation_time = event_loop.monotonic_now();
Austin Schuh19731b02024-03-02 16:53:19 -0800123 } else if (logging && !should_be_logging) {
Niko Sohmers3860f8a2024-01-12 21:05:19 -0800124 // Stop logging if we've been disabled for a non-negligible amount of
125 // time
126 LOG(INFO) << "Stopping logging";
127 logger.StopLogging(event_loop.monotonic_now());
128 logging = false;
129 }
130 });
131
132 event_loop.Run();
133
134 LOG(INFO) << "Shutting down";
135
136 return 0;
137}