diff --git a/redfish-core/lib/log_services.hpp b/redfish-core/lib/log_services.hpp
index 76a2414..26ddc0a 100644
--- a/redfish-core/lib/log_services.hpp
+++ b/redfish-core/lib/log_services.hpp
@@ -1263,53 +1263,58 @@
     });
 }
 
+inline void handleSystemsLogServicesEventLogActionsClearPost(
+    App& app, const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& systemName)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+    if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+    {
+        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+                                   systemName);
+        return;
+    }
+
+    // Clear the EventLog by deleting the log files
+    std::vector<std::filesystem::path> redfishLogFiles;
+    if (getRedfishLogFiles(redfishLogFiles))
+    {
+        for (const std::filesystem::path& file : redfishLogFiles)
+        {
+            std::error_code ec;
+            std::filesystem::remove(file, ec);
+        }
+    }
+
+    // Reload rsyslog so it knows to start new log files
+    crow::connections::systemBus->async_method_call(
+        [asyncResp](const boost::system::error_code& ec) {
+        if (ec)
+        {
+            BMCWEB_LOG_ERROR("Failed to reload rsyslog: {}", ec);
+            messages::internalError(asyncResp->res);
+            return;
+        }
+
+        messages::success(asyncResp->res);
+    },
+        "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
+        "org.freedesktop.systemd1.Manager", "ReloadUnit", "rsyslog.service",
+        "replace");
+}
+
 inline void requestRoutesJournalEventLogClear(App& app)
 {
     BMCWEB_ROUTE(
         app,
         "/redfish/v1/Systems/<str>/LogServices/EventLog/Actions/LogService.ClearLog/")
         .privileges({{"ConfigureComponents"}})
-        .methods(boost::beast::http::verb::post)(
-            [&app](const crow::Request& req,
-                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                   const std::string& systemName) {
-        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-        {
-            return;
-        }
-        if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
-        {
-            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
-                                       systemName);
-            return;
-        }
-        // Clear the EventLog by deleting the log files
-        std::vector<std::filesystem::path> redfishLogFiles;
-        if (getRedfishLogFiles(redfishLogFiles))
-        {
-            for (const std::filesystem::path& file : redfishLogFiles)
-            {
-                std::error_code ec;
-                std::filesystem::remove(file, ec);
-            }
-        }
-
-        // Reload rsyslog so it knows to start new log files
-        crow::connections::systemBus->async_method_call(
-            [asyncResp](const boost::system::error_code& ec) {
-            if (ec)
-            {
-                BMCWEB_LOG_ERROR("Failed to reload rsyslog: {}", ec);
-                messages::internalError(asyncResp->res);
-                return;
-            }
-
-            messages::success(asyncResp->res);
-        },
-            "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
-            "org.freedesktop.systemd1.Manager", "ReloadUnit", "rsyslog.service",
-            "replace");
-    });
+        .methods(boost::beast::http::verb::post)(std::bind_front(
+            handleSystemsLogServicesEventLogActionsClearPost, std::ref(app)));
 }
 
 enum class LogParseError
@@ -1397,116 +1402,191 @@
     return LogParseError::success;
 }
 
-inline void requestRoutesJournalEventLogEntryCollection(App& app)
+inline void handleSystemsLogServiceEventLogLogEntryCollection(
+    App& app, const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& systemName)
 {
-    BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/")
-        .privileges(redfish::privileges::getLogEntryCollection)
-        .methods(boost::beast::http::verb::get)(
-            [&app](const crow::Request& req,
-                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                   const std::string& systemName) {
-        query_param::QueryCapabilities capabilities = {
-            .canDelegateTop = true,
-            .canDelegateSkip = true,
-        };
-        query_param::Query delegatedQuery;
-        if (!redfish::setUpRedfishRouteWithDelegation(
-                app, req, asyncResp, delegatedQuery, capabilities))
+    query_param::QueryCapabilities capabilities = {
+        .canDelegateTop = true,
+        .canDelegateSkip = true,
+    };
+    query_param::Query delegatedQuery;
+    if (!redfish::setUpRedfishRouteWithDelegation(app, req, asyncResp,
+                                                  delegatedQuery, capabilities))
+    {
+        return;
+    }
+    if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+    {
+        // Option currently returns no systems.  TBD
+        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+                                   systemName);
+        return;
+    }
+    if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+    {
+        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+                                   systemName);
+        return;
+    }
+
+    size_t top = delegatedQuery.top.value_or(query_param::Query::maxTop);
+    size_t skip = delegatedQuery.skip.value_or(0);
+
+    // Collections don't include the static data added by SubRoute
+    // because it has a duplicate entry for members
+    asyncResp->res.jsonValue["@odata.type"] =
+        "#LogEntryCollection.LogEntryCollection";
+    asyncResp->res.jsonValue["@odata.id"] =
+        std::format("/redfish/v1/Systems/{}/LogServices/EventLog/Entries",
+                    BMCWEB_REDFISH_SYSTEM_URI_NAME);
+    asyncResp->res.jsonValue["Name"] = "System Event Log Entries";
+    asyncResp->res.jsonValue["Description"] =
+        "Collection of System Event Log Entries";
+
+    nlohmann::json& logEntryArray = asyncResp->res.jsonValue["Members"];
+    logEntryArray = nlohmann::json::array();
+    // Go through the log files and create a unique ID for each
+    // entry
+    std::vector<std::filesystem::path> redfishLogFiles;
+    getRedfishLogFiles(redfishLogFiles);
+    uint64_t entryCount = 0;
+    std::string logEntry;
+
+    // Oldest logs are in the last file, so start there and loop
+    // backwards
+    for (auto it = redfishLogFiles.rbegin(); it < redfishLogFiles.rend(); it++)
+    {
+        std::ifstream logStream(*it);
+        if (!logStream.is_open())
         {
-            return;
-        }
-        if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
-        {
-            // Option currently returns no systems.  TBD
-            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
-                                       systemName);
-            return;
-        }
-        if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
-        {
-            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
-                                       systemName);
-            return;
+            continue;
         }
 
