Revert "Redfish: Support Host Log Entries"

This commit appears to cause 500 errors on systems that don't have
host-logger installed.  Reverting for now to get the codebase back to
stable;  To the author, please fix the error and resubmit.

The bump that failed is here:
https://gerrit.openbmc-project.xyz/c/openbmc/openbmc/+/47933

This reverts commit bf888502a247d8374c70e7ceddc9862bf0ad88bd.

Change-Id: I346178f079245f96e2c1e03720490dcbcf19427b
Signed-off-by: Ed Tanous <edtanous@google.com>
diff --git a/meson.build b/meson.build
index 0bcf366..7673112 100644
--- a/meson.build
+++ b/meson.build
@@ -77,7 +77,6 @@
   'redfish'                         : '-DBMCWEB_ENABLE_REDFISH',
   'redfish-bmc-journal'             : '-DBMCWEB_ENABLE_REDFISH_BMC_JOURNAL',
   'redfish-cpu-log'                 : '-DBMCWEB_ENABLE_REDFISH_CPU_LOG',
-  'redfish-host-logger'             : '-DBMCWEB_ENABLE_REDFISH_HOST_LOGGER',
   'redfish-dbus-log'                : '-DBMCWEB_ENABLE_REDFISH_DBUS_LOG_ENTRIES',
   'redfish-provisioning-feature'    : '-DBMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE',
   'redfish-dump-log'                : '-DBMCWEB_ENABLE_REDFISH_DUMP_LOG',
diff --git a/meson_options.txt b/meson_options.txt
index 6c0f643..ada1957 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -19,7 +19,6 @@
 option('redfish-cpu-log', type : 'feature', value : 'disabled', description : '''Enable CPU log service transactions through Redfish. Paths are under \'/redfish/v1/Systems/system/LogServices/Crashdump'.''')
 option('redfish-dump-log', type : 'feature', value : 'disabled', description : 'Enable Dump log service transactions through Redfish. Paths are under \'/redfish/v1/Systems/system/LogServices/Dump\'and \'/redfish/v1/Managers/bmc/LogServices/Dump\'')
 option('redfish-dbus-log', type : 'feature', value : 'disabled', description : 'Enable DBUS log service transactions through Redfish. Paths are under \'/redfish/v1/Systems/system/LogServices/EventLog/Entries\'')
-option('redfish-host-logger', type : 'feature', value : 'enabled', description : 'Enable host log service transactions based on phosphor-hostlogger through Redfish.  Paths are under \'/redfish/v1/Systems/system/LogServices/HostLogger\'')
 option('redfish-provisioning-feature', type : 'feature', value : 'disabled', description : 'Enable provisioning feature support in redfish. Paths are under \'/redfish/v1/Systems/system/\'')
 option('bmcweb-logging', type : 'feature', value : 'disabled', description : 'Enable output the extended debug logs')
 option('basic-auth', type : 'feature', value : 'enabled', description : '''Enable basic authentication''')
diff --git a/redfish-core/include/gzfile.hpp b/redfish-core/include/gzfile.hpp
deleted file mode 100644
index 9f1b5db..0000000
--- a/redfish-core/include/gzfile.hpp
+++ /dev/null
@@ -1,178 +0,0 @@
-#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 2479332..0a97150 100644
--- a/redfish-core/include/redfish.hpp
+++ b/redfish-core/include/redfish.hpp
@@ -161,12 +161,6 @@
         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 065a4d1..2c9ae3a 100644
--- a/redfish-core/lib/log_services.hpp
+++ b/redfish-core/lib/log_services.hpp
@@ -15,9 +15,7 @@
 */
 #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"
@@ -977,12 +975,6 @@
                     {{"@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();
 
@@ -1825,221 +1817,6 @@
             });
 }
 
-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/")