blob: 45e25f6f819a0fe53e0ac55ba472debbfe46dabe [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"
12#include "frc971/input/joystick_state_generated.h"
13
14DEFINE_string(config, "aos_config.json", "Config file to use.");
15
16DEFINE_double(rotate_every, 0.0,
17 "If set, rotate the logger after this many seconds");
18DECLARE_int32(flush_size);
19DEFINE_double(disabled_time, 5.0,
20 "Continue logging if disabled for this amount of time or less");
21DEFINE_bool(direct, false,
22 "If true, write using O_DIRECT and write 512 byte aligned blocks "
23 "whenever possible.");
24
25std::unique_ptr<aos::logger::MultiNodeFilesLogNamer> MakeLogNamer(
26 aos::EventLoop *event_loop) {
27 std::optional<std::string> log_name =
28 aos::logging::MaybeGetLogName("fbs_log");
29
30 if (!log_name.has_value()) {
31 return nullptr;
32 }
33
34 return std::make_unique<aos::logger::MultiNodeFilesLogNamer>(
35 event_loop, std::make_unique<aos::logger::RenamableFileBackend>(
36 absl::StrCat(log_name.value(), "/"), FLAGS_direct));
37}
38
39int main(int argc, char *argv[]) {
40 gflags::SetUsageMessage(
41 "This program provides a simple logger binary that logs all SHMEM data "
42 "directly to a file specified at the command line when the robot is "
43 "enabled and for a bit of time after.");
44 aos::InitGoogle(&argc, &argv);
45
46 aos::FlatbufferDetachedBuffer<aos::Configuration> config =
47 aos::configuration::ReadConfig(FLAGS_config);
48
49 aos::ShmEventLoop event_loop(&config.message());
50
51 bool logging = false;
52 bool enabled = false;
53 aos::monotonic_clock::time_point last_disable_time =
54 event_loop.monotonic_now();
55 aos::monotonic_clock::time_point last_rotation_time =
56 event_loop.monotonic_now();
57 aos::logger::Logger logger(&event_loop);
58
59 if (FLAGS_rotate_every != 0.0) {
60 logger.set_on_logged_period([&](aos::monotonic_clock::time_point) {
61 const auto now = event_loop.monotonic_now();
62 if (logging && now > last_rotation_time + std::chrono::duration<double>(
63 FLAGS_rotate_every)) {
64 logger.Rotate();
65 last_rotation_time = now;
66 }
67 });
68 }
69
70 event_loop.OnRun([]() {
71 errno = 0;
72 setpriority(PRIO_PROCESS, 0, -20);
73 PCHECK(errno == 0) << ": Renicing to -20 failed.";
74 });
75
76 event_loop.MakeWatcher(
77 "/imu/aos", [&](const aos::JoystickState &joystick_state) {
78 const auto timestamp = event_loop.context().monotonic_event_time;
79 // Store the last time we got disabled
80 if (enabled && !joystick_state.enabled()) {
81 last_disable_time = timestamp;
82 }
83 enabled = joystick_state.enabled();
84
85 if (!logging && enabled) {
86 auto log_namer = MakeLogNamer(&event_loop);
87 if (log_namer == nullptr) {
88 return;
89 }
90
91 // Start logging if we just got enabled
92 LOG(INFO) << "Starting logging";
93 logger.StartLogging(std::move(log_namer));
94 logging = true;
95 last_rotation_time = event_loop.monotonic_now();
96 } else if (logging && !enabled &&
97 (timestamp - last_disable_time) >
98 std::chrono::duration<double>(FLAGS_disabled_time)) {
99 // Stop logging if we've been disabled for a non-negligible amount of
100 // time
101 LOG(INFO) << "Stopping logging";
102 logger.StopLogging(event_loop.monotonic_now());
103 logging = false;
104 }
105 });
106
107 event_loop.Run();
108
109 LOG(INFO) << "Shutting down";
110
111 return 0;
112}