-        size_t top = delegatedQuery.top.value_or(query_param::Query::maxTop);
-        size_t skip = delegatedQuery.skip.value_or(0);
-
-        // Collections don't include the static data added by SubRoute
-        // because it has a duplicate entry for members
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#LogEntryCollection.LogEntryCollection";
-        asyncResp->res.jsonValue["@odata.id"] =
-            std::format("/redfish/v1/Systems/{}/LogServices/EventLog/Entries",
-                        BMCWEB_REDFISH_SYSTEM_URI_NAME);
-        asyncResp->res.jsonValue["Name"] = "System Event Log Entries";
-        asyncResp->res.jsonValue["Description"] =
-            "Collection of System Event Log Entries";
-
-        nlohmann::json& logEntryArray = asyncResp->res.jsonValue["Members"];
-        logEntryArray = nlohmann::json::array();
-        // Go through the log files and create a unique ID for each
-        // entry
-        std::vector<std::filesystem::path> redfishLogFiles;
-        getRedfishLogFiles(redfishLogFiles);
-        uint64_t entryCount = 0;
-        std::string logEntry;
-
-        // Oldest logs are in the last file, so start there and loop
-        // backwards
-        for (auto it = redfishLogFiles.rbegin(); it < redfishLogFiles.rend();
-             it++)
+        // Reset the unique ID on the first entry
+        bool firstEntry = true;
+        while (std::getline(logStream, logEntry))
         {
-            std::ifstream logStream(*it);
-            if (!logStream.is_open())
+            std::string idStr;
+            if (!getUniqueEntryID(logEntry, idStr, firstEntry))
+            {
+                continue;
+            }
+            firstEntry = false;
+
+            nlohmann::json::object_t bmcLogEntry;
+            LogParseError status = fillEventLogEntryJson(idStr, logEntry,
+                                                         bmcLogEntry);
+            if (status == LogParseError::messageIdNotInRegistry)
+            {
+                continue;
+            }
+            if (status != LogParseError::success)
+            {
+                messages::internalError(asyncResp->res);
+                return;
+            }
+
+            entryCount++;
+            // Handle paging using skip (number of entries to skip from the
+            // start) and top (number of entries to display)
+            if (entryCount <= skip || entryCount > skip + top)
             {
                 continue;
             }
 
-            // Reset the unique ID on the first entry
-            bool firstEntry = true;
-            while (std::getline(logStream, logEntry))
-            {
-                std::string idStr;
-                if (!getUniqueEntryID(logEntry, idStr, firstEntry))
-                {
-                    continue;
-                }
-                firstEntry = false;
+            logEntryArray.emplace_back(std::move(bmcLogEntry));
+        }
+    }
+    asyncResp->res.jsonValue["Members@odata.count"] = entryCount;
+    if (skip + top < entryCount)
+    {
+        asyncResp->res.jsonValue["Members@odata.nextLink"] =
+            boost::urls::format(
+                "/redfish/v1/Systems/{}/LogServices/EventLog/Entries?$skip={}",
+                BMCWEB_REDFISH_SYSTEM_URI_NAME, std::to_string(skip + top));
+    }
+}
 
