diff --git a/redfish-core/include/gzfile.hpp b/redfish-core/include/gzfile.hpp
new file mode 100644
index 0000000..9f1b5db
--- /dev/null
+++ b/redfish-core/include/gzfile.hpp
@@ -0,0 +1,178 @@
+#pragma once
+
+#include <zlib.h>
+
+#include <array>
+#include <filesystem>
+#include <vector>
+
+class GzFileReader
+{
+  public:
+    bool gzGetLines(std::vector<std::string>& logEntries,
+                    const std::string& filename)
+    {
+        gzFile logStream = gzopen(filename.c_str(), "r");
+        if (!logStream)
+        {
+            BMCWEB_LOG_ERROR << "Can't open gz file: " << filename << '\n';
+            return false;
+        }
+
+        std::string wholeFile;
+        if (!readFile(wholeFile, logStream))
+        {
+            gzclose(logStream);
+            return false;
+        }
+        std::string newLastMessage;
+        std::vector<std::string> parseLogs =
+            hostLogEntryParser(wholeFile, newLastMessage);
+
+        // If file doesn't contain any "\r" or "\n", parseLogs should be empty.
+        if (parseLogs.empty())
+        {
+            lastMessage.insert(lastMessage.end(),
+                               std::make_move_iterator(newLastMessage.begin()),
+                               std::make_move_iterator(newLastMessage.end()));
+        }
+        else
+        {
+            if (!lastMessage.empty())
+            {
+                parseLogs.front() = lastMessage + parseLogs.front();
+                lastMessage.clear();
+            }
+            if (!newLastMessage.empty())
+            {
+                lastMessage = std::move(newLastMessage);
+            }
+            logEntries.insert(logEntries.end(),
+                              std::make_move_iterator(parseLogs.begin()),
+                              std::make_move_iterator(parseLogs.end()));
+        }
+        gzclose(logStream);
+        return true;
+    }
+
+    std::string getLastMessage()
+    {
+        return lastMessage;
+    }
+
+  private:
+    std::string lastMessage;
+    std::string lastDelimiter;
+    size_t totalFilesSize = 0;
+
+    void printErrorMessage(gzFile logStream)
+    {
+        int errNum = 0;
+        const char* errMsg = gzerror(logStream, &errNum);
+
+        BMCWEB_LOG_ERROR << "Error reading gz compressed data.\n"
+                         << "Error Message: " << errMsg << '\n'
+                         << "Error Number: " << errNum;
+    }
+
+    bool readFile(std::string& wholeFile, gzFile logStream)
+    {
+        // Assume we have 8 files, and the max size of each file is
+        // 16k, so define the max size as 256kb (double of 8 files *
+        // 16kb)
+        constexpr size_t maxTotalFilesSize = 262144;
+        constexpr int bufferLimitSize = 1024;
+        do
+        {
+            std::string bufferStr;
+            bufferStr.resize(bufferLimitSize);
+
+            int bytesRead = gzread(logStream, bufferStr.data(),
+                                   static_cast<unsigned int>(bufferStr.size()));
+            // On errors, gzread() shall return a value less than 0.
+            if (bytesRead < 0)
+            {
+                printErrorMessage(logStream);
+                return false;
+            }
+            bufferStr.resize(static_cast<size_t>(bytesRead));
+            totalFilesSize += bufferStr.size();
+            if (totalFilesSize > maxTotalFilesSize)
+            {
+                BMCWEB_LOG_ERROR << "File size exceeds maximum allowed size of "
+                                 << maxTotalFilesSize;
+                return false;
+            }
+            wholeFile.insert(wholeFile.end(),
+                             std::make_move_iterator(bufferStr.begin()),
+                             std::make_move_iterator(bufferStr.end()));
+        } while (!gzeof(logStream));
+
+        return true;
+    }
+
+    std::vector<std::string> hostLogEntryParser(const std::string& wholeFile,
+                                                std::string& newLastMessage)
+    {
+        std::vector<std::string> logEntries;
+
+        // It may contain several log entry in one line, and
+        // the end of each log entry will be '\r\n' or '\r'.
+        // So we need to go through and split string by '\n' and '\r'
+        size_t pos = wholeFile.find_first_of("\n\r");
+        size_t initialPos = 0;
+
+        while (pos != std::string::npos)
+        {
+            std::string logEntry =
+                wholeFile.substr(initialPos, pos - initialPos);
+            // Since there might be consecutive delimiters like "\r\n", we need
+            // to filter empty strings.
+            if (!logEntry.empty())
+            {
+                logEntries.push_back(logEntry);
+            }
+            else
+            {
+                // Handle consecutive delimiter. '\r\n' act as a single
+                // delimiter, the other case like '\n\n', '\n\r' or '\r\r' will
+                // push back a "\n" as a log.
+                std::string delimiters;
+                if (pos > 0)
+                {
+                    delimiters = wholeFile.substr(pos - 1, 2);
+                }
+                // Handle consecutive delimiter but spilt between two files.
+                if (pos == 0 && !(lastDelimiter.empty()))
+                {
+                    delimiters = lastDelimiter + wholeFile.substr(0, 1);
+                }
+                if (delimiters != "\r\n")
+                {
+                    logEntries.emplace_back("\n");
+                }
+            }
+            initialPos = pos + 1;
+            pos = wholeFile.find_first_of("\n\r", initialPos);
+        }
+
+        // Store the last message
+        if (initialPos < wholeFile.size())
+        {
+            newLastMessage = wholeFile.substr(initialPos);
+        }
+        // If consecutive delimiter spilt by file, the last character of the
+        // file must be the delimiter.
+        else if (initialPos == wholeFile.size())
+        {
+            lastDelimiter = wholeFile.substr(initialPos - 1, 1);
+        }
+        return logEntries;
+    }
+
+  public:
+    GzFileReader() = default;
+    ~GzFileReader() = default;
+    GzFileReader(const GzFileReader&) = delete;
+    GzFileReader& operator=(const GzFileReader&) = delete;
+};
diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp
index 0a97150..2479332 100644
--- a/redfish-core/include/redfish.hpp
+++ b/redfish-core/include/redfish.hpp
@@ -161,6 +161,12 @@
         requestRoutesDBusEventLogEntryDownload(app);
 #endif
 
