Add failsafe logger for zones

Tested:
...
Nov 23 21:40:06 tmddp10-nfd01.prod.google.com swampd[4893]:
Zone `0` is in failsafe mode.
With update at `fleeting0`: The sensor has bad readings.
Nov 23 21:40:06 tmddp10-nfd01.prod.google.com swampd[4893]:
Zone `1` is in failsafe mode.
With update at `fleeting1`: The sensor has bad readings.
Nov 23 21:40:06 tmddp10-nfd01.prod.google.com swampd[4893]:
Zone `1` leaves failsafe mode.
With update at `hotswap_in_Input_Power`: The sensor has recovered.
Nov 23 21:40:06 tmddp10-nfd01.prod.google.com swampd[4893]:
Zone `0` leaves failsafe mode.
With update at `hotswap_in_Input_Power`: The sensor has recovered.
...

Change-Id: I2c296addb7ad117c03c04a27de91204796cda036
Signed-off-by: James Zheng <alphetis@google.com>
diff --git a/pid/zone.cpp b/pid/zone.cpp
index 901905d..d9fe3c0 100644
--- a/pid/zone.cpp
+++ b/pid/zone.cpp
@@ -18,6 +18,7 @@
 #include "zone.hpp"
 
 #include "conf.hpp"
+#include "failsafeloggers/failsafe_logger_utility.hpp"
 #include "pid/controller.hpp"
 #include "pid/ec/pid.hpp"
 #include "pid/fancontroller.hpp"
@@ -101,6 +102,8 @@
     if (_missingAcceptable.find(name) != _missingAcceptable.end())
     {
         // Disallow sensors in MissingIsAcceptable list from causing failsafe
+        outputFailsafeLogWithZone(_zoneId, this->getFailSafeMode(), name,
+                                  "The sensor is missing but is acceptable.");
         return;
     }
 
@@ -558,6 +561,11 @@
     return _mgr.getSensor(name);
 }
 
+std::vector<std::string> DbusPidZone::getSensorNames(void)
+{
+    return _thermalInputs;
+}
+
 bool DbusPidZone::getRedundantWrite(void) const
 {
     return _redundantWrite;
diff --git a/pid/zone.hpp b/pid/zone.hpp
index 8c49f1f..14017b8 100644
--- a/pid/zone.hpp
+++ b/pid/zone.hpp
@@ -2,6 +2,7 @@
 
 #include "conf.hpp"
 #include "controller.hpp"
+#include "failsafeloggers/failsafe_logger_utility.hpp"
 #include "pidcontroller.hpp"
 #include "sensors/manager.hpp"
 #include "sensors/sensor.hpp"
@@ -88,6 +89,7 @@
     uint64_t getUpdateThermalsCycle(void) const override;
 
     Sensor* getSensor(const std::string& name) override;
+    std::vector<std::string> getSensorNames(void) override;
     void determineMaxSetPointRequest(void) override;
     void updateFanTelemetry(void) override;
     void updateSensors(void) override;
@@ -184,6 +186,9 @@
                 {
                     std::cerr << sensorInput << " sensor timeout\n";
                 }
+                outputFailsafeLogWithZone(_zoneId, this->getFailSafeMode(),
+                                          sensorInput,
+                                          "The sensor has timed out.");
             }
             else
             {
@@ -198,6 +203,9 @@
                     }
 
                     _failSafeSensors.erase(kt);
+                    outputFailsafeLogWithZone(_zoneId, this->getFailSafeMode(),
+                                              sensorInput,
+                                              "The sensor has recovered.");
                 }
             }
         }
diff --git a/pid/zone_interface.hpp b/pid/zone_interface.hpp
index 34a5352..33f0a6f 100644
--- a/pid/zone_interface.hpp
+++ b/pid/zone_interface.hpp
@@ -27,6 +27,9 @@
     /** Return a pointer to the sensor specified by name. */
     virtual Sensor* getSensor(const std::string& name) = 0;
 
+    /** Return the list of sensor names in the zone. */
+    virtual std::vector<std::string> getSensorNames(void) = 0;
+
     /* updateFanTelemetry() and updateSensors() both clear the failsafe state
      * for a sensor if it's no longer in that state.
      */