diff options
-rw-r--r-- | redfish-core/include/event_service_manager.hpp | 458 | ||||
-rw-r--r-- | src/webserver_main.cpp | 9 |
2 files changed, 1 insertions, 466 deletions
diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp index faf093dd4b..569c307977 100644 --- a/redfish-core/include/event_service_manager.hpp +++ b/redfish-core/include/event_service_manager.hpp @@ -15,11 +15,6 @@ */ #pragma once #include "node.hpp" -#include "registries.hpp" -#include "registries/base_message_registry.hpp" -#include "registries/openbmc_message_registry.hpp" - -#include <sys/inotify.h> #include <boost/asio/io_context.hpp> #include <boost/container/flat_map.hpp> @@ -45,224 +40,6 @@ static constexpr const char* metricReportFormatType = "MetricReport"; static constexpr const char* eventServiceFile = "/var/lib/bmcweb/eventservice_config.json"; -#ifndef BMCWEB_ENABLE_REDFISH_DBUS_LOG_ENTRIES -constexpr const char* redfishEventLogFile = "/var/log/redfish"; -constexpr const uint32_t inotifyFileAction = IN_MODIFY; -std::shared_ptr<boost::asio::posix::stream_descriptor> inotifyConn = nullptr; - -// <ID, timestamp, RedfishLogId, registryPrefix, MessageId, MessageArgs> -using EventLogObjectsType = - std::tuple<std::string, std::string, std::string, std::string, std::string, - boost::beast::span<std::string>>; - -namespace message_registries -{ -static const Message* - getMsgFromRegistry(const std::string& messageKey, - const boost::beast::span<const MessageEntry>& registry) -{ - boost::beast::span<const MessageEntry>::const_iterator messageIt = - std::find_if(registry.cbegin(), registry.cend(), - [&messageKey](const MessageEntry& messageEntry) { - return !messageKey.compare(messageEntry.first); - }); - if (messageIt != registry.cend()) - { - return &messageIt->second; - } - - return nullptr; -} - -static const Message* formatMessage(const std::string_view& messageID) -{ - // Redfish MessageIds are in the form - // RegistryName.MajorVersion.MinorVersion.MessageKey, so parse it to find - // the right Message - std::vector<std::string> fields; - fields.reserve(4); - boost::split(fields, messageID, boost::is_any_of(".")); - if (fields.size() != 4) - { - return nullptr; - } - std::string& registryName = fields[0]; - std::string& messageKey = fields[3]; - - // Find the right registry and check it for the MessageKey - if (std::string(base::header.registryPrefix) == registryName) - { - return getMsgFromRegistry( - messageKey, boost::beast::span<const MessageEntry>(base::registry)); - } - if (std::string(openbmc::header.registryPrefix) == registryName) - { - return getMsgFromRegistry( - messageKey, - boost::beast::span<const MessageEntry>(openbmc::registry)); - } - return nullptr; -} -} // namespace message_registries - -namespace event_log -{ -bool getUniqueEntryID(const std::string& logEntry, std::string& entryID, - const bool firstEntry = true) -{ - static time_t prevTs = 0; - static int index = 0; - if (firstEntry) - { - prevTs = 0; - } - - // Get the entry timestamp - std::time_t curTs = 0; - std::tm timeStruct = {}; - std::istringstream entryStream(logEntry); - if (entryStream >> std::get_time(&timeStruct, "%Y-%m-%dT%H:%M:%S")) - { - curTs = std::mktime(&timeStruct); - if (curTs == -1) - { - return false; - } - } - // If the timestamp isn't unique, increment the index - index = (curTs == prevTs) ? index + 1 : 0; - - // Save the timestamp - prevTs = curTs; - - entryID = std::to_string(curTs); - if (index > 0) - { - entryID += "_" + std::to_string(index); - } - return true; -} - -int getEventLogParams(const std::string& logEntry, std::string& timestamp, - std::string& messageID, - boost::beast::span<std::string>& messageArgs) -{ - // The redfish log format is "<Timestamp> <MessageId>,<MessageArgs>" - // First get the Timestamp - size_t space = logEntry.find_first_of(" "); - if (space == std::string::npos) - { - return -EINVAL; - } - timestamp = logEntry.substr(0, space); - // Then get the log contents - size_t entryStart = logEntry.find_first_not_of(" ", space); - if (entryStart == std::string::npos) - { - return -EINVAL; - } - std::string_view entry(logEntry); - entry.remove_prefix(entryStart); - // Use split to separate the entry into its fields - std::vector<std::string> logEntryFields; - boost::split(logEntryFields, entry, boost::is_any_of(","), - boost::token_compress_on); - // We need at least a MessageId to be valid - if (logEntryFields.size() < 1) - { - return -EINVAL; - } - messageID = logEntryFields[0]; - - // Get the MessageArgs from the log if there are any - if (logEntryFields.size() > 1) - { - std::string& messageArgsStart = logEntryFields[1]; - // If the first string is empty, assume there are no MessageArgs - std::size_t messageArgsSize = 0; - if (!messageArgsStart.empty()) - { - messageArgsSize = logEntryFields.size() - 1; - } - - messageArgs = boost::beast::span(&messageArgsStart, messageArgsSize); - } - - return 0; -} - -void getRegistryAndMessageKey(const std::string& messageID, - std::string& registryName, - std::string& messageKey) -{ - // Redfish MessageIds are in the form - // RegistryName.MajorVersion.MinorVersion.MessageKey, so parse it to find - // the right Message - std::vector<std::string> fields; - fields.reserve(4); - boost::split(fields, messageID, boost::is_any_of(".")); - if (fields.size() == 4) - { - registryName = fields[0]; - messageKey = fields[3]; - } -} - -int formatEventLogEntry(const std::string& logEntryID, - const std::string& messageID, - const boost::beast::span<std::string>& messageArgs, - std::string timestamp, const std::string customText, - nlohmann::json& logEntryJson) -{ - // Get the Message from the MessageRegistry - const message_registries::Message* message = - message_registries::formatMessage(messageID); - - std::string msg; - std::string severity; - if (message != nullptr) - { - msg = message->message; - severity = message->severity; - } - - // Fill the MessageArgs into the Message - int i = 0; - for (const std::string& messageArg : messageArgs) - { - std::string argStr = "%" + std::to_string(++i); - size_t argPos = msg.find(argStr); - if (argPos != std::string::npos) - { - msg.replace(argPos, argStr.length(), messageArg); - } - } - - // Get the Created time from the timestamp. The log timestamp is in - // RFC3339 format which matches the Redfish format except for the - // fractional seconds between the '.' and the '+', so just remove them. - std::size_t dot = timestamp.find_first_of("."); - std::size_t plus = timestamp.find_first_of("+"); - if (dot != std::string::npos && plus != std::string::npos) - { - timestamp.erase(dot, plus - dot); - } - - // Fill in the log entry with the gathered data - logEntryJson = {{"EventId", logEntryID}, - {"EventType", "Event"}, - {"Severity", std::move(severity)}, - {"Message", std::move(msg)}, - {"MessageId", std::move(messageID)}, - {"MessageArgs", std::move(messageArgs)}, - {"EventTimestamp", std::move(timestamp)}, - {"Context", customText}}; - return 0; -} - -} // namespace event_log -#endif - class Subscription { public: @@ -335,72 +112,6 @@ class Subscription this->eventSeqNum++; } -#ifndef BMCWEB_ENABLE_REDFISH_DBUS_LOG_ENTRIES - void filterAndSendEventLogs( - const std::vector<EventLogObjectsType>& eventRecords) - { - nlohmann::json logEntryArray; - for (const EventLogObjectsType& logEntry : eventRecords) - { - const std::string& idStr = std::get<0>(logEntry); - const std::string& timestamp = std::get<1>(logEntry); - const std::string& messageID = std::get<2>(logEntry); - const std::string& registryName = std::get<3>(logEntry); - const std::string& messageKey = std::get<4>(logEntry); - const boost::beast::span<std::string>& messageArgs = - std::get<5>(logEntry); - - // If registryPrefixes list is empty, don't filter events - // send everything. - if (registryPrefixes.size()) - { - auto obj = std::find(registryPrefixes.begin(), - registryPrefixes.end(), registryName); - if (obj == registryPrefixes.end()) - { - continue; - } - } - - // If registryMsgIds list is empty, don't filter events - // send everything. - if (registryMsgIds.size()) - { - auto obj = std::find(registryMsgIds.begin(), - registryMsgIds.end(), messageKey); - if (obj == registryMsgIds.end()) - { - continue; - } - } - - logEntryArray.push_back({}); - nlohmann::json& bmcLogEntry = logEntryArray.back(); - if (event_log::formatEventLogEntry(idStr, messageID, messageArgs, - timestamp, customText, - bmcLogEntry) != 0) - { - BMCWEB_LOG_DEBUG << "Read eventLog entry failed"; - continue; - } - } - - if (logEntryArray.size() < 1) - { - BMCWEB_LOG_DEBUG << "No log entries available to be transferred."; - return; - } - - nlohmann::json msg = {{"@odata.type", "#Event.v1_4_0.Event"}, - {"Id", std::to_string(eventSeqNum)}, - {"Name", "Event Log"}, - {"Events", logEntryArray}}; - - this->sendEvent(msg.dump()); - this->eventSeqNum++; - } -#endif - void filterAndSendReports(const std::string& id, const std::string& readingsTs, const ReadingsObjType& readings) @@ -478,7 +189,6 @@ class EventServiceManager initConfig(); } - std::string lastEventTStr; size_t noOfEventLogSubscribers; size_t noOfMetricReportSubscribers; std::shared_ptr<sdbusplus::bus::match::match> matchTelemetryMonitor; @@ -783,13 +493,6 @@ class EventServiceManager { updateSubscriptionData(); } - -#ifndef BMCWEB_ENABLE_REDFISH_DBUS_LOG_ENTRIES - if (lastEventTStr.empty()) - { - cacheLastEventTimestamp(); - } -#endif return id; } @@ -852,165 +555,6 @@ class EventServiceManager } } -#ifndef BMCWEB_ENABLE_REDFISH_DBUS_LOG_ENTRIES - void cacheLastEventTimestamp() - { - std::ifstream logStream(redfishEventLogFile); - if (!logStream.good()) - { - BMCWEB_LOG_ERROR << " Redfish log file open failed \n"; - return; - } - std::string logEntry; - while (std::getline(logStream, logEntry)) - { - size_t space = logEntry.find_first_of(" "); - if (space == std::string::npos) - { - // Shouldn't enter here but lets skip it. - BMCWEB_LOG_DEBUG << "Invalid log entry found."; - continue; - } - lastEventTStr = logEntry.substr(0, space); - } - BMCWEB_LOG_DEBUG << "Last Event time stamp set: " << lastEventTStr; - } - - void readEventLogsFromFile() - { - if (!serviceEnabled || !noOfEventLogSubscribers) - { - BMCWEB_LOG_DEBUG << "EventService disabled or no Subscriptions."; - return; - } - std::ifstream logStream(redfishEventLogFile); - if (!logStream.good()) - { - BMCWEB_LOG_ERROR << " Redfish log file open failed"; - return; - } - - std::vector<EventLogObjectsType> eventRecords; - - bool startLogCollection = false; - bool firstEntry = true; - - std::string logEntry; - while (std::getline(logStream, logEntry)) - { - if (!startLogCollection) - { - if (boost::starts_with(logEntry, lastEventTStr)) - { - startLogCollection = true; - } - continue; - } - - std::string idStr; - if (!event_log::getUniqueEntryID(logEntry, idStr, firstEntry)) - { - continue; - } - firstEntry = false; - - std::string timestamp; - std::string messageID; - boost::beast::span<std::string> messageArgs; - if (event_log::getEventLogParams(logEntry, timestamp, messageID, - messageArgs) != 0) - { - BMCWEB_LOG_DEBUG << "Read eventLog entry params failed"; - continue; - } - - std::string registryName; - std::string messageKey; - event_log::getRegistryAndMessageKey(messageID, registryName, - messageKey); - if (registryName.empty() || messageKey.empty()) - { - continue; - } - - lastEventTStr = timestamp; - eventRecords.emplace_back(idStr, timestamp, messageID, registryName, - messageKey, messageArgs); - } - - for (const auto& it : this->subscriptionsMap) - { - std::shared_ptr<Subscription> entry = it.second; - if (entry->eventFormatType == "Event") - { - entry->filterAndSendEventLogs(eventRecords); - } - } - } - - static void watchRedfishEventLogFile() - { - if (inotifyConn == nullptr) - { - return; - } - - static std::array<char, 1024> readBuffer; - - inotifyConn->async_read_some( - boost::asio::buffer(readBuffer), - [&](const boost::system::error_code& ec, - const std::size_t& bytesTransferred) { - if (ec) - { - BMCWEB_LOG_ERROR << "Callback Error: " << ec.message(); - return; - } - std::size_t index = 0; - while ((index + sizeof(inotify_event)) <= bytesTransferred) - { - struct inotify_event event; - std::memcpy(&event, &readBuffer[index], - sizeof(inotify_event)); - if (event.mask == inotifyFileAction) - { - EventServiceManager::getInstance() - .readEventLogsFromFile(); - } - index += (sizeof(inotify_event) + event.len); - } - - watchRedfishEventLogFile(); - }); - } - - static int startEventLogMonitor(boost::asio::io_context& ioc) - { - inotifyConn = - std::make_shared<boost::asio::posix::stream_descriptor>(ioc); - int fd = inotify_init1(IN_NONBLOCK); - if (fd == -1) - { - BMCWEB_LOG_ERROR << "inotify_init1 failed."; - return -1; - } - auto wd = inotify_add_watch(fd, redfishEventLogFile, inotifyFileAction); - if (wd == -1) - { - BMCWEB_LOG_ERROR - << "inotify_add_watch failed for redfish log file."; - return -1; - } - - // monitor redfish event log file - inotifyConn->assign(fd); - watchRedfishEventLogFile(); - - return 0; - } - -#endif - void getMetricReading(const std::string& service, const std::string& objPath, const std::string& intf) { @@ -1162,6 +706,6 @@ class EventServiceManager } return true; } -}; // namespace redfish +}; } // namespace redfish diff --git a/src/webserver_main.cpp b/src/webserver_main.cpp index ea32122b3b..f4e6207b7f 100644 --- a/src/webserver_main.cpp +++ b/src/webserver_main.cpp @@ -116,15 +116,6 @@ int main(int argc, char** argv) redfish::RedfishService redfish(app); -#ifndef BMCWEB_ENABLE_REDFISH_DBUS_LOG_ENTRIES - int rc = redfish::EventServiceManager::startEventLogMonitor(*io); - if (rc) - { - BMCWEB_LOG_ERROR << "Redfish event handler setup failed..."; - return rc; - } -#endif - app.run(); io->run(); |