match thresholdAsserted signal for threshold event monitor
thresholdAsserted signal includes the sensor reading that caused
threshold property change. This removes the need to read the
sensor value at the time of logging, which may miss the bad reading
when the log is delayed.
Tested:
Build and send the following command
busctl set-property xyz.openbmc_project.ADCSensor
/xyz/openbmc_project/sensors/voltage/P1V8_PCH
xyz.openbmc_project.Sensor.Value Value d 1.97
observed the following event logged
P1V8_PCH sensor crossed a critical high threshold going high. Reading=1.970000 Threshold=1.961000.
Signed-off-by: Zhikui Ren <zhikui.ren@intel.com>
Change-Id: Ie8831a9ba48188e1dd343db22583485c02f35dbc
diff --git a/include/sel_logger.hpp b/include/sel_logger.hpp
index 58c7cc6..35f8b95 100644
--- a/include/sel_logger.hpp
+++ b/include/sel_logger.hpp
@@ -32,6 +32,7 @@
std::numeric_limits<uint16_t>::max();
static constexpr size_t selEvtDataMaxSize = 3;
static constexpr size_t selOemDataMaxSize = 13;
+static constexpr uint8_t selEvtDataUnspecified = 0xFF;
static const std::filesystem::path selLogDir = "/var/log";
static const std::string selLogFilename = "ipmi_sel";
diff --git a/include/threshold_event_monitor.hpp b/include/threshold_event_monitor.hpp
index da63e0d..f1df9bd 100644
--- a/include/threshold_event_monitor.hpp
+++ b/include/threshold_event_monitor.hpp
@@ -34,31 +34,35 @@
static const std::string openBMCMessageRegistryVersion("0.1");
-inline static sdbusplus::bus::match::match startThresholdEventMonitor(
+inline static sdbusplus::bus::match::match startThresholdAssertMonitor(
std::shared_ptr<sdbusplus::asio::connection> conn)
{
- auto thresholdEventMatcherCallback = [conn](
- sdbusplus::message::message& msg) {
+ auto thresholdAssertMatcherCallback = [conn](sdbusplus::message::message&
+ msg) {
// This static set of std::pair<path, event> tracks asserted events to
// avoid duplicate logs or deasserts logged without an assert
static boost::container::flat_set<std::pair<std::string, std::string>>
assertedEvents;
- // SEL event data is three bytes where 0xFF means unspecified
- std::vector<uint8_t> eventData(selEvtDataMaxSize, 0xFF);
+ std::vector<uint8_t> eventData(selEvtDataMaxSize,
+ selEvtDataUnspecified);
// Get the event type and assertion details from the message
+ std::string sensorName;
std::string thresholdInterface;
- boost::container::flat_map<std::string, std::variant<bool>>
- propertiesChanged;
- msg.read(thresholdInterface, propertiesChanged);
- std::string event = propertiesChanged.begin()->first;
- bool* pval = std::get_if<bool>(&propertiesChanged.begin()->second);
- if (!pval)
+ std::string event;
+ bool assert;
+ double assertValue;
+ try
{
- std::cerr << "threshold event direction has invalid type\n";
+ msg.read(sensorName, thresholdInterface, event, assert,
+ assertValue);
+ }
+ catch (sdbusplus::exception_t&)
+ {
+ std::cerr << "error getting assert signal data from "
+ << msg.get_path() << "\n";
return;
}
- bool assert = *pval;
// Check the asserted events to determine if we should log this event
std::pair<std::string, std::string> pathAndEvent(
@@ -140,30 +144,15 @@
{
min = std::visit(ipmi::VariantToDoubleVisitor(), findMin->second);
}
- double sensorVal = 0;
- auto findVal = sensorValue.find("Value");
- if (findVal != sensorValue.end())
- {
- sensorVal =
- std::visit(ipmi::VariantToDoubleVisitor(), findVal->second);
- }
- double scale = 0;
- auto findScale = sensorValue.find("Scale");
- if (findScale != sensorValue.end())
- {
- scale =
- std::visit(ipmi::VariantToDoubleVisitor(), findScale->second);
- sensorVal *= std::pow(10, scale);
- }
try
{
- eventData[1] = ipmi::getScaledIPMIValue(sensorVal, max, min);
+ eventData[1] = ipmi::getScaledIPMIValue(assertValue, max, min);
}
catch (const std::exception& e)
{
std::cerr << e.what();
- eventData[1] = 0xFF;
+ eventData[1] = selEvtDataUnspecified;
}
// Get the threshold value to put in the event data
@@ -194,8 +183,13 @@
}
double thresholdVal =
std::visit(ipmi::VariantToDoubleVisitor(), thresholdValue);
+
+ double scale = 0;
+ auto findScale = sensorValue.find("Scale");
if (findScale != sensorValue.end())
{
+ scale =
+ std::visit(ipmi::VariantToDoubleVisitor(), findScale->second);
thresholdVal *= std::pow(10, scale);
}
try
@@ -205,14 +199,9 @@
catch (const std::exception& e)
{
std::cerr << e.what();
- eventData[2] = 0xFF;
+ eventData[2] = selEvtDataUnspecified;
}
- // Construct a human-readable message of this event for the log
- std::string_view sensorName(msg.get_path());
- sensorName.remove_prefix(
- std::min(sensorName.find_last_of("/") + 1, sensorName.size()));
-
std::string threshold;
std::string direction;
std::string redfishMessageID =
@@ -276,7 +265,7 @@
std::string journalMsg(std::string(sensorName) + " sensor crossed a " +
threshold + " threshold going " + direction +
- ". Reading=" + std::to_string(sensorVal) +
+ ". Reading=" + std::to_string(assertValue) +
" Threshold=" + std::to_string(thresholdVal) +
".");
@@ -284,13 +273,11 @@
journalMsg, std::string(msg.get_path()), eventData, assert,
selBMCGenID, "REDFISH_MESSAGE_ID=%s", redfishMessageID.c_str(),
"REDFISH_MESSAGE_ARGS=%.*s,%f,%f", sensorName.length(),
- sensorName.data(), sensorVal, thresholdVal);
+ sensorName.data(), assertValue, thresholdVal);
};
- sdbusplus::bus::match::match thresholdEventMatcher(
+ sdbusplus::bus::match::match thresholdAssertMatcher(
static_cast<sdbusplus::bus::bus&>(*conn),
- "type='signal',interface='org.freedesktop.DBus.Properties',member='"
- "PropertiesChanged',arg0namespace='xyz.openbmc_project.Sensor."
- "Threshold'",
- std::move(thresholdEventMatcherCallback));
- return thresholdEventMatcher;
+ "type='signal', member='ThresholdAsserted'",
+ std::move(thresholdAssertMatcherCallback));
+ return thresholdAssertMatcher;
}
diff --git a/src/sel_logger.cpp b/src/sel_logger.cpp
index fadcc17..186072e 100644
--- a/src/sel_logger.cpp
+++ b/src/sel_logger.cpp
@@ -202,8 +202,8 @@
ifaceAddSel->initialize();
#ifdef SEL_LOGGER_MONITOR_THRESHOLD_EVENTS
- sdbusplus::bus::match::match thresholdEventMonitor =
- startThresholdEventMonitor(conn);
+ sdbusplus::bus::match::match thresholdAssertMonitor =
+ startThresholdAssertMonitor(conn);
#endif
#ifdef REDFISH_LOG_MONITOR_PULSE_EVENTS