+#ifdef BMCWEB_ENABLE_REDFISH_HOST_LOGGER
+        requestRoutesSystemHostLogger(app);
+        requestRoutesSystemHostLoggerCollection(app);
+        requestRoutesSystemHostLoggerLogEntry(app);
+#endif
+
         requestRoutesMessageRegistryFileCollection(app);
         requestRoutesMessageRegistryFile(app);
         requestRoutesMessageRegistry(app);
diff --git a/redfish-core/lib/log_services.hpp b/redfish-core/lib/log_services.hpp
index 2c9ae3a..065a4d1 100644
--- a/redfish-core/lib/log_services.hpp
+++ b/redfish-core/lib/log_services.hpp
@@ -15,7 +15,9 @@
 */
 #pragma once
 
+#include "gzfile.hpp"
 #include "http_utility.hpp"
+#include "human_sort.hpp"
 #include "registries.hpp"
 #include "registries/base_message_registry.hpp"
 #include "registries/openbmc_message_registry.hpp"
@@ -975,6 +977,12 @@
                     {{"@odata.id",
                       "/redfish/v1/Systems/system/LogServices/Crashdump"}});
 #endif
+
+#ifdef BMCWEB_ENABLE_REDFISH_HOST_LOGGER
+                logServiceArray.push_back(
+                    {{"@odata.id",
+                      "/redfish/v1/Systems/system/LogServices/HostLogger"}});
+#endif
                 asyncResp->res.jsonValue["Members@odata.count"] =
                     logServiceArray.size();
 
