still unstupidying log interval stuff...
diff --git a/aos/common/control_loop/ControlLoop-tmpl.h b/aos/common/control_loop/ControlLoop-tmpl.h
index 46178f1..e96ae66 100644
--- a/aos/common/control_loop/ControlLoop-tmpl.h
+++ b/aos/common/control_loop/ControlLoop-tmpl.h
@@ -26,12 +26,12 @@
 
 template <class T, bool has_position, bool fail_no_position>
 void ControlLoop<T, has_position, fail_no_position>::Iterate() {
-  LOG_INTERVAL(no_prior_goal_);
-  LOG_INTERVAL(no_sensor_generation_);
-  LOG_INTERVAL(very_stale_position_);
-  LOG_INTERVAL(no_prior_position_);
-  LOG_INTERVAL(driver_station_old_);
-  LOG_INTERVAL(no_driver_station_);
+  no_prior_goal_.Print();
+  no_sensor_generation_.Print();
+  very_stale_position_.Print();
+  no_prior_position_.Print();
+  driver_station_old_.Print();
+  no_driver_station_.Print();
 
   // Fetch the latest control loop goal and position.  If there is no new
   // goal, we will just reuse the old one.
@@ -42,14 +42,14 @@
   // goals.
   const GoalType *goal = control_loop_->goal.get();
   if (goal == NULL) {
-    no_prior_goal_.WantToLog();
+    LOG_INTERVAL(no_prior_goal_);
     ZeroOutputs();
     return;
   }
 
   ::bbb::sensor_generation.FetchLatest();
   if (::bbb::sensor_generation.get() == nullptr) {
-    no_sensor_generation_.WantToLog();
+    LOG_INTERVAL(no_sensor_generation_);
     ZeroOutputs();
     return;
   }
@@ -82,7 +82,7 @@
       if (control_loop_->position.get() && !reset_) {
         int msec_age = control_loop_->position.Age().ToMSec();
         if (!control_loop_->position.IsNewerThanMS(kPositionTimeoutMs)) {
-          very_stale_position_.WantToLog();
+          LOG_INTERVAL(very_stale_position_);
           ZeroOutputs();
           return;
         } else {
@@ -90,7 +90,7 @@
               kPositionTimeoutMs);
         }
       } else {
-        no_prior_position_.WantToLog();
+        LOG_INTERVAL(no_prior_position_);
         if (fail_no_position) {
           ZeroOutputs();
           return;
@@ -111,9 +111,9 @@
     outputs_enabled = true;
   } else {
     if (::aos::robot_state.get()) {
-      driver_station_old_.WantToLog();
+      LOG_INTERVAL(driver_station_old_);
     } else {
-      no_driver_station_.WantToLog();
+      LOG_INTERVAL(no_driver_station_);
     }
   }
 
diff --git a/aos/common/util/log_interval.h b/aos/common/util/log_interval.h
index 71d37ac..7c8a329 100644
--- a/aos/common/util/log_interval.h
+++ b/aos/common/util/log_interval.h
@@ -55,23 +55,28 @@
 };
 
 // This one is even easier to use. It always logs with a message "%s %d
