blob: cb8fc4e3e99e5937273feab2ed72f15e52bb4bde [file] [log] [blame]
Niko Sohmers3860f8a2024-01-12 21:05:19 -08001#include <sys/resource.h>
2#include <sys/time.h>
3
Austin Schuh99f7c6a2024-06-25 22:07:44 -07004#include "absl/flags/flag.h"
5#include "absl/flags/usage.h"
6#include "absl/log/check.h"
7#include "absl/log/log.h"
Niko Sohmers3860f8a2024-01-12 21:05:19 -08008
9#include "aos/configuration.h"
10#include "aos/events/logging/log_writer.h"
11#include "aos/events/shm_event_loop.h"
12#include "aos/init.h"
13#include "aos/logging/log_namer.h"
Austin Schuh19731b02024-03-02 16:53:19 -080014#include "aos/util/filesystem_generated.h"
Niko Sohmers3860f8a2024-01-12 21:05:19 -080015#include "frc971/input/joystick_state_generated.h"
16
Austin Schuh99f7c6a2024-06-25 22:07:44 -070017ABSL_FLAG(std::string, config, "aos_config.json", "Config file to use.");
Niko Sohmers3860f8a2024-01-12 21:05:19 -080018
Austin Schuh99f7c6a2024-06-25 22:07:44 -070019ABSL_FLAG(double, rotate_every, 0.0,
20 "If set, rotate the logger after this many seconds");
21ABSL_DECLARE_FLAG(int32_t, flush_size);
22ABSL_FLAG(double, disabled_time, 5.0,
23 "Continue logging if disabled for this amount of time or less");
24ABSL_FLAG(bool, direct, false,
25 "If true, write using O_DIRECT and write 512 byte aligned blocks "
26 "whenever possible.");
Niko Sohmers3860f8a2024-01-12 21:05:19 -080027
28std::unique_ptr<aos::logger::MultiNodeFilesLogNamer> MakeLogNamer(
29 aos::EventLoop *event_loop) {
30 std::optional<std::string> log_name =
James Kuszmaulecafe1f2024-02-27 20:29:53 -080031 aos::logging::MaybeGetLogName("image_log");
Niko Sohmers3860f8a2024-01-12 21:05:19 -080032
33 if (!log_name.has_value()) {
34 return nullptr;
35 }
36
37 return std::make_unique<aos::logger::MultiNodeFilesLogNamer>(
Austin Schuh99f7c6a2024-06-25 22:07:44 -070038 event_loop,
39 std::make_unique<aos::logger::RenamableFileBackend>(
40 absl::StrCat(log_name.value(), "/"), absl::GetFlag(FLAGS_direct)));
Niko Sohmers3860f8a2024-01-12 21:05:19 -080041}
42
43int main(int argc, char *argv[]) {
Austin Schuh99f7c6a2024-06-25 22:07:44 -070044 absl::SetProgramUsageMessage(
Niko Sohmers3860f8a2024-01-12 21:05:19 -080045 "This program provides a simple logger binary that logs all SHMEM data "
46 "directly to a file specified at the command line when the robot is "
47 "enabled and for a bit of time after.");
48 aos::InitGoogle(&argc, &argv);
49
50 aos::FlatbufferDetachedBuffer<aos::Configuration> config =
Austin Schuh99f7c6a2024-06-25 22:07:44 -070051 aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));
Niko Sohmers3860f8a2024-01-12 21:05:19 -080052
53 aos::ShmEventLoop event_loop(&config.message());
54
Austin Schuh19731b02024-03-02 16:53:19 -080055 aos::Fetcher<aos::util::FilesystemStatus> filesystem_status =
56 event_loop.MakeFetcher<aos::util::FilesystemStatus>("/aos");
57
Niko Sohmers3860f8a2024-01-12 21:05:19 -080058 bool logging = false;
59 bool enabled = false;
60 aos::monotonic_clock::time_point last_disable_time =
Austin Schuh19731b02024-03-02 16:53:19 -080061 aos::monotonic_clock::min_time;
Niko Sohmers3860f8a2024-01-12 21:05:19 -080062 aos::monotonic_clock::time_point last_rotation_time =
63 event_loop.monotonic_now();
64 aos::logger::Logger logger(&event_loop);
65
Austin Schuh99f7c6a2024-06-25 22:07:44 -070066 if (absl::GetFlag(FLAGS_rotate_every) != 0.0) {
Niko Sohmers3860f8a2024-01-12 21:05:19 -080067 logger.set_on_logged_period([&](aos::monotonic_clock::time_point) {
68 const auto now = event_loop.monotonic_now();
Austin Schuh99f7c6a2024-06-25 22:07:44 -070069 if (logging &&
70 now > last_rotation_time + std::chrono::duration<double>(
71 absl::GetFlag(FLAGS_rotate_every))) {
Niko Sohmers3860f8a2024-01-12 21:05:19 -080072 logger.Rotate();
73 last_rotation_time = now;
74 }
75 });
76 }
77
78 event_loop.OnRun([]() {
79 errno = 0;
80 setpriority(PRIO_PROCESS, 0, -20);
81 PCHECK(errno == 0) << ": Renicing to -20 failed.";
82 });
83
84 event_loop.MakeWatcher(
85 "/imu/aos", [&](const aos::JoystickState &joystick_state) {
86 const auto timestamp = event_loop.context().monotonic_event_time;
Austin Schuh19731b02024-03-02 16:53:19 -080087 filesystem_status.Fetch();
88
Niko Sohmers3860f8a2024-01-12 21:05:19 -080089 // Store the last time we got disabled
90 if (enabled && !joystick_state.enabled()) {
91 last_disable_time = timestamp;
92 }
93 enabled = joystick_state.enabled();
94
Austin Schuh19731b02024-03-02 16:53:19 -080095 bool enough_space = true;
96
97 if (filesystem_status.get() != nullptr) {
98 enough_space = false;
99 for (const aos::util::Filesystem *fs :
100 *filesystem_status->filesystems()) {
101 CHECK(fs->has_path());
102 if (fs->path()->string_view() == "/") {
103 if (fs->free_space() > 50ull * 1024ull * 1024ull * 1024ull) {
104 enough_space = true;
105 }
106 }
107 }
108 }
109
110 const bool should_be_logging =
111 (enabled ||
Austin Schuh99f7c6a2024-06-25 22:07:44 -0700112 timestamp <
113 last_disable_time + std::chrono::duration<double>(
114 absl::GetFlag(FLAGS_disabled_time))) &&
Austin Schuh19731b02024-03-02 16:53:19 -0800115 enough_space;
116
117 if (!logging && should_be_logging) {
Niko Sohmers3860f8a2024-01-12 21:05:19 -0800118 auto log_namer = MakeLogNamer(&event_loop);
119 if (log_namer == nullptr) {
120 return;
121 }
122
123 // Start logging if we just got enabled
124 LOG(INFO) << "Starting logging";
125 logger.StartLogging(std::move(log_namer));
126 logging = true;
127 last_rotation_time = event_loop.monotonic_now();
Austin Schuh19731b02024-03-02 16:53:19 -0800128 } else if (logging && !should_be_logging) {
Niko Sohmers3860f8a2024-01-12 21:05:19 -0800129 // Stop logging if we've been disabled for a non-negligible amount of
130 // time
131 LOG(INFO) << "Stopping logging";
132 logger.StopLogging(event_loop.monotonic_now());
133 logging = false;
134 }
135 });
136
137 event_loop.Run();
138
139 LOG(INFO) << "Shutting down";
140
141 return 0;
142}