1 #include "dbus_log_watcher.hpp" 2 3 #include "dbus_singleton.hpp" 4 #include "dbus_utility.hpp" 5 #include "event_logs_object_type.hpp" 6 #include "event_service_manager.hpp" 7 #include "logging.hpp" 8 #include "metric_report.hpp" 9 #include "utils/dbus_event_log_entry.hpp" 10 11 #include <sdbusplus/bus/match.hpp> 12 #include <sdbusplus/message.hpp> 13 #include <sdbusplus/message/native_types.hpp> 14 15 #include <algorithm> 16 #include <optional> 17 #include <string> 18 #include <variant> 19 #include <vector> 20 21 namespace redfish 22 { 23 static bool eventLogObjectFromDBus(const dbus::utility::DBusPropertiesMap& map, 24 EventLogObjectsType& event) 25 { 26 std::optional<DbusEventLogEntry> optEntry = 27 fillDbusEventLogEntryFromPropertyMap(map); 28 29 if (!optEntry.has_value()) 30 { 31 BMCWEB_LOG_ERROR( 32 "Could not construct event log entry from dbus properties"); 33 return false; 34 } 35 DbusEventLogEntry& entry = optEntry.value(); 36 event.id = std::to_string(entry.Id); 37 38 // The order of 'AdditionalData' is not what's specified in an e.g. 39 // busctl call to create the Event Log Entry. So it cannot be used 40 // to map to the message args. Leaving this branch here for it to be 41 // implemented when the mapping is available 42 43 return true; 44 } 45 46 static void dbusEventLogMatchHandlerSingleEntry( 47 const dbus::utility::DBusPropertiesMap& map) 48 { 49 std::vector<EventLogObjectsType> eventRecords; 50 EventLogObjectsType& event = eventRecords.emplace_back(); 51 bool success = eventLogObjectFromDBus(map, event); 52 if (!success) 53 { 54 BMCWEB_LOG_ERROR("Could not parse event log entry from dbus"); 55 return; 56 } 57 58 BMCWEB_LOG_DEBUG("Found Event Log Entry Id={}, Timestamp={}, Message={}", 59 event.id, event.timestamp, event.messageId); 60 EventServiceManager::sendEventsToSubs(eventRecords); 61 } 62 63 static void onDbusEventLogCreated(sdbusplus::message_t& msg) 64 { 65 BMCWEB_LOG_DEBUG("Handling new DBus Event Log Entry"); 66 67 sdbusplus::message::object_path objectPath; 68 dbus::utility::DBusInterfacesMap interfaces; 69 70 msg.read(objectPath, interfaces); 71 72 for (auto& pair : interfaces) 73 { 74 BMCWEB_LOG_DEBUG("Found dbus interface {}", pair.first); 75 if (pair.first == "xyz.openbmc_project.Logging.Entry") 76 { 77 const dbus::utility::DBusPropertiesMap& map = pair.second; 78 dbusEventLogMatchHandlerSingleEntry(map); 79 } 80 } 81 } 82 83 const std::string propertiesMatchString = 84 sdbusplus::bus::match::rules::type::signal() + 85 sdbusplus::bus::match::rules::sender("xyz.openbmc_project.Logging") + 86 sdbusplus::bus::match::rules::interface( 87 "org.freedesktop.DBus.ObjectManager") + 88 sdbusplus::bus::match::rules::path("/xyz/openbmc_project/logging") + 89 sdbusplus::bus::match::rules::member("InterfacesAdded"); 90 91 DbusEventLogMonitor::DbusEventLogMonitor() : 92 dbusEventLogMonitor(*crow::connections::systemBus, propertiesMatchString, 93 onDbusEventLogCreated) 94 95 {} 96 97 static void getReadingsForReport(sdbusplus::message_t& msg) 98 { 99 if (msg.is_method_error()) 100 { 101 BMCWEB_LOG_ERROR("TelemetryMonitor Signal error"); 102 return; 103 } 104 105 sdbusplus::message::object_path path(msg.get_path()); 106 std::string id = path.filename(); 107 if (id.empty()) 108 { 109 BMCWEB_LOG_ERROR("Failed to get Id from path"); 110 return; 111 } 112 113 std::string interface; 114 dbus::utility::DBusPropertiesMap props; 115 std::vector<std::string> invalidProps; 116 msg.read(interface, props, invalidProps); 117 118 auto found = std::ranges::find_if(props, [](const auto& x) { 119 return x.first == "Readings"; 120 }); 121 if (found == props.end()) 122 { 123 BMCWEB_LOG_INFO("Failed to get Readings from Report properties"); 124 return; 125 } 126 127 const telemetry::TimestampReadings* readings = 128 std::get_if<telemetry::TimestampReadings>(&found->second); 129 if (readings == nullptr) 130 { 131 BMCWEB_LOG_INFO("Failed to get Readings from Report properties"); 132 return; 133 } 134 EventServiceManager::sendTelemetryReportToSubs(id, *readings); 135 } 136 137 const std::string telemetryMatchStr = 138 "type='signal',member='PropertiesChanged'," 139 "interface='org.freedesktop.DBus.Properties'," 140 "arg0=xyz.openbmc_project.Telemetry.Report"; 141 142 DbusTelemetryMonitor::DbusTelemetryMonitor() : 143 matchTelemetryMonitor(*crow::connections::systemBus, telemetryMatchStr, 144 getReadingsForReport) 145 {} 146 } // namespace redfish 147