-// times\n". Call WantToLog() like with LogInterval and insert a LOG_INTERVAL
-// call somewhere that will always get run (ie not after a conditional return).
+// times\n". Call LOG_INTERVAL wherever it should log and make sure Print gets
+// called often (ie not after a conditional return)
 class SimpleLogInterval {
  public:
   SimpleLogInterval(const ::aos::time::Time &interval, log_level level,
                     const ::std::string &message)
       : interval_(interval), level_(level), message_(message) {}
 
-  void WantToLog() { interval_.WantToLog(); }
-
 #define LOG_INTERVAL(simple_log) \
-  simple_log.Print(LOG_SOURCENAME ": " STRINGIFY(__LINE__))
-  void Print(const char *context) {
+  simple_log.WantToLog(LOG_SOURCENAME ": " STRINGIFY(__LINE__))
+  void WantToLog(const char *context) {
+    context_ = context;
+    interval_.WantToLog();
+  }
+
+  void Print() {
     if (interval_.ShouldLog()) {
-      log_do(level_, "%s: %.*s %d times over %f sec\n", context,
+      CHECK_NOTNULL(context_);
+      log_do(level_, "%s: %.*s %d times over %f sec\n", context_,
              static_cast<int>(message_.size()), message_.data(),
              interval_.Count(), interval_.interval().ToSeconds());
+      context_ = NULL;
     }
   }
 
@@ -79,6 +84,7 @@
   LogInterval interval_;
   const log_level level_;
   const ::std::string message_;
+  const char *context_ = NULL;
 };
 
 }  // namespace util
diff --git a/bbb_cape/src/bbb/packet_finder.cc b/bbb_cape/src/bbb/packet_finder.cc
index a73f8ab..15a8e62 100644
--- a/bbb_cape/src/bbb/packet_finder.cc
+++ b/bbb_cape/src/bbb/packet_finder.cc
@@ -110,12 +110,12 @@
   uint32_t unstuffed = cows_unstuff(
       reinterpret_cast<uint32_t *>(buf_), packet_size_,
       reinterpret_cast<uint32_t *>(unstuffed_data_), packet_size_ - 4);
-  LOG_INTERVAL(invalid_packet_);
-  LOG_INTERVAL(bad_checksum_);
+  invalid_packet_.Print();
+  bad_checksum_.Print();
 
   if (unstuffed == 0) {
     if (kDebugLogs) LOG(INFO, "invalid\n");
-    invalid_packet_.WantToLog();
+    LOG_INTERVAL(invalid_packet_);
     return false;
   } else if (unstuffed != (packet_size_ - 4) / 4) {
     LOG(WARNING, "packet is %" PRIu32 " words instead of %zu\n",
@@ -133,7 +133,7 @@
       LOG(INFO, "sent %" PRIx32 " not %" PRIx32 "\n", sent_checksum,
           calculated_checksum);
     }
-    bad_checksum_.WantToLog();
+    LOG_INTERVAL(bad_checksum_);
     return false;
   }
 
diff --git a/bbb_cape/src/bbb/sensor_reader.cc b/bbb_cape/src/bbb/sensor_reader.cc
index dbe200e..c0e9604 100644
--- a/bbb_cape/src/bbb/sensor_reader.cc
+++ b/bbb_cape/src/bbb/sensor_reader.cc
@@ -42,7 +42,7 @@
       ::aos::time::Time::InSeconds(5);
 
   while (true) {
-    LOG_INTERVAL(receive_failed_);
+    receive_failed_.Print();
 
     ::aos::time::Time next_timeout = last_received_time_ + kResetTimeout;
     if (next_timeout <= ::aos::time::Time::Now()) {
@@ -69,7 +69,7 @@
       last_cape_timestamp_ = data->timestamp;
       return data;
     }
-    receive_failed_.WantToLog();
+    LOG_INTERVAL(receive_failed_);
   }
 }
 
diff --git a/frc971/control_loops/drivetrain/drivetrain.cc b/frc971/control_loops/drivetrain/drivetrain.cc
index 7edeea7..b73c163 100644
--- a/frc971/control_loops/drivetrain/drivetrain.cc
+++ b/frc971/control_loops/drivetrain/drivetrain.cc
@@ -588,10 +588,10 @@
 
   bool bad_pos = false;
   if (position == nullptr) {
-    no_position_.WantToLog();
+    LOG_INTERVAL(no_position_);
     bad_pos = true;
   }
-  LOG_INTERVAL(no_position_);
+  no_position_.Print();
 
   double wheel = goal->steering;
   double throttle = goal->throttle;
diff --git a/frc971/output/motor_writer.cc b/frc971/output/motor_writer.cc
index 864e200..54ff7d9 100644
--- a/frc971/output/motor_writer.cc
+++ b/frc971/output/motor_writer.cc
@@ -43,9 +43,9 @@
       } else {
         DisablePWMOutput(3);
         DisablePWMOutput(8);
-        drivetrain_old_.WantToLog();
+        LOG_INTERVAL(drivetrain_old_);
       }
-      LOG_INTERVAL(drivetrain_old_);
+      drivetrain_old_.Print();
     }
 
     {
@@ -60,9 +60,9 @@
       } else {
         DisablePWMOutput(9);
         SetSolenoid(5, false);  // engage the brake
-        shooter_old_.WantToLog();
+        LOG_INTERVAL(shooter_old_);
       }
-      LOG_INTERVAL(shooter_old_);
+      shooter_old_.Print();
     }
 
     {
@@ -83,9 +83,9 @@
         DisablePWMOutput(2);
         DisablePWMOutput(4);
         DisablePWMOutput(5);
-        claw_old_.WantToLog();
+        LOG_INTERVAL(claw_old_);
       }
-      LOG_INTERVAL(claw_old_);
+      claw_old_.Print();
     }
   }