+inline void requestRoutesJournalEventLogEntryCollection(App& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/")
+        .privileges(redfish::privileges::getLogEntryCollection)
+        .methods(boost::beast::http::verb::get)(std::bind_front(
+            handleSystemsLogServiceEventLogLogEntryCollection, std::ref(app)));
+}
+
+inline void handleSystemsLogServiceEventLogEntriesGet(
+    App& app, const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& systemName, const std::string& param)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+    if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+    {
+        // Option currently returns no systems.  TBD
+        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+                                   systemName);
+        return;
+    }
+
+    if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
+    {
+        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+                                   systemName);
+        return;
+    }
+
+    const std::string& targetID = param;
+
+    // Go through the log files and check the unique ID for each
+    // entry to find the target entry
+    std::vector<std::filesystem::path> redfishLogFiles;
+    getRedfishLogFiles(redfishLogFiles);
+    std::string logEntry;
+
+    // Oldest logs are in the last file, so start there and loop
+    // backwards
+    for (auto it = redfishLogFiles.rbegin(); it < redfishLogFiles.rend(); it++)
+    {
+        std::ifstream logStream(*it);
+        if (!logStream.is_open())
+        {
+            continue;
+        }
+
+        // Reset the unique ID on the first entry
+        bool firstEntry = true;
+        while (std::getline(logStream, logEntry))
+        {
+            std::string idStr;
+            if (!getUniqueEntryID(logEntry, idStr, firstEntry))
+            {
+                continue;
+            }
+            firstEntry = false;
+
+            if (idStr == targetID)
+            {
                 nlohmann::json::object_t bmcLogEntry;
                 LogParseError status = fillEventLogEntryJson(idStr, logEntry,
                                                              bmcLogEntry);
-                if (status == LogParseError::messageIdNotInRegistry)
-                {
-                    continue;
-                }
                 if (status != LogParseError::success)
                 {
                     messages::internalError(asyncResp->res);
                     return;
                 }
-
-                entryCount++;
-                // Handle paging using skip (number of entries to skip from the
-                // start) and top (number of entries to display)
-                if (entryCount <= skip || entryCount > skip + top)
-                {
-                    continue;
-                }
-
-                logEntryArray.emplace_back(std::move(bmcLogEntry));
+                asyncResp->res.jsonValue.update(bmcLogEntry);
+                return;
             }
         }
-        asyncResp->res.jsonValue["Members@odata.count"] = entryCount;
-        if (skip + top < entryCount)
-        {
-            asyncResp->res
-                .jsonValue["Members@odata.nextLink"] = boost::urls::format(
-                "/redfish/v1/Systems/{}/LogServices/EventLog/Entries?$skip={}",
-                BMCWEB_REDFISH_SYSTEM_URI_NAME, std::to_string(skip + top));
-        }
-    });
+    }
+    // Requested ID was not found
+    messages::resourceNotFound(asyncResp->res, "LogEntry", targetID);
 }
 
 inline void requestRoutesJournalEventLogEntry(App& app)
