sensor-mon: Check for threshold alarms on startup
Add the functionality to the ThresholdAlarmLogger class to check for any
active alarms on startup and make a createEventLog() call for them.
It also keeps track of the alarm values so that the propertiesChanged
handler can know if an alarm changed state or is just new.
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I0dec7fc7c42d5007c1466700470faefbf6976dff
diff --git a/sensor-monitor/threshold_alarm_logger.cpp b/sensor-monitor/threshold_alarm_logger.cpp
index 0a057dc..137e7dc 100644
--- a/sensor-monitor/threshold_alarm_logger.cpp
+++ b/sensor-monitor/threshold_alarm_logger.cpp
@@ -15,9 +15,20 @@
*/
#include "threshold_alarm_logger.hpp"
+#include "sdbusplus.hpp"
+
+#include <fmt/format.h>
+
+#include <phosphor-logging/log.hpp>
+#include <xyz/openbmc_project/Logging/Entry/server.hpp>
+
namespace sensor::monitor
{
+using namespace sdbusplus::xyz::openbmc_project::Logging::server;
+using namespace phosphor::logging;
+using namespace phosphor::fan::util;
+
const std::string warningInterface =
"xyz.openbmc_project.Sensor.Threshold.Warning";
const std::string criticalInterface =
@@ -25,6 +36,44 @@
const std::string perfLossInterface =
"xyz.openbmc_project.Sensor.Threshold.PerformanceLoss";
+using ErrorData = std::tuple<ErrorName, Entry::Level>;
+
+/**
+ * Map of threshold interfaces and alarm properties and values to error data.
+ */
+const std::map<InterfaceName, std::map<PropertyName, std::map<bool, ErrorData>>>
+ thresholdData{
+
+ {warningInterface,
+ {{"WarningAlarmHigh",
+ {{true, ErrorData{"WarningHigh", Entry::Level::Warning}},
+ {false,
+ ErrorData{"WarningHighClear", Entry::Level::Informational}}}},
+ {"WarningAlarmLow",
+ {{true, ErrorData{"WarningLow", Entry::Level::Warning}},
+ {false,
+ ErrorData{"WarningLowClear", Entry::Level::Informational}}}}}},
+
+ {criticalInterface,
+ {{"CriticalAlarmHigh",
+ {{true, ErrorData{"CriticalHigh", Entry::Level::Critical}},
+ {false,
+ ErrorData{"CriticalHighClear", Entry::Level::Informational}}}},
+ {"CriticalAlarmLow",
+ {{true, ErrorData{"CriticalLow", Entry::Level::Critical}},
+ {false,
+ ErrorData{"CriticalLowClear", Entry::Level::Informational}}}}}},
+
+ {perfLossInterface,
+ {{"PerfLossAlarmHigh",
+ {{true, ErrorData{"PerfLossHigh", Entry::Level::Warning}},
+ {false,
+ ErrorData{"PerfLossHighClear", Entry::Level::Informational}}}},
+ {"PerfLossAlarmLow",
+ {{true, ErrorData{"PerfLossLow", Entry::Level::Warning}},
+ {false,
+ ErrorData{"PerfLossLowClear", Entry::Level::Informational}}}}}}};
+
ThresholdAlarmLogger::ThresholdAlarmLogger(sdbusplus::bus::bus& bus,
sdeventplus::Event& event) :
bus(bus),
@@ -50,11 +99,71 @@
perfLossInterface + "'",
std::bind(&ThresholdAlarmLogger::propertiesChanged, this,
std::placeholders::_1))
-{}
+{
+ // check for any currently asserted threshold alarms
+ std::for_each(
+ thresholdData.begin(), thresholdData.end(),
+ [this](const auto& thresholdInterface) {
+ const auto& interface = thresholdInterface.first;
+ auto objects =
+ SDBusPlus::getSubTreeRaw(this->bus, "/", interface, 0);
+ std::for_each(objects.begin(), objects.end(),
+ [interface, this](const auto& object) {
+ const auto& path = object.first;
+ const auto& service =
+ object.second.begin()->first;
+ checkThresholds(interface, path, service);
+ });
+ });
+}
void ThresholdAlarmLogger::propertiesChanged(sdbusplus::message::message& msg)
{
// TODO
}
+void ThresholdAlarmLogger::checkThresholds(const std::string& interface,
+ const std::string& sensorPath,
+ const std::string& service)
+{
+ auto properties = thresholdData.find(interface);
+ if (properties == thresholdData.end())
+ {
+ return;
+ }
+
+ for (const auto& [property, unused] : properties->second)
+ {
+ try
+ {
+ auto alarmValue = SDBusPlus::getProperty<bool>(
+ bus, service, sensorPath, interface, property);
+ alarms[InterfaceKey(sensorPath, interface)][property] = alarmValue;
+
+ // This is just for checking alarms on startup,
+ // so only look for active alarms.
+ if (alarmValue)
+ {
+ createEventLog(sensorPath, interface, property, alarmValue);
+ }
+ }
+ catch (const DBusError& e)
+ {
+ log<level::ERR>(
+ fmt::format("Failed reading sensor threshold properties: {}",
+ e.what())
+ .c_str());
+ continue;
+ }
+ }
+}
+
+void ThresholdAlarmLogger::createEventLog(const std::string& sensorPath,
+ const std::string& interface,
+ const std::string& alarmProperty,
+ bool alarmValue)
+{
+ // TODO
+}
+
} // namespace sensor::monitor
diff --git a/sensor-monitor/threshold_alarm_logger.hpp b/sensor-monitor/threshold_alarm_logger.hpp
index 89e460d..c95f396 100644
--- a/sensor-monitor/threshold_alarm_logger.hpp
+++ b/sensor-monitor/threshold_alarm_logger.hpp
@@ -22,6 +22,12 @@
namespace sensor::monitor
{
+using InterfaceName = std::string;
+using PropertyName = std::string;
+using ErrorName = std::string;
+using ObjectPath = std::string;
+using InterfaceKey = std::tuple<ObjectPath, InterfaceName>;
+
/**
* @class ThresholdAlarmLogger
*
@@ -69,6 +75,30 @@
void propertiesChanged(sdbusplus::message::message& msg);
/**
+ * @brief Checks for active alarms on the path and threshold interface
+ * passed in and creates event logs if necessary.
+ *
+ * @param[in] interface - The threshold interface
+ * @param[in] sensorPath - The sensor D-Bus path
+ * @param[in] service - The D-Bus service that owns the interface
+ */
+ void checkThresholds(const std::string& interface,
+ const std::string& sensorPath,
+ const std::string& service);
+
+ /**
+ * @brief Creates an event log for the alarm set/clear
+ *
+ * @param[in] sensorPath - The sensor object path
+ * @param[in] interface - The threshold interface
+ * @param[in] alarmProperty - The alarm property name
+ * @param[in] alarmValue - The alarm value
+ */
+ void createEventLog(const std::string& sensorPath,
+ const std::string& interface,
+ const std::string& alarmProperty, bool alarmValue);
+
+ /**
* @brief The sdbusplus bus object
*/
sdbusplus::bus::bus& bus;
@@ -92,6 +122,11 @@
* @brief The PerformanceLoss interface match object
*/
sdbusplus::bus::match::match perfLossMatch;
+
+ /**
+ * @brief The current alarm values
+ */
+ std::map<InterfaceKey, std::map<PropertyName, bool>> alarms;
};
} // namespace sensor::monitor