blob: 01ceaf415f58e7ca3b2e6eb5589c1439460ea0ea [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
Jim Ostrowskicc3d5942024-06-29 18:05:54 -070078 LOG(INFO) << "Starting image_logger; will wait on joystick enabled to start "
79 "logging";
Niko Sohmers3860f8a2024-01-12 21:05:19 -080080 event_loop.OnRun([]() {
81 errno = 0;
82 setpriority(PRIO_PROCESS, 0, -20);
83 PCHECK(errno == 0) << ": Renicing to -20 failed.";
84 });
85
86 event_loop.MakeWatcher(
87 "/imu/aos", [&](const aos::JoystickState &joystick_state) {
88 const auto timestamp = event_loop.context().monotonic_event_time;
Austin Schuh19731b02024-03-02 16:53:19 -080089 filesystem_status.Fetch();
90
Niko Sohmers3860f8a2024-01-12 21:05:19 -080091 // Store the last time we got disabled
92 if (enabled && !joystick_state.enabled()) {
93 last_disable_time = timestamp;
94 }
95 enabled = joystick_state.enabled();
96
Austin Schuh19731b02024-03-02 16:53:19 -080097 bool enough_space = true;
98
99 if (filesystem_status.get() != nullptr) {
100 enough_space = false;
101 for (const aos::util::Filesystem *fs :
102 *filesystem_status->filesystems()) {
103 CHECK(fs->has_path());
104 if (fs->path()->string_view() == "/") {
105 if (fs->free_space() > 50ull * 1024ull * 1024ull * 1024ull) {
106 enough_space = true;
107 }
108 }
109 }
110 }
111
112 const bool should_be_logging =
113 (enabled ||
Austin Schuh99f7c6a2024-06-25 22:07:44 -0700114 timestamp <
115 last_disable_time + std::chrono::duration<double>(
116 absl::GetFlag(FLAGS_disabled_time))) &&
Austin Schuh19731b02024-03-02 16:53:19 -0800117 enough_space;
118
119 if (!logging && should_be_logging) {
Niko Sohmers3860f8a2024-01-12 21:05:19 -0800120 auto log_namer = MakeLogNamer(&event_loop);
121 if (log_namer == nullptr) {
122 return;
123 }
124
125 // Start logging if we just got enabled
126 LOG(INFO) << "Starting logging";
127 logger.StartLogging(std::move(log_namer));
128 logging = true;
129 last_rotation_time = event_loop.monotonic_now();
Austin Schuh19731b02024-03-02 16:53:19 -0800130 } else if (logging && !should_be_logging) {
Niko Sohmers3860f8a2024-01-12 21:05:19 -0800131 // Stop logging if we've been disabled for a non-negligible amount of
132 // time
133 LOG(INFO) << "Stopping logging";
134 logger.StopLogging(event_loop.monotonic_now());
135 logging = false;
136 }
137 });
138
139 event_loop.Run();
140
141 LOG(INFO) << "Shutting down";
142
143 return 0;
144}