@@ -1514,76 +1594,180 @@
     BMCWEB_ROUTE(
         app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
         .privileges(redfish::privileges::getLogEntry)
-        .methods(boost::beast::http::verb::get)(
-            [&app](const crow::Request& req,
-                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                   const std::string& systemName, const std::string& param) {
-        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+        .methods(boost::beast::http::verb::get)(std::bind_front(
+            handleSystemsLogServiceEventLogEntriesGet, std::ref(app)));
+}
+
+inline void dBusEventLogEntryCollection(
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    // Collections don't include the static data added by SubRoute
+    // because it has a duplicate entry for members
+    asyncResp->res.jsonValue["@odata.type"] =
+        "#LogEntryCollection.LogEntryCollection";
+    asyncResp->res.jsonValue["@odata.id"] =
+        std::format("/redfish/v1/Systems/{}/LogServices/EventLog/Entries",
+                    BMCWEB_REDFISH_SYSTEM_URI_NAME);
+    asyncResp->res.jsonValue["Name"] = "System Event Log Entries";
+    asyncResp->res.jsonValue["Description"] =
+        "Collection of System Event Log Entries";
+
+    // DBus implementation of EventLog/Entries
+    // Make call to Logging Service to find all log entry objects
+    sdbusplus::message::object_path path("/xyz/openbmc_project/logging");
+    dbus::utility::getManagedObjects(
+        "xyz.openbmc_project.Logging", path,
+        [asyncResp](const boost::system::error_code& ec,
+                    const dbus::utility::ManagedObjectType& resp) {
+        if (ec)
         {
+            // TODO Handle for specific error code
+            BMCWEB_LOG_ERROR("getLogEntriesIfaceData resp_handler got error {}",
+                             ec);
+            messages::internalError(asyncResp->res);
             return;
         }
-        if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
+        nlohmann::json::array_t entriesArray;
+        for (const auto& objectPath : resp)
         {
-            // Option currently returns no systems.  TBD
-            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
-                                       systemName);
-            return;
-        }
+            const uint32_t* id = nullptr;
+            const uint64_t* timestamp = nullptr;
+            const uint64_t* updateTimestamp = nullptr;
+            const std::string* severity = nullptr;
+            const std::string* message = nullptr;
+            const std::string* filePath = nullptr;
+            const std::string* resolution = nullptr;
+            bool resolved = false;
+            const std::string* notify = nullptr;
 
-        if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
-        {
-            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
-                                       systemName);
-            return;
-        }
-
-        const std::string& targetID = param;
-
-        // Go through the log files and check the unique ID for each
-        // entry to find the target entry
-        std::vector<std::filesystem::path> redfishLogFiles;
-        getRedfishLogFiles(redfishLogFiles);
-        std::string logEntry;
-
-        // Oldest logs are in the last file, so start there and loop
-        // backwards
-        for (auto it = redfishLogFiles.rbegin(); it < redfishLogFiles.rend();
-             it++)
-        {
-            std::ifstream logStream(*it);
-            if (!logStream.is_open())
+            for (const auto& interfaceMap : objectPath.second)
             {
-                continue;
-            }
-
-            // Reset the unique ID on the first entry
-            bool firstEntry = true;
-            while (std::getline(logStream, logEntry))
-            {
-                std::string idStr;
-                if (!getUniqueEntryID(logEntry, idStr, firstEntry))
+                if (interfaceMap.first == "xyz.openbmc_project.Logging.Entry")
                 {
-                    continue;
-                }
-                firstEntry = false;
-
-                if (idStr == targetID)
-                {
-                    nlohmann::json::object_t bmcLogEntry;
-                    LogParseError status =
-                        fillEventLogEntryJson(idStr, logEntry, bmcLogEntry);
-                    if (status != LogParseError::success)
+                    for (const auto& propertyMap : interfaceMap.second)
+                    {
+                        if (propertyMap.first == "Id")
+                        {
+                            id = std::get_if<uint32_t>(&propertyMap.second);
+                        }
+                        else if (propertyMap.first == "Timestamp")
+                        {
+                            timestamp =
+                                std::get_if<uint64_t>(&propertyMap.second);
+                        }
+                        else if (propertyMap.first == "UpdateTimestamp")
+                        {
+                            updateTimestamp =
+                                std::get_if<uint64_t>(&propertyMap.second);
+                        }
+                        else if (propertyMap.first == "Severity")
+                        {
+                            severity =
+                                std::get_if<std::string>(&propertyMap.second);
+                        }
+                        else if (propertyMap.first == "Resolution")
+                        {
+                            resolution =
+                                std::get_if<std::string>(&propertyMap.second);
+                        }
+                        else if (propertyMap.first == "Message")
+                        {
+                            message =
+                                std::get_if<std::string>(&propertyMap.second);
+                        }
+                        else if (propertyMap.first == "Resolved")
+                        {
+                            const bool* resolveptr =
+                                std::get_if<bool>(&propertyMap.second);
+                            if (resolveptr == nullptr)
+                            {
+                                messages::internalError(asyncResp->res);
+                                return;
+                            }
+                            resolved = *resolveptr;
+                        }
+                        else if (propertyMap.first == "ServiceProviderNotify")
+                        {
+                            notify =
+                                std::get_if<std::string>(&propertyMap.second);
+                            if (notify == nullptr)
+                            {
+                                messages::internalError(asyncResp->res);
+                                return;
+                            }
+                        }
+                    }
+                    if (id == nullptr || message == nullptr ||
+                        severity == nullptr)
                     {
                         messages::internalError(asyncResp->res);
                         return;
                     }
-                    asyncResp->res.jsonValue.update(bmcLogEntry);
-                    return;
+                }
+                else if (interfaceMap.first ==
+                         "xyz.openbmc_project.Common.FilePath")
+                {
+                    for (const auto& propertyMap : interfaceMap.second)
+                    {
+                        if (propertyMap.first == "Path")
+                        {
+                            filePath =
+                                std::get_if<std::string>(&propertyMap.second);
+                        }
+                    }
                 }
             }
+            // Object path without the
+            // xyz.openbmc_project.Logging.Entry interface, ignore
+            // and continue.
+            if (id == nullptr || message == nullptr || severity == nullptr ||
+                timestamp == nullptr || updateTimestamp == nullptr)
+            {
+                continue;
+            }
+            nlohmann::json& thisEntry = entriesArray.emplace_back();
+            thisEntry["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
+            thisEntry["@odata.id"] = boost::urls::format(
+                "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/{}",
+                BMCWEB_REDFISH_SYSTEM_URI_NAME, std::to_string(*id));
+            thisEntry["Name"] = "System Event Log Entry";
+            thisEntry["Id"] = std::to_string(*id);
+            thisEntry["Message"] = *message;
+            thisEntry["Resolved"] = resolved;
+            if ((resolution != nullptr) && (!(*resolution).empty()))
+            {
+                thisEntry["Resolution"] = *resolution;
+            }
+            if (notify != nullptr)
+            {
+                std::optional<bool> notifyAction =
+                    getProviderNotifyAction(*notify);
+                if (notifyAction)
+                {
+                    thisEntry["ServiceProviderNotified"] = *notifyAction;
+                }
+            }
+            thisEntry["EntryType"] = "Event";
+            thisEntry["Severity"] = translateSeverityDbusToRedfish(*severity);
+            thisEntry["Created"] =
+                redfish::time_utils::getDateTimeUintMs(*timestamp);
+            thisEntry["Modified"] =
+                redfish::time_utils::getDateTimeUintMs(*updateTimestamp);
+            if (filePath != nullptr)
+            {
+                thisEntry["AdditionalDataURI"] =
+                    std::format(
+                        "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/",
+                        BMCWEB_REDFISH_SYSTEM_URI_NAME) +
+                    std::to_string(*id) + "/attachment";
+            }
         }
-        // Requested ID was not found
-        messages::resourceNotFound(asyncResp->res, "LogEntry", targetID);
+        std::ranges::sort(entriesArray, [](const nlohmann::json& left,
+                                           const nlohmann::json& right) {
+            return (left["Id"] <= right["Id"]);
+        });
+        asyncResp->res.jsonValue["Members@odata.count"] = entriesArray.size();
+        asyncResp->res.jsonValue["Members"] = std::move(entriesArray);
     });
 }
 
@@ -1612,181 +1796,155 @@
                                        systemName);
             return;
         }
