Add monotonic start and end time flags to log_cat

Useful when wanting to look at a certain time in a log, and is much
easier to use than giving the realtime timestamp (log_reader flag).

Signed-off-by: Milind Upadhyay <milind.upadhyay@gmail.com>
Change-Id: I39b8d79543eea82f6f31498595f5ee2869da03e3
diff --git a/aos/events/logging/log_cat.cc b/aos/events/logging/log_cat.cc
index 60ad0e2..2b6fe3e 100644
--- a/aos/events/logging/log_cat.cc
+++ b/aos/events/logging/log_cat.cc
@@ -46,6 +46,12 @@
             "If true, only print out the results of logfile sorting.");
 DEFINE_bool(channels, false,
             "If true, print out all the configured channels for this log.");
+DEFINE_double(monotonic_start_time, 0.0,
+              "If set, only print messages sent at or after this many seconds "
+              "after epoch.");
+DEFINE_double(monotonic_end_time, 0.0,
+              "If set, only print messages sent at or before this many seconds "
+              "after epoch.");
 
 using aos::monotonic_clock;
 namespace chrono = std::chrono;
@@ -272,6 +278,21 @@
     const flatbuffers::Vector<flatbuffers::Offset<aos::Channel>> *channels =
         event_loop_->configuration()->channels();
 
+    const monotonic_clock::time_point start_time =
+        (FLAGS_monotonic_start_time == 0.0
+             ? monotonic_clock::min_time
+             : monotonic_clock::time_point(
+                   std::chrono::duration_cast<monotonic_clock::duration>(
+                       std::chrono::duration<double>(
+                           FLAGS_monotonic_start_time))));
+    const monotonic_clock::time_point end_time =
+        (FLAGS_monotonic_end_time == 0.0
+             ? monotonic_clock::max_time
+             : monotonic_clock::time_point(
+                   std::chrono::duration_cast<monotonic_clock::duration>(
+                       std::chrono::duration<double>(
+                           FLAGS_monotonic_end_time))));
+
     for (flatbuffers::uoffset_t i = 0; i < channels->size(); i++) {
       const aos::Channel *channel = channels->Get(i);
       const flatbuffers::string_view name = channel->name()->string_view();
@@ -286,8 +307,9 @@
 
         CHECK_NOTNULL(channel->schema());
         event_loop_->MakeRawWatcher(
-            channel, [this, channel](const aos::Context &context,
-                                     const void * /*message*/) {
+            channel,
+            [this, channel, start_time, end_time](const aos::Context &context,
+                                                  const void * /*message*/) {
               if (!FLAGS_print) {
                 return;
               }
@@ -296,6 +318,11 @@
                 return;
               }
 
+              if (context.monotonic_event_time < start_time ||
+                  context.monotonic_event_time > end_time) {
+                return;
+              }
+
               PrintMessage(node_name_, channel, context, builder_);
               ++(*message_print_counter_);
               if (FLAGS_count > 0 && *message_print_counter_ >= FLAGS_count) {