diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp
index 54bc503..553fc5f 100644
--- a/redfish-core/include/event_service_manager.hpp
+++ b/redfish-core/include/event_service_manager.hpp
@@ -15,6 +15,11 @@
 */
 #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/container/flat_map.hpp>
 #include <cstdlib>
@@ -27,6 +32,224 @@
 
 namespace redfish
 {
+#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;
+}
+#endif
+
+} // namespace event_log
+
 class Subscription
 {
   public:
@@ -98,6 +321,72 @@
         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
+
   private:
     uint64_t eventSeqNum;
     std::string host;
@@ -124,6 +413,7 @@
         retryTimeoutInterval = 30; // seconds
     }
 
+    std::string lastEventTStr;
     boost::container::flat_map<std::string, std::shared_ptr<Subscription>>
         subscriptionsMap;
 
@@ -182,6 +472,13 @@
         }
 
         updateSubscriptionData();
+
+#ifndef BMCWEB_ENABLE_REDFISH_DBUS_LOG_ENTRIES
+        if (lastEventTStr.empty())
+        {
+            cacheLastEventTimestamp();
+        }
+#endif
         return id;
     }
 
@@ -242,6 +539,166 @@
             entry->sendTestEventLog();
         }
     }
+
+#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 (!getNumberOfSubscriptions())
+        {
+            // no subscriptions. Just return.
+            BMCWEB_LOG_DEBUG << "No Subscriptions\n";
+            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_service& 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
 };
 
 } // namespace redfish
diff --git a/src/webserver_main.cpp b/src/webserver_main.cpp
index 4bdf880..2763991 100644
--- a/src/webserver_main.cpp
+++ b/src/webserver_main.cpp
@@ -115,6 +115,15 @@
 
     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();
 