+        dBusEventLogEntryCollection(asyncResp);
+    });
+}
 
-        // Collections don't include the static data added by SubRoute
-        // because it has a duplicate entry for members
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#LogEntryCollection.LogEntryCollection";
-        asyncResp->res.jsonValue["@odata.id"] =
-            std::format("/redfish/v1/Systems/{}/LogServices/EventLog/Entries",
-                        BMCWEB_REDFISH_SYSTEM_URI_NAME);
-        asyncResp->res.jsonValue["Name"] = "System Event Log Entries";
-        asyncResp->res.jsonValue["Description"] =
-            "Collection of System Event Log Entries";
+inline void
+    dBusEventLogEntryGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                         std::string& entryID)
+{
+    dbus::utility::escapePathForDbus(entryID);
 
-        // DBus implementation of EventLog/Entries
-        // Make call to Logging Service to find all log entry objects
-        sdbusplus::message::object_path path("/xyz/openbmc_project/logging");
-        dbus::utility::getManagedObjects(
-            "xyz.openbmc_project.Logging", path,
-            [asyncResp](const boost::system::error_code& ec,
-                        const dbus::utility::ManagedObjectType& resp) {
-            if (ec)
+    // DBus implementation of EventLog/Entries
+    // Make call to Logging Service to find all log entry objects
+    sdbusplus::asio::getAllProperties(
+        *crow::connections::systemBus, "xyz.openbmc_project.Logging",
+        "/xyz/openbmc_project/logging/entry/" + entryID, "",
+        [asyncResp, entryID](const boost::system::error_code& ec,
+                             const dbus::utility::DBusPropertiesMap& resp) {
+        if (ec.value() == EBADR)
+        {
+            messages::resourceNotFound(asyncResp->res, "EventLogEntry",
+                                       entryID);
+            return;
+        }
+        if (ec)
+        {
+            BMCWEB_LOG_ERROR("EventLogEntry (DBus) resp_handler got error {}",
+                             ec);
+            messages::internalError(asyncResp->res);
+            return;
+        }
+        const uint32_t* id = nullptr;
+        const uint64_t* timestamp = nullptr;
+        const uint64_t* updateTimestamp = nullptr;
+        const std::string* severity = nullptr;
+        const std::string* message = nullptr;
+        const std::string* filePath = nullptr;
+        const std::string* resolution = nullptr;
+        bool resolved = false;
+        const std::string* notify = nullptr;
+
+        const bool success = sdbusplus::unpackPropertiesNoThrow(
+            dbus_utils::UnpackErrorPrinter(), resp, "Id", id, "Timestamp",
+            timestamp, "UpdateTimestamp", updateTimestamp, "Severity", severity,
+            "Message", message, "Resolved", resolved, "Resolution", resolution,
+            "Path", filePath, "ServiceProviderNotify", notify);
+
+        if (!success)
+        {
+            messages::internalError(asyncResp->res);
+            return;
+        }
+
+        if (id == nullptr || message == nullptr || severity == nullptr ||
+            timestamp == nullptr || updateTimestamp == nullptr ||
+            notify == nullptr)
+        {
+            messages::internalError(asyncResp->res);
+            return;
+        }
+
+        asyncResp->res.jsonValue["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
+        asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
+            "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/{}",
+            BMCWEB_REDFISH_SYSTEM_URI_NAME, std::to_string(*id));
+        asyncResp->res.jsonValue["Name"] = "System Event Log Entry";
+        asyncResp->res.jsonValue["Id"] = std::to_string(*id);
+        asyncResp->res.jsonValue["Message"] = *message;
+        asyncResp->res.jsonValue["Resolved"] = resolved;
+        std::optional<bool> notifyAction = getProviderNotifyAction(*notify);
+        if (notifyAction)
+        {
+            asyncResp->res.jsonValue["ServiceProviderNotified"] = *notifyAction;
+        }
+        if ((resolution != nullptr) && (!(*resolution).empty()))
+        {
+            asyncResp->res.jsonValue["Resolution"] = *resolution;
+        }
+        asyncResp->res.jsonValue["EntryType"] = "Event";
+        asyncResp->res.jsonValue["Severity"] =
+            translateSeverityDbusToRedfish(*severity);
+        asyncResp->res.jsonValue["Created"] =
+            redfish::time_utils::getDateTimeUintMs(*timestamp);
+        asyncResp->res.jsonValue["Modified"] =
+            redfish::time_utils::getDateTimeUintMs(*updateTimestamp);
+        if (filePath != nullptr)
+        {
+            asyncResp->res.jsonValue["AdditionalDataURI"] =
+                std::format(
+                    "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/",
+                    BMCWEB_REDFISH_SYSTEM_URI_NAME) +
+                std::to_string(*id) + "/attachment";
+        }
+    });
+}
+
+inline void
+    dBusEventLogEntryPatch(const crow::Request& req,
+                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                           const std::string& entryId)
+{
+    std::optional<bool> resolved;
+
+    if (!json_util::readJsonPatch(req, asyncResp->res, "Resolved", resolved))
+    {
+        return;
+    }
+    BMCWEB_LOG_DEBUG("Set Resolved");
+
+    setDbusProperty(asyncResp, "Resolved", "xyz.openbmc_project.Logging",
+                    "/xyz/openbmc_project/logging/entry/" + entryId,
+                    "xyz.openbmc_project.Logging.Entry", "Resolved",
+                    resolved.value_or(false));
+}
+
+inline void
+    dBusEventLogEntryDelete(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                            std::string entryID)
+{
+    BMCWEB_LOG_DEBUG("Do delete single event entries.");
+
+    dbus::utility::escapePathForDbus(entryID);
+
+    // Process response from Logging service.
+    auto respHandler = [asyncResp,
+                        entryID](const boost::system::error_code& ec) {
+        BMCWEB_LOG_DEBUG("EventLogEntry (DBus) doDelete callback: Done");
+        if (ec)
+        {
+            if (ec.value() == EBADR)
             {
-                // TODO Handle for specific error code
-                BMCWEB_LOG_ERROR(
-                    "getLogEntriesIfaceData resp_handler got error {}", ec);
-                messages::internalError(asyncResp->res);
+                messages::resourceNotFound(asyncResp->res, "LogEntry", entryID);
                 return;
             }
-            nlohmann::json::array_t entriesArray;
-            for (const auto& objectPath : resp)
-            {
-                const uint32_t* id = nullptr;
-                const uint64_t* timestamp = nullptr;
-                const uint64_t* updateTimestamp = nullptr;
-                const std::string* severity = nullptr;
-                const std::string* message = nullptr;
-                const std::string* filePath = nullptr;
-                const std::string* resolution = nullptr;
-                bool resolved = false;
-                const std::string* notify = nullptr;
+            // TODO Handle for specific error code
+            BMCWEB_LOG_ERROR(
+                "EventLogEntry (DBus) doDelete respHandler got error {}", ec);
+            asyncResp->res.result(
+                boost::beast::http::status::internal_server_error);
+            return;
+        }
 
-                for (const auto& interfaceMap : objectPath.second)
-                {
-                    if (interfaceMap.first ==
-                        "xyz.openbmc_project.Logging.Entry")
-                    {
-                        for (const auto& propertyMap : interfaceMap.second)
-                        {
-                            if (propertyMap.first == "Id")
-                            {
-                                id = std::get_if<uint32_t>(&propertyMap.second);
-                            }
-                            else if (propertyMap.first == "Timestamp")
-                            {
-                                timestamp =
-                                    std::get_if<uint64_t>(&propertyMap.second);
-                            }
-                            else if (propertyMap.first == "UpdateTimestamp")
-                            {
-                                updateTimestamp =
-                                    std::get_if<uint64_t>(&propertyMap.second);
-                            }
-                            else if (propertyMap.first == "Severity")
-                            {
-                                severity = std::get_if<std::string>(
-                                    &propertyMap.second);
-                            }
-                            else if (propertyMap.first == "Resolution")
-                            {
-                                resolution = std::get_if<std::string>(
-                                    &propertyMap.second);
-                            }
-                            else if (propertyMap.first == "Message")
-                            {
-                                message = std::get_if<std::string>(
-                                    &propertyMap.second);
-                            }
-                            else if (propertyMap.first == "Resolved")
-                            {
-                                const bool* resolveptr =
-                                    std::get_if<bool>(&propertyMap.second);
-                                if (resolveptr == nullptr)
-                                {
-                                    messages::internalError(asyncResp->res);
-                                    return;
-                                }
-                                resolved = *resolveptr;
-                            }
-                            else if (propertyMap.first ==
-                                     "ServiceProviderNotify")
-                            {
-                                notify = std::get_if<std::string>(
-                                    &propertyMap.second);
-                                if (notify == nullptr)
-                                {
-                                    messages::internalError(asyncResp->res);
-                                    return;
-                                }
-                            }
-                        }
-                        if (id == nullptr || message == nullptr ||
-                            severity == nullptr)
-                        {
-                            messages::internalError(asyncResp->res);
-                            return;
-                        }
-                    }
-                    else if (interfaceMap.first ==
-                             "xyz.openbmc_project.Common.FilePath")
-                    {
-                        for (const auto& propertyMap : interfaceMap.second)
-                        {
-                            if (propertyMap.first == "Path")
-                            {
-                                filePath = std::get_if<std::string>(
-                                    &propertyMap.second);
-                            }
-                        }
-                    }
-                }
-                // Object path without the
-                // xyz.openbmc_project.Logging.Entry interface, ignore
-                // and continue.
-                if (id == nullptr || message == nullptr ||
-                    severity == nullptr || timestamp == nullptr ||
-                    updateTimestamp == nullptr)
-                {
-                    continue;
-                }
-                nlohmann::json& thisEntry = entriesArray.emplace_back();
-                thisEntry["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
-                thisEntry["@odata.id"] = boost::urls::format(
-                    "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/{}",
-                    BMCWEB_REDFISH_SYSTEM_URI_NAME, std::to_string(*id));
-                thisEntry["Name"] = "System Event Log Entry";
-                thisEntry["Id"] = std::to_string(*id);
-                thisEntry["Message"] = *message;
-                thisEntry["Resolved"] = resolved;
-                if ((resolution != nullptr) && (!(*resolution).empty()))
-                {
-                    thisEntry["Resolution"] = *resolution;
-                }
-                if (notify != nullptr)
-                {
-                    std::optional<bool> notifyAction =
-                        getProviderNotifyAction(*notify);
-                    if (notifyAction)
-                    {
-                        thisEntry["ServiceProviderNotified"] = *notifyAction;
-                    }
-                }
-                thisEntry["EntryType"] = "Event";
-                thisEntry["Severity"] =
-                    translateSeverityDbusToRedfish(*severity);
-                thisEntry["Created"] =
-                    redfish::time_utils::getDateTimeUintMs(*timestamp);
-                thisEntry["Modified"] =
-                    redfish::time_utils::getDateTimeUintMs(*updateTimestamp);
-                if (filePath != nullptr)
-                {
-                    thisEntry["AdditionalDataURI"] =
-                        std::format(
-                            "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/",
-                            BMCWEB_REDFISH_SYSTEM_URI_NAME) +
-                        std::to_string(*id) + "/attachment";
-                }
-            }
-            std::ranges::sort(entriesArray, [](const nlohmann::json& left,
-                                               const nlohmann::json& right) {
-                return (left["Id"] <= right["Id"]);
-            });
-            asyncResp->res.jsonValue["Members@odata.count"] =
-                entriesArray.size();
-            asyncResp->res.jsonValue["Members"] = std::move(entriesArray);
-        });
-    });
+        asyncResp->res.result(boost::beast::http::status::ok);
+    };
+
+    // Make call to Logging service to request Delete Log
+    crow::connections::systemBus->async_method_call(
+        respHandler, "xyz.openbmc_project.Logging",
+        "/xyz/openbmc_project/logging/entry/" + entryID,
+        "xyz.openbmc_project.Object.Delete", "Delete");
 }
 
 inline void requestRoutesDBusEventLogEntry(App& app)