@@ -1817,6 +1825,221 @@
             });
 }
 
+constexpr const char* hostLoggerFolderPath = "/var/log/console";
+inline bool
+    getHostLoggerFiles(const std::string& hostLoggerFilePath,
+                       std::vector<std::filesystem::path>& hostLoggerFiles)
+{
+    std::error_code ec;
+    std::filesystem::directory_iterator logPath(hostLoggerFilePath, ec);
+    if (ec)
+    {
+        BMCWEB_LOG_ERROR << ec.message();
+        return false;
+    }
+    for (const std::filesystem::directory_entry& it : logPath)
+    {
+        std::string filename = it.path().filename();
+        // Prefix of each log files is "log". Find the file and save the
+        // path
+        if (boost::starts_with(filename, "log"))
+        {
+            hostLoggerFiles.emplace_back(it.path());
+        }
+    }
+    // As the log files rotate, they are appended with a ".#" that is higher for
+    // the older logs. Since we start from oldest logs, sort the name in
+    // descending order.
+    std::sort(hostLoggerFiles.rbegin(), hostLoggerFiles.rend(),
+              AlphanumLess<std::string>());
+
+    return true;
+}
+
+inline bool
+    getHostLoggerEntries(std::vector<std::filesystem::path>& hostLoggerFiles,
+                         std::vector<std::string>& logEntries)
+{
+    GzFileReader logFile;
+
+    // Go though all log files and expose host log into logEntries
+    for (const std::filesystem::path& it : hostLoggerFiles)
+    {
+        if (!logFile.gzGetLines(logEntries, it.string()))
+        {
+            BMCWEB_LOG_ERROR << "fail to expose host logs";
+            return false;
+        }
+    }
+    // Get lastMessage from constructor by getter
+    std::string lastMessage = logFile.getLastMessage();
+    if (!lastMessage.empty())
+    {
+        logEntries.push_back(lastMessage);
+    }
+    return true;
+}
+
+inline void fillHostLoggerEntryJson(const std::string& logEntryID,
+                                    const std::string& msg,
+                                    nlohmann::json& logEntryJson)
+{
+    // Fill in the log entry with the gathered data.
+    logEntryJson = {
+        {"@odata.type", "#LogEntry.v1_4_0.LogEntry"},
+        {"@odata.id",
+         "/redfish/v1/Systems/system/LogServices/HostLogger/Entries/" +
+             logEntryID},
+        {"Name", "Host Logger Entry"},
+        {"Id", logEntryID},
+        {"Message", msg},
+        {"EntryType", "Oem"},
+        {"Severity", "OK"},
+        {"OemRecordFormat", "Host Logger Entry"}};
+}
+
+inline void requestRoutesSystemHostLogger(App& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/LogServices/HostLogger/")
+        .privileges(redfish::privileges::getLogService)
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/Systems/system/LogServices/HostLogger";
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#LogService.v1_1_0.LogService";
+                asyncResp->res.jsonValue["Name"] = "Host Logger Service";
+                asyncResp->res.jsonValue["Description"] = "Host Logger Service";
+                asyncResp->res.jsonValue["Id"] = "HostLogger";
+                asyncResp->res.jsonValue["Entries"] = {
+                    {"@odata.id", "/redfish/v1/Systems/system/LogServices/"
+                                  "HostLogger/Entries"}};
+            });
+}
+
+inline void requestRoutesSystemHostLoggerCollection(App& app)
+{
+    BMCWEB_ROUTE(app,
+                 "/redfish/v1/Systems/system/LogServices/HostLogger/Entries/")
+        .privileges(redfish::privileges::getLogEntry)
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request& req,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                uint64_t skip = 0;
+                uint64_t top = maxEntriesPerPage; // Show max 1000 entries by
+                                                  // default, allow range 1 to
+                                                  // 1000 entries per page.
+                if (!getSkipParam(asyncResp, req, skip))
+                {
+                    return;
+                }
+                if (!getTopParam(asyncResp, req, top))
+                {
+                    return;
+                }
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/Systems/system/LogServices/HostLogger/Entries";
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#LogEntryCollection.LogEntryCollection";
+                asyncResp->res.jsonValue["Name"] = "HostLogger Entries";
+                asyncResp->res.jsonValue["Description"] =
+                    "Collection of HostLogger Entries";
+                nlohmann::json& logEntryArray =
+                    asyncResp->res.jsonValue["Members"];
+                logEntryArray = nlohmann::json::array();
+
+                std::vector<std::filesystem::path> hostLoggerFiles;
+                if (!getHostLoggerFiles(hostLoggerFolderPath, hostLoggerFiles))
+                {
+                    BMCWEB_LOG_ERROR << "fail to get host log file path";
+                    messages::internalError(asyncResp->res);
+                    return;
+                }
+
+                std::vector<std::string> logEntries;
+                if (!getHostLoggerEntries(hostLoggerFiles, logEntries))
+                {
+                    messages::internalError(asyncResp->res);
+                    return;
+                }
+
+                for (uint64_t id = skip;
+                     id < std::min<uint64_t>(skip + top, logEntries.size());
+                     id++)
+                {
+                    logEntryArray.push_back({});
+                    nlohmann::json& hostLogEntry = logEntryArray.back();
+                    fillHostLoggerEntryJson(std::to_string(id),
+                                            logEntries[static_cast<size_t>(id)],
+                                            hostLogEntry);
+                }
+
+                asyncResp->res.jsonValue["Members@odata.count"] =
+                    logEntries.size();
+                if (skip + top < logEntries.size())
+                {
+                    asyncResp->res.jsonValue["Members@odata.nextLink"] =
+                        "/redfish/v1/Systems/system/LogServices/HostLogger/"
+                        "Entries?skip=" +
+                        std::to_string(skip + top);
+                }
+            });
+}
+
+inline void requestRoutesSystemHostLoggerLogEntry(App& app)
+{
+    BMCWEB_ROUTE(
+        app, "/redfish/v1/Systems/system/LogServices/HostLogger/Entries/<str>/")
+        .privileges(redfish::privileges::getLogEntry)
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+               const std::string& param) {
+                const std::string& targetID = param;
+
+                std::vector<std::filesystem::path> hostLoggerFiles;
+                if (!getHostLoggerFiles(hostLoggerFolderPath, hostLoggerFiles))
+                {
+                    BMCWEB_LOG_ERROR << "fail to get host log file path";
+                    messages::internalError(asyncResp->res);
+                    return;
+                }
+
+                std::vector<std::string> logEntries;
+                if (!getHostLoggerEntries(hostLoggerFiles, logEntries))
+                {
+                    messages::internalError(asyncResp->res);
+                    return;
+                }
+
+                uint64_t idInt = 0;
+                auto [ptr, ec] = std::from_chars(
+                    targetID.data(), targetID.data() + targetID.size(), idInt);
+                if (ec == std::errc::invalid_argument)
+                {
+                    messages::resourceMissingAtURI(asyncResp->res, targetID);
+                    return;
+                }
+                if (ec == std::errc::result_out_of_range)
+                {
+                    messages::resourceMissingAtURI(asyncResp->res, targetID);
+                    return;
+                }
+
+                if (idInt < logEntries.size())
+                {
+                    fillHostLoggerEntryJson(
+                        targetID, logEntries[static_cast<size_t>(idInt)],
+                        asyncResp->res.jsonValue);
+                    return;
+                }
+
+                // Requested ID was not found
+                messages::resourceMissingAtURI(asyncResp->res, targetID);
+            });
+}
+
 inline void requestRoutesBMCLogServiceCollection(App& app)
 {
     BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/LogServices/")
