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