@@ -1817,94 +1975,8 @@
         }
 
         std::string entryID = param;
-        dbus::utility::escapePathForDbus(entryID);
 
-        // DBus implementation of EventLog/Entries
-        // Make call to Logging Service to find all log entry objects
-        sdbusplus::asio::getAllProperties(
-            *crow::connections::systemBus, "xyz.openbmc_project.Logging",
-            "/xyz/openbmc_project/logging/entry/" + entryID, "",
-            [asyncResp, entryID](const boost::system::error_code& ec,
-                                 const dbus::utility::DBusPropertiesMap& resp) {
-            if (ec.value() == EBADR)
-            {
-                messages::resourceNotFound(asyncResp->res, "EventLogEntry",
-                                           entryID);
-                return;
-            }
-            if (ec)
-            {
-                BMCWEB_LOG_ERROR(
-                    "EventLogEntry (DBus) resp_handler got error {}", ec);
-                messages::internalError(asyncResp->res);
-                return;
-            }
-            const uint32_t* id = nullptr;
-            const uint64_t* timestamp = nullptr;
-            const uint64_t* updateTimestamp = nullptr;
-            const std::string* severity = nullptr;
-            const std::string* message = nullptr;
-            const std::string* filePath = nullptr;
-            const std::string* resolution = nullptr;
-            bool resolved = false;
-            const std::string* notify = nullptr;
-
-            const bool success = sdbusplus::unpackPropertiesNoThrow(
-                dbus_utils::UnpackErrorPrinter(), resp, "Id", id, "Timestamp",
-                timestamp, "UpdateTimestamp", updateTimestamp, "Severity",
-                severity, "Message", message, "Resolved", resolved,
-                "Resolution", resolution, "Path", filePath,
-                "ServiceProviderNotify", notify);
-
-            if (!success)
-            {
-                messages::internalError(asyncResp->res);
-                return;
-            }
-
-            if (id == nullptr || message == nullptr || severity == nullptr ||
-                timestamp == nullptr || updateTimestamp == nullptr ||
-                notify == nullptr)
-            {
-                messages::internalError(asyncResp->res);
-                return;
-            }
-
-            asyncResp->res.jsonValue["@odata.type"] =
-                "#LogEntry.v1_9_0.LogEntry";
-            asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
-                "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/{}",
-                BMCWEB_REDFISH_SYSTEM_URI_NAME, std::to_string(*id));
-            asyncResp->res.jsonValue["Name"] = "System Event Log Entry";
-            asyncResp->res.jsonValue["Id"] = std::to_string(*id);
-            asyncResp->res.jsonValue["Message"] = *message;
-            asyncResp->res.jsonValue["Resolved"] = resolved;
-            std::optional<bool> notifyAction = getProviderNotifyAction(*notify);
-            if (notifyAction)
-            {
-                asyncResp->res.jsonValue["ServiceProviderNotified"] =
-                    *notifyAction;
-            }
-            if ((resolution != nullptr) && (!(*resolution).empty()))
-            {
-                asyncResp->res.jsonValue["Resolution"] = *resolution;
-            }
-            asyncResp->res.jsonValue["EntryType"] = "Event";
-            asyncResp->res.jsonValue["Severity"] =
-                translateSeverityDbusToRedfish(*severity);
-            asyncResp->res.jsonValue["Created"] =
-                redfish::time_utils::getDateTimeUintMs(*timestamp);
-            asyncResp->res.jsonValue["Modified"] =
-                redfish::time_utils::getDateTimeUintMs(*updateTimestamp);
-            if (filePath != nullptr)
-            {
-                asyncResp->res.jsonValue["AdditionalDataURI"] =
-                    std::format(
-                        "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/",
-                        BMCWEB_REDFISH_SYSTEM_URI_NAME) +
-                    std::to_string(*id) + "/attachment";
-            }
-        });
+        dBusEventLogEntryGet(asyncResp, entryID);
     });
 
     BMCWEB_ROUTE(
@@ -1931,19 +2003,8 @@
                                        systemName);
             return;
         }
-        std::optional<bool> resolved;
 
-        if (!json_util::readJsonPatch(req, asyncResp->res, "Resolved",
-                                      resolved))
-        {
-            return;
-        }
-        BMCWEB_LOG_DEBUG("Set Resolved");
-
-        setDbusProperty(asyncResp, "Resolved", "xyz.openbmc_project.Logging",
-                        "/xyz/openbmc_project/logging/entry/" + entryId,
-                        "xyz.openbmc_project.Logging.Entry", "Resolved",
-                        *resolved);
+        dBusEventLogEntryPatch(req, asyncResp, entryId);
     });
 
     BMCWEB_ROUTE(
@@ -1971,41 +2032,7 @@
                                        systemName);
             return;
         }
-        BMCWEB_LOG_DEBUG("Do delete single event entries.");
-
-        std::string entryID = param;
-
-        dbus::utility::escapePathForDbus(entryID);
-
-        // Process response from Logging service.
-        auto respHandler = [asyncResp,
-                            entryID](const boost::system::error_code& ec) {
-            BMCWEB_LOG_DEBUG("EventLogEntry (DBus) doDelete callback: Done");
-            if (ec)
-            {
-                if (ec.value() == EBADR)
-                {
-                    messages::resourceNotFound(asyncResp->res, "LogEntry",
-                                               entryID);
-                    return;
-                }
-                // TODO Handle for specific error code
-                BMCWEB_LOG_ERROR(
-                    "EventLogEntry (DBus) doDelete respHandler got error {}",
-                    ec);
-                asyncResp->res.result(
-                    boost::beast::http::status::internal_server_error);
-                return;
-            }
-
-            asyncResp->res.result(boost::beast::http::status::ok);
-        };
-
-        // Make call to Logging service to request Delete Log
-        crow::connections::systemBus->async_method_call(
-            respHandler, "xyz.openbmc_project.Logging",
-            "/xyz/openbmc_project/logging/entry/" + entryID,
-            "xyz.openbmc_project.Object.Delete", "Delete");
+        dBusEventLogEntryDelete(asyncResp, param);
     });
 }
 
