summaryrefslogtreecommitdiff
path: root/redfish-core/include/event_service_manager.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'redfish-core/include/event_service_manager.hpp')
-rw-r--r--redfish-core/include/event_service_manager.hpp641
1 files changed, 403 insertions, 238 deletions
diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp
index 4c2d0eebbd..8fd0157f9d 100644
--- a/redfish-core/include/event_service_manager.hpp
+++ b/redfish-core/include/event_service_manager.hpp
@@ -1,22 +1,25 @@
/*
-// Copyright (c) 2020 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+Copyright (c) 2020 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
*/
#pragma once
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "event_service_store.hpp"
+#include "filter_expr_executor.hpp"
+#include "generated/enums/event.hpp"
+#include "generated/enums/log_entry.hpp"
#include "http_client.hpp"
#include "metric_report.hpp"
#include "ossl_random.hpp"
@@ -31,6 +34,7 @@
#include <sys/inotify.h>
#include <boost/asio/io_context.hpp>
+#include <boost/circular_buffer.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/url/format.hpp>
#include <boost/url/url_view_base.hpp>
@@ -39,17 +43,16 @@
#include <algorithm>
#include <cstdlib>
#include <ctime>
+#include <format>
#include <fstream>
#include <memory>
#include <ranges>
#include <span>
+#include <string>
namespace redfish
{
-using ReadingsObjType =
- std::vector<std::tuple<std::string, std::string, double, int32_t>>;
-
static constexpr const char* eventFormatType = "Event";
static constexpr const char* metricReportFormatType = "MetricReport";
@@ -72,11 +75,13 @@ static int inotifyFd = -1;
static int dirWatchDesc = -1;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
static int fileWatchDesc = -1;
-
-// <ID, timestamp, RedfishLogId, registryPrefix, MessageId, MessageArgs>
-using EventLogObjectsType =
- std::tuple<std::string, std::string, std::string, std::string, std::string,
- std::vector<std::string>>;
+struct EventLogObjectsType
+{
+ std::string id;
+ std::string timestamp;
+ std::string messageId;
+ std::vector<std::string> messageArgs;
+};
namespace registries
{
@@ -86,8 +91,8 @@ static const Message*
{
std::span<const MessageEntry>::iterator messageIt = std::ranges::find_if(
registry, [&messageKey](const MessageEntry& messageEntry) {
- return messageKey == messageEntry.first;
- });
+ return messageKey == messageEntry.first;
+ });
if (messageIt != registry.end())
{
return &messageIt->second;
@@ -159,6 +164,8 @@ inline int getEventLogParams(const std::string& logEntry,
size_t space = logEntry.find_first_of(' ');
if (space == std::string::npos)
{
+ BMCWEB_LOG_ERROR("EventLog Params: could not find first space: {}",
+ logEntry);
return -EINVAL;
}
timestamp = logEntry.substr(0, space);
@@ -166,6 +173,8 @@ inline int getEventLogParams(const std::string& logEntry,
size_t entryStart = logEntry.find_first_not_of(' ', space);
if (entryStart == std::string::npos)
{
+ BMCWEB_LOG_ERROR("EventLog Params: could not find log contents: {}",
+ logEntry);
return -EINVAL;
}
std::string_view entry(logEntry);
@@ -176,6 +185,8 @@ inline int getEventLogParams(const std::string& logEntry,
// We need at least a MessageId to be valid
if (logEntryFields.empty())
{
+ BMCWEB_LOG_ERROR("EventLog Params: could not find entry fields: {}",
+ logEntry);
return -EINVAL;
}
messageID = logEntryFields[0];
@@ -212,12 +223,10 @@ inline void getRegistryAndMessageKey(const std::string& messageID,
}
}
-inline int formatEventLogEntry(const std::string& logEntryID,
- const std::string& messageID,
- const std::span<std::string_view> messageArgs,
- std::string timestamp,
- const std::string& customText,
- nlohmann::json& logEntryJson)
+inline int formatEventLogEntry(
+ const std::string& logEntryID, const std::string& messageID,
+ const std::span<std::string_view> messageArgs, std::string timestamp,
+ const std::string& customText, nlohmann::json::object_t& logEntryJson)
{
// Get the Message from the MessageRegistry
const registries::Message* message = registries::formatMessage(messageID);
@@ -227,8 +236,8 @@ inline int formatEventLogEntry(const std::string& logEntryID,
return -1;
}
- std::string msg = redfish::registries::fillMessageArgs(messageArgs,
- message->message);
+ std::string msg =
+ redfish::registries::fillMessageArgs(messageArgs, message->message);
if (msg.empty())
{
return -1;
@@ -246,7 +255,7 @@ inline int formatEventLogEntry(const std::string& logEntryID,
// Fill in the log entry with the gathered data
logEntryJson["EventId"] = logEntryID;
- logEntryJson["EventType"] = "Event";
+
logEntryJson["Severity"] = message->messageSeverity;
logEntryJson["Message"] = std::move(msg);
logEntryJson["MessageId"] = messageID;
@@ -282,7 +291,7 @@ class Subscription : public persistent_data::UserSubscription
~Subscription() = default;
- bool sendEvent(std::string&& msg)
+ bool sendEventToSubscriber(std::string&& msg)
{
persistent_data::EventServiceConfig eventServiceConfig =
persistent_data::EventServiceStore::getInstance()
@@ -292,33 +301,158 @@ class Subscription : public persistent_data::UserSubscription
return false;
}
- // A connection pool will be created if one does not already exist
if (client)
{
- client->sendData(std::move(msg), destinationUrl, httpHeaders,
- boost::beast::http::verb::post);
+ client->sendData(
+ std::move(msg), destinationUrl,
+ static_cast<ensuressl::VerifyCertificate>(verifyCertificate),
+ httpHeaders, boost::beast::http::verb::post);
return true;
}
if (sseConn != nullptr)
{
eventSeqNum++;
- sseConn->sendEvent(std::to_string(eventSeqNum), msg);
+ sseConn->sendSseEvent(std::to_string(eventSeqNum), msg);
}
return true;
}
+ bool eventMatchesFilter(const nlohmann::json::object_t& eventMessage,
+ std::string_view resType)
+ {
+ // If resourceTypes list is empty, assume all
+ if (!resourceTypes.empty())
+ {
+ // Search the resourceTypes list for the subscription.
+ auto resourceTypeIndex = std::ranges::find_if(
+ resourceTypes, [resType](const std::string& rtEntry) {
+ return rtEntry == resType;
+ });
+ if (resourceTypeIndex == resourceTypes.end())
+ {
+ BMCWEB_LOG_DEBUG("Not subscribed to this resource");
+ return false;
+ }
+ BMCWEB_LOG_DEBUG("ResourceType {} found in the subscribed list",
+ resType);
+ }
+
+ // If registryPrefixes list is empty, don't filter events
+ // send everything.
+ if (!registryPrefixes.empty())
+ {
+ auto eventJson = eventMessage.find("MessageId");
+ if (eventJson == eventMessage.end())
+ {
+ return false;
+ }
+
+ const std::string* messageId =
+ eventJson->second.get_ptr<const std::string*>();
+ if (messageId == nullptr)
+ {
+ BMCWEB_LOG_ERROR("MessageId wasn't a string???");
+ return false;
+ }
+
+ std::string registry;
+ std::string messageKey;
+ event_log::getRegistryAndMessageKey(*messageId, registry,
+ messageKey);
+
+ auto obj = std::ranges::find(registryPrefixes, registry);
+ if (obj == registryPrefixes.end())
+ {
+ return false;
+ }
+ }
+
+ if (!originResources.empty())
+ {
+ auto eventJson = eventMessage.find("OriginOfCondition");
+ if (eventJson == eventMessage.end())
+ {
+ return false;
+ }
+
+ const std::string* originOfCondition =
+ eventJson->second.get_ptr<const std::string*>();
+ if (originOfCondition == nullptr)
+ {
+ BMCWEB_LOG_ERROR("OriginOfCondition wasn't a string???");
+ return false;
+ }
+
+ auto obj = std::ranges::find(originResources, *originOfCondition);
+
+ if (obj == originResources.end())
+ {
+ return false;
+ }
+ }
+
+ // If registryMsgIds list is empty, assume all
+ if (!registryMsgIds.empty())
+ {
+ auto eventJson = eventMessage.find("MessageId");
+ if (eventJson == eventMessage.end())
+ {
+ BMCWEB_LOG_DEBUG("'MessageId' not present");
+ return false;
+ }
+
+ const std::string* messageId =
+ eventJson->second.get_ptr<const std::string*>();
+ if (messageId == nullptr)
+ {
+ BMCWEB_LOG_ERROR("EventType wasn't a string???");
+ return false;
+ }
+
+ std::string registry;
+ std::string messageKey;
+ event_log::getRegistryAndMessageKey(*messageId, registry,
+ messageKey);
+
+ BMCWEB_LOG_DEBUG("extracted registry {}", registry);
+ BMCWEB_LOG_DEBUG("extracted message key {}", messageKey);
+
+ auto obj = std::ranges::find(
+ registryMsgIds, std::format("{}.{}", registry, messageKey));
+ if (obj == registryMsgIds.end())
+ {
+ BMCWEB_LOG_DEBUG("did not find registry {} in registryMsgIds",
+ registry);
+ BMCWEB_LOG_DEBUG("registryMsgIds has {} entries",
+ registryMsgIds.size());
+ return false;
+ }
+ }
+
+ if (filter)
+ {
+ if (!memberMatches(eventMessage, *filter))
+ {
+ BMCWEB_LOG_DEBUG("Filter didn't match");
+ return false;
+ }
+ }
+
+ return true;
+ }
+
bool sendTestEventLog()
{
- nlohmann::json logEntryArray;
- logEntryArray.push_back({});
- nlohmann::json& logEntryJson = logEntryArray.back();
+ nlohmann::json::array_t logEntryArray;
+ nlohmann::json& logEntryJson = logEntryArray.emplace_back();
logEntryJson["EventId"] = "TestID";
- logEntryJson["EventType"] = "Event";
- logEntryJson["Severity"] = "OK";
+ logEntryJson["Severity"] = log_entry::EventSeverity::OK;
logEntryJson["Message"] = "Generated test event";
logEntryJson["MessageId"] = "OpenBMC.0.2.TestEventLog";
+ // MemberId is 0 : since we are sending one event record.
+ logEntryJson["MemberId"] = 0;
logEntryJson["MessageArgs"] = nlohmann::json::array();
logEntryJson["EventTimestamp"] =
redfish::time_utils::getDateTimeOffsetNow().first;
@@ -330,58 +464,37 @@ class Subscription : public persistent_data::UserSubscription
msg["Name"] = "Event Log";
msg["Events"] = logEntryArray;
- std::string strMsg = msg.dump(2, ' ', true,
- nlohmann::json::error_handler_t::replace);
- return sendEvent(std::move(strMsg));
+ std::string strMsg =
+ msg.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
+ return sendEventToSubscriber(std::move(strMsg));
}
void filterAndSendEventLogs(
const std::vector<EventLogObjectsType>& eventRecords)
{
- nlohmann::json logEntryArray;
+ nlohmann::json::array_t 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 std::vector<std::string>& messageArgs = std::get<5>(logEntry);
-
- // If registryPrefixes list is empty, don't filter events
- // send everything.
- if (!registryPrefixes.empty())
- {
- auto obj = std::ranges::find(registryPrefixes, registryName);
- if (obj == registryPrefixes.end())
- {
- continue;
- }
- }
+ std::vector<std::string_view> messageArgsView(
+ logEntry.messageArgs.begin(), logEntry.messageArgs.end());
- // If registryMsgIds list is empty, don't filter events
- // send everything.
- if (!registryMsgIds.empty())
+ nlohmann::json::object_t bmcLogEntry;
+ if (event_log::formatEventLogEntry(
+ logEntry.id, logEntry.messageId, messageArgsView,
+ logEntry.timestamp, customText, bmcLogEntry) != 0)
{
- auto obj = std::ranges::find(registryMsgIds, messageKey);
- if (obj == registryMsgIds.end())
- {
- continue;
- }
+ BMCWEB_LOG_DEBUG("Read eventLog entry failed");
+ continue;
}
- std::vector<std::string_view> messageArgsView(messageArgs.begin(),
- messageArgs.end());
-
- logEntryArray.push_back({});
- nlohmann::json& bmcLogEntry = logEntryArray.back();
- if (event_log::formatEventLogEntry(idStr, messageID,
- messageArgsView, timestamp,
- customText, bmcLogEntry) != 0)
+ if (!eventMatchesFilter(bmcLogEntry, ""))
{
- BMCWEB_LOG_DEBUG("Read eventLog entry failed");
+ BMCWEB_LOG_DEBUG("Event {} did not match the filter",
+ nlohmann::json(bmcLogEntry).dump());
continue;
}
+
+ logEntryArray.emplace_back(std::move(bmcLogEntry));
}
if (logEntryArray.empty())
@@ -394,10 +507,10 @@ class Subscription : public persistent_data::UserSubscription
msg["@odata.type"] = "#Event.v1_4_0.Event";
msg["Id"] = std::to_string(eventSeqNum);
msg["Name"] = "Event Log";
- msg["Events"] = logEntryArray;
- std::string strMsg = msg.dump(2, ' ', true,
- nlohmann::json::error_handler_t::replace);
- sendEvent(std::move(strMsg));
+ msg["Events"] = std::move(logEntryArray);
+ std::string strMsg =
+ msg.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
+ sendEventToSubscriber(std::move(strMsg));
eventSeqNum++;
}
@@ -434,9 +547,9 @@ class Subscription : public persistent_data::UserSubscription
msg["Context"] = customText;
}
- std::string strMsg = msg.dump(2, ' ', true,
- nlohmann::json::error_handler_t::replace);
- sendEvent(std::move(strMsg));
+ std::string strMsg =
+ msg.dump(2, ' ', true, nlohmann::json::error_handler_t::replace);
+ sendEventToSubscriber(std::move(strMsg));
}
void updateRetryConfig(uint32_t retryAttempts,
@@ -472,16 +585,6 @@ class Subscription : public persistent_data::UserSubscription
return &thisConn == sseConn;
}
- private:
- std::string subId;
- uint64_t eventSeqNum = 1;
- boost::urls::url host;
- std::shared_ptr<crow::ConnectionPolicy> policy;
- crow::sse_socket::Connection* sseConn = nullptr;
- std::optional<crow::HttpClient> client;
- std::string path;
- std::string uriProto;
-
// Check used to indicate what response codes are valid as part of our retry
// policy. 2XX is considered acceptable
static boost::system::error_code retryRespHandler(unsigned int respCode)
@@ -498,6 +601,18 @@ class Subscription : public persistent_data::UserSubscription
return boost::system::errc::make_error_code(
boost::system::errc::success);
}
+
+ private:
+ std::string subId;
+ uint64_t eventSeqNum = 1;
+ boost::urls::url host;
+ std::shared_ptr<crow::ConnectionPolicy> policy;
+ crow::sse_socket::Connection* sseConn = nullptr;
+
+ std::optional<crow::HttpClient> client;
+
+ public:
+ std::optional<filter_ast::LogicalAnd> filter;
};
class EventServiceManager
@@ -516,6 +631,15 @@ class EventServiceManager
uint64_t eventId{1};
+ struct Event
+ {
+ std::string id;
+ nlohmann::json message;
+ };
+
+ constexpr static size_t maxMessages = 200;
+ boost::circular_buffer<Event> messages{maxMessages};
+
boost::asio::io_context& ioc;
public:
@@ -571,6 +695,7 @@ class EventServiceManager
subValue->id = newSub->id;
subValue->destinationUrl = newSub->destinationUrl;
subValue->protocol = newSub->protocol;
+ subValue->verifyCertificate = newSub->verifyCertificate;
subValue->retryPolicy = newSub->retryPolicy;
subValue->customText = newSub->customText;
subValue->eventFormatType = newSub->eventFormatType;
@@ -580,6 +705,7 @@ class EventServiceManager
subValue->resourceTypes = newSub->resourceTypes;
subValue->httpHeaders = newSub->httpHeaders;
subValue->metricReportDefinitions = newSub->metricReportDefinitions;
+ subValue->originResources = newSub->originResources;
if (subValue->id.empty())
{
@@ -796,8 +922,8 @@ class EventServiceManager
return subValue;
}
- std::string addSubscription(const std::shared_ptr<Subscription>& subValue,
- const bool updateFile = true)
+ std::string
+ addSubscriptionInternal(const std::shared_ptr<Subscription>& subValue)
{
std::uniform_int_distribution<uint32_t> dist(0);
bmcweb::OpenSSLGenerator gen;
@@ -841,16 +967,13 @@ class EventServiceManager
newSub->resourceTypes = subValue->resourceTypes;
newSub->httpHeaders = subValue->httpHeaders;
newSub->metricReportDefinitions = subValue->metricReportDefinitions;
+ newSub->originResources = subValue->originResources;
+
persistent_data::EventServiceStore::getInstance()
.subscriptionsConfigMap.emplace(newSub->id, newSub);
updateNoOfSubscribersCount();
- if (updateFile)
- {
- updateSubscriptionData();
- }
-
if constexpr (!BMCWEB_REDFISH_DBUS_LOG)
{
if (redfishLogFilePosition != 0)
@@ -863,6 +986,55 @@ class EventServiceManager
// Set Subscription ID for back trace
subValue->setSubscriptionId(id);
+
+ return id;
+ }
+
+ std::string
+ addSSESubscription(const std::shared_ptr<Subscription>& subValue,
+ std::string_view lastEventId)
+ {
+ std::string id = addSubscriptionInternal(subValue);
+
+ if (!lastEventId.empty())
+ {
+ BMCWEB_LOG_INFO("Attempting to find message for last id {}",
+ lastEventId);
+ boost::circular_buffer<Event>::iterator lastEvent =
+ std::find_if(messages.begin(), messages.end(),
+ [&lastEventId](const Event& event) {
+ return event.id == lastEventId;
+ });
+ // Can't find a matching ID
+ if (lastEvent == messages.end())
+ {
+ nlohmann::json msg = messages::eventBufferExceeded();
+ // If the buffer overloaded, send all messages.
+ subValue->sendEventToSubscriber(msg);
+ lastEvent = messages.begin();
+ }
+ else
+ {
+ // Skip the last event the user already has
+ lastEvent++;
+ }
+
+ for (boost::circular_buffer<Event>::const_iterator event =
+ lastEvent;
+ lastEvent != messages.end(); lastEvent++)
+ {
+ subValue->sendEventToSubscriber(event->message);
+ }
+ }
+ return id;
+ }
+
+ std::string
+ addPushSubscription(const std::shared_ptr<Subscription>& subValue)
+ {
+ std::string id = addSubscriptionInternal(subValue);
+
+ updateSubscriptionData();
return id;
}
@@ -916,8 +1088,8 @@ class EventServiceManager
subscriptionsMap,
[](const std::pair<std::string, std::shared_ptr<Subscription>>&
entry) {
- return (entry.second->subscriptionType == subscriptionTypeSSE);
- });
+ return (entry.second->subscriptionType == subscriptionTypeSSE);
+ });
return static_cast<size_t>(size);
}
@@ -944,68 +1116,43 @@ class EventServiceManager
return true;
}
- void sendEvent(nlohmann::json eventMessage, const std::string& origin,
- const std::string& resType)
+ void sendEvent(nlohmann::json::object_t eventMessage,
+ std::string_view origin, std::string_view resourceType)
{
- if (!serviceEnabled || (noOfEventLogSubscribers == 0U))
- {
- BMCWEB_LOG_DEBUG("EventService disabled or no Subscriptions.");
- return;
- }
- nlohmann::json eventRecord = nlohmann::json::array();
-
eventMessage["EventId"] = eventId;
- // MemberId is 0 : since we are sending one event record.
- eventMessage["MemberId"] = 0;
+
eventMessage["EventTimestamp"] =
redfish::time_utils::getDateTimeOffsetNow().first;
eventMessage["OriginOfCondition"] = origin;
- eventRecord.emplace_back(std::move(eventMessage));
+ // MemberId is 0 : since we are sending one event record.
+ eventMessage["MemberId"] = 0;
- for (const auto& it : subscriptionsMap)
+ messages.push_back(Event(std::to_string(eventId), eventMessage));
+
+ for (auto& it : subscriptionsMap)
{
- std::shared_ptr<Subscription> entry = it.second;
- bool isSubscribed = false;
- // Search the resourceTypes list for the subscription.
- // If resourceTypes list is empty, don't filter events
- // send everything.
- if (!entry->resourceTypes.empty())
+ std::shared_ptr<Subscription>& entry = it.second;
+ if (!entry->eventMatchesFilter(eventMessage, resourceType))
{
- for (const auto& resource : entry->resourceTypes)
- {
- if (resType == resource)
- {
- BMCWEB_LOG_INFO(
- "ResourceType {} found in the subscribed list",
- resource);
- isSubscribed = true;
- break;
- }
- }
- }
- else // resourceTypes list is empty.
- {
- isSubscribed = true;
+ BMCWEB_LOG_DEBUG("Filter didn't match");
+ continue;
}
- if (isSubscribed)
- {
- nlohmann::json msgJson;
- msgJson["@odata.type"] = "#Event.v1_4_0.Event";
- msgJson["Name"] = "Event Log";
- msgJson["Id"] = eventId;
- msgJson["Events"] = eventRecord;
+ nlohmann::json::array_t eventRecord;
+ eventRecord.emplace_back(eventMessage);
- std::string strMsg = msgJson.dump(
- 2, ' ', true, nlohmann::json::error_handler_t::replace);
- entry->sendEvent(std::move(strMsg));
- eventId++; // increment the eventId
- }
- else
- {
- BMCWEB_LOG_INFO("Not subscribed to this resource");
- }
+ nlohmann::json msgJson;
+
+ msgJson["@odata.type"] = "#Event.v1_4_0.Event";
+ msgJson["Name"] = "Event Log";
+ msgJson["Id"] = eventId;
+ msgJson["Events"] = std::move(eventRecord);
+
+ std::string strMsg = msgJson.dump(
+ 2, ' ', true, nlohmann::json::error_handler_t::replace);
+ entry->sendEventToSubscriber(std::move(strMsg));
+ eventId++; // increment the eventId
}
}
@@ -1046,17 +1193,24 @@ class EventServiceManager
std::string logEntry;
+ BMCWEB_LOG_DEBUG("Redfish log file: seek to {}",
+ static_cast<int>(redfishLogFilePosition));
+
// Get the read pointer to the next log to be read.
logStream.seekg(redfishLogFilePosition);
while (std::getline(logStream, logEntry))
{
+ BMCWEB_LOG_DEBUG("Redfish log file: found new event log entry");
// Update Pointer position
redfishLogFilePosition = logStream.tellg();
std::string idStr;
if (!event_log::getUniqueEntryID(logEntry, idStr))
{
+ BMCWEB_LOG_DEBUG(
+ "Redfish log file: could not get unique entry id for {}",
+ logEntry);
continue;
}
@@ -1065,6 +1219,8 @@ class EventServiceManager
// If Service is not enabled, no need to compute
// the remaining items below.
// But, Loop must continue to keep track of Timestamp
+ BMCWEB_LOG_DEBUG(
+ "Redfish log file: no subscribers / event service not enabled");
continue;
}
@@ -1074,21 +1230,12 @@ class EventServiceManager
if (event_log::getEventLogParams(logEntry, timestamp, messageID,
messageArgs) != 0)
{
- BMCWEB_LOG_DEBUG("Read eventLog entry params failed");
+ BMCWEB_LOG_DEBUG("Read eventLog entry params failed for {}",
+ logEntry);
continue;
}
- std::string registryName;
- std::string messageKey;
- event_log::getRegistryAndMessageKey(messageID, registryName,
- messageKey);
- if (registryName.empty() || messageKey.empty())
- {
- continue;
- }
-
- eventRecords.emplace_back(idStr, timestamp, messageID, registryName,
- messageKey, messageArgs);
+ eventRecords.emplace_back(idStr, timestamp, messageID, messageArgs);
}
if (!serviceEnabled || noOfEventLogSubscribers == 0)
@@ -1118,98 +1265,110 @@ class EventServiceManager
{
if (!inotifyConn)
{
+ BMCWEB_LOG_ERROR("inotify Connection is not present");
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 + iEventSize) <= bytesTransferred)
- {
- struct inotify_event event
- {};
- std::memcpy(&event, &readBuffer[index], iEventSize);
- if (event.wd == dirWatchDesc)
+ inotifyConn->async_read_some(
+ boost::asio::buffer(readBuffer),
+ [&](const boost::system::error_code& ec,
+ const std::size_t& bytesTransferred) {
+ if (ec == boost::asio::error::operation_aborted)
{
- if ((event.len == 0) ||
- (index + iEventSize + event.len > bytesTransferred))
- {
- index += (iEventSize + event.len);
- continue;
- }
+ BMCWEB_LOG_DEBUG("Inotify was canceled (shutdown?)");
+ return;
+ }
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("Callback Error: {}", ec.message());
+ return;
+ }
- std::string fileName(&readBuffer[index + iEventSize]);
- if (fileName != "redfish")
- {
- index += (iEventSize + event.len);
- continue;
- }
+ BMCWEB_LOG_DEBUG("reading {} via inotify", bytesTransferred);
- BMCWEB_LOG_DEBUG(
- "Redfish log file created/deleted. event.name: {}",
- fileName);
- if (event.mask == IN_CREATE)
+ std::size_t index = 0;
+ while ((index + iEventSize) <= bytesTransferred)
+ {
+ struct inotify_event event
+ {};
+ std::memcpy(&event, &readBuffer[index], iEventSize);
+ if (event.wd == dirWatchDesc)
{
- if (fileWatchDesc != -1)
+ if ((event.len == 0) ||
+ (index + iEventSize + event.len > bytesTransferred))
{
- BMCWEB_LOG_DEBUG(
- "Remove and Add inotify watcher on "
- "redfish event log file");
- // Remove existing inotify watcher and add
- // with new redfish event log file.
- inotify_rm_watch(inotifyFd, fileWatchDesc);
- fileWatchDesc = -1;
+ index += (iEventSize + event.len);
+ continue;
}
- fileWatchDesc = inotify_add_watch(
- inotifyFd, redfishEventLogFile, IN_MODIFY);
- if (fileWatchDesc == -1)
+ std::string fileName(&readBuffer[index + iEventSize]);
+ if (fileName != "redfish")
{
- BMCWEB_LOG_ERROR("inotify_add_watch failed for "
- "redfish log file.");
- return;
+ index += (iEventSize + event.len);
+ continue;
}
- EventServiceManager::getInstance()
- .resetRedfishFilePosition();
- EventServiceManager::getInstance()
- .readEventLogsFromFile();
- }
- else if ((event.mask == IN_DELETE) ||
- (event.mask == IN_MOVED_TO))
- {
- if (fileWatchDesc != -1)
+ BMCWEB_LOG_DEBUG(
+ "Redfish log file created/deleted. event.name: {}",
+ fileName);
+ if (event.mask == IN_CREATE)
{
- inotify_rm_watch(inotifyFd, fileWatchDesc);
- fileWatchDesc = -1;
+ if (fileWatchDesc != -1)
+ {
+ BMCWEB_LOG_DEBUG(
+ "Remove and Add inotify watcher on "
+ "redfish event log file");
+ // Remove existing inotify watcher and add
+ // with new redfish event log file.
+ inotify_rm_watch(inotifyFd, fileWatchDesc);
+ fileWatchDesc = -1;
+ }
+
+ fileWatchDesc = inotify_add_watch(
+ inotifyFd, redfishEventLogFile, IN_MODIFY);
+ if (fileWatchDesc == -1)
+ {
+ BMCWEB_LOG_ERROR("inotify_add_watch failed for "
+ "redfish log file.");
+ return;
+ }
+
+ EventServiceManager::getInstance()
+ .resetRedfishFilePosition();
+ EventServiceManager::getInstance()
+ .readEventLogsFromFile();
+ }
+ else if ((event.mask == IN_DELETE) ||
+ (event.mask == IN_MOVED_TO))
+ {
+ if (fileWatchDesc != -1)
+ {
+ inotify_rm_watch(inotifyFd, fileWatchDesc);
+ fileWatchDesc = -1;
+ }
}
}
- }
- else if (event.wd == fileWatchDesc)
- {
- if (event.mask == IN_MODIFY)
+ else if (event.wd == fileWatchDesc)
{
- EventServiceManager::getInstance()
- .readEventLogsFromFile();
+ if (event.mask == IN_MODIFY)
+ {
+ EventServiceManager::getInstance()
+ .readEventLogsFromFile();
+ }
}
+ index += (iEventSize + event.len);
}
- index += (iEventSize + event.len);
- }
- watchRedfishEventLogFile();
- });
+ watchRedfishEventLogFile();
+ });
}
static int startEventLogMonitor(boost::asio::io_context& ioc)
{
+ BMCWEB_LOG_DEBUG("starting Event Log Monitor");
+
inotifyConn.emplace(ioc);
inotifyFd = inotify_init1(IN_NONBLOCK);
if (inotifyFd == -1)
@@ -1230,8 +1389,8 @@ class EventServiceManager
}
// Watch redfish event log file for modifications.
- fileWatchDesc = inotify_add_watch(inotifyFd, redfishEventLogFile,
- IN_MODIFY);
+ fileWatchDesc =
+ inotify_add_watch(inotifyFd, redfishEventLogFile, IN_MODIFY);
if (fileWatchDesc == -1)
{
BMCWEB_LOG_ERROR("inotify_add_watch failed for redfish log file.");
@@ -1246,6 +1405,11 @@ class EventServiceManager
return 0;
}
+ static void stopEventLogMonitor()
+ {
+ inotifyConn.reset();
+ }
+
static void getReadingsForReport(sdbusplus::message_t& msg)
{
if (msg.is_method_error())
@@ -1267,8 +1431,9 @@ class EventServiceManager
std::vector<std::string> invalidProps;
msg.read(interface, props, invalidProps);
- auto found = std::ranges::find_if(
- props, [](const auto& x) { return x.first == "Readings"; });
+ auto found = std::ranges::find_if(props, [](const auto& x) {
+ return x.first == "Readings";
+ });
if (found == props.end())
{
BMCWEB_LOG_INFO("Failed to get Readings from Report properties");