@@ -3434,6 +3461,33 @@
     });
 }
 
+inline void dBusLogServiceActionsClear(
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    BMCWEB_LOG_DEBUG("Do delete all entries.");
+
+    // Process response from Logging service.
+    auto respHandler = [asyncResp](const boost::system::error_code& ec) {
+        BMCWEB_LOG_DEBUG("doClearLog resp_handler callback: Done");
+        if (ec)
+        {
+            // TODO Handle for specific error code
+            BMCWEB_LOG_ERROR("doClearLog resp_handler got error {}", ec);
+            asyncResp->res.result(
+                boost::beast::http::status::internal_server_error);
+            return;
+        }
+
+        asyncResp->res.result(boost::beast::http::status::no_content);
+    };
+
+    // Make call to Logging service to request Clear Log
+    crow::connections::systemBus->async_method_call(
+        respHandler, "xyz.openbmc_project.Logging",
+        "/xyz/openbmc_project/logging",
+        "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
+}
+
 /**
  * DBusLogServiceActionsClear class supports POST method for ClearLog action.
  */
@@ -3470,28 +3524,7 @@
                                        systemName);
             return;
         }
-        BMCWEB_LOG_DEBUG("Do delete all entries.");
-
-        // Process response from Logging service.
-        auto respHandler = [asyncResp](const boost::system::error_code& ec) {
-            BMCWEB_LOG_DEBUG("doClearLog resp_handler callback: Done");
-            if (ec)
-            {
-                // TODO Handle for specific error code
-                BMCWEB_LOG_ERROR("doClearLog resp_handler got error {}", ec);
-                asyncResp->res.result(
-                    boost::beast::http::status::internal_server_error);
-                return;
-            }
-
-            asyncResp->res.result(boost::beast::http::status::no_content);
-        };
-
-        // Make call to Logging service to request Clear Log
-        crow::connections::systemBus->async_method_call(
-            respHandler, "xyz.openbmc_project.Logging",
-            "/xyz/openbmc_project/logging",
-            "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
+        dBusLogServiceActionsClear(asyncResp);
     });
 }
 
