diff options
| author | Adriana Kobylak <anoo@us.ibm.com> | 2016-10-16 09:54:40 -0500 |
|---|---|---|
| committer | Patrick Williams <patrick@stwcx.xyz> | 2016-11-09 22:27:47 +0000 |
| commit | d311bc8d781caab241233465ad276c15a97bade5 (patch) | |
| tree | 8240cd3098d5ec6b4038239af44183b7f06afd75 /log_manager.cpp | |
| parent | 1d5fa772a646ab0573a9f5e84d0e8bf7de3ff18d (diff) | |
| download | phosphor-logging-d311bc8d781caab241233465ad276c15a97bade5.tar.gz phosphor-logging-d311bc8d781caab241233465ad276c15a97bade5.zip | |
Add error/event log commit dbus method
Create error/event log based on message id (process id)
and metadata values.
Change-Id: Iaf944130c4075ae2d2c192e5ef840451561791bc
Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
Diffstat (limited to 'log_manager.cpp')
| -rw-r--r-- | log_manager.cpp | 134 |
1 files changed, 123 insertions, 11 deletions
diff --git a/log_manager.cpp b/log_manager.cpp index 1cc1ce2..21e99a8 100644 --- a/log_manager.cpp +++ b/log_manager.cpp @@ -1,28 +1,140 @@ -#include <stdio.h> +#include <fstream> +#include <iostream> +#include <cstdio> +#include <string> +#include <vector> #include <sdbusplus/vtable.hpp> #include <systemd/sd-bus.h> +#include <systemd/sd-journal.h> #include "log.hpp" +using namespace phosphor; + /* * @fn commit() - * @brief Create an error/event log based on a message id - * @param[in] msg - dbus message - * @param[in] user_data - user data - * @param[in] error - dbus error - * @return Commit id + * @brief Create an error/event log based on specified id and metadata variable + * names that includes the journal message and the metadata values. */ -auto commit(sd_bus_message *msg, void *user_data, sd_bus_error *error) +auto commit(sd_bus_message *msg, void *userdata, sd_bus_error *error) { - int rc = 0; + // TODO Change /tmp path to a permanent location on flash + constexpr const auto path = "/tmp/elog"; + constexpr const auto msgIdStr = "_PID"; - return rc; + // Read PID + int rc = -1; + char *msgId = nullptr; + rc = sd_bus_message_read(msg, "s", &msgId); + if (rc < 0) + { + logging::log<logging::level::ERR>("Failed to read msg id", + logging::entry("DESCRIPTION=%s", strerror(-rc))); + return sd_bus_reply_method_return(msg, "i", rc); + } + + // Create log file + std::string filename{}; + filename.append(path); + // TODO Create error logs in their own separate dir once permanent location + // on flash is determined. Ex: ../msgId/1 + filename.append(msgId); + std::ofstream efile; + efile.open(filename); + efile << "{" << std::endl; + + // Read metadata variables passed as array of strings and store in vector + // TODO Read required metadata fields from header file instead + rc = sd_bus_message_enter_container(msg, SD_BUS_TYPE_ARRAY, "s"); + if (rc < 0) + { + logging::log<logging::level::ERR>("Failed to read metadata vars", + logging::entry("DESCRIPTION=%s", strerror(-rc))); + return sd_bus_reply_method_return(msg, nullptr); + } + const char* metaVar = nullptr; + std::vector<const char*> metaList; + while ((rc = sd_bus_message_read_basic(msg, 's', &metaVar)) > 0) + { + metaList.push_back(metaVar); + } + sd_bus_message_exit_container(msg); + + sd_journal *j = nullptr; + rc = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY); + if (rc < 0) + { + logging::log<logging::level::ERR>("Failed to open journal", + logging::entry("DESCRIPTION=%s", strerror(-rc))); + return sd_bus_reply_method_return(msg, nullptr); + } + + // Read the journal from the end to get the most recent entry first. + // The result from the sd_journal_get_data() is of the form VARIABLE=value. + SD_JOURNAL_FOREACH_BACKWARDS(j) + { + const char *data = nullptr; + size_t length = 0; + + // Search for the msg id + rc = sd_journal_get_data(j, msgIdStr, (const void **)&data, &length); + if (rc < 0) + { + // Instance not found, continue to next journal entry + continue; + } + std::string result(data); + if (result.find(msgId) == std::string::npos) + { + // Match not found, continue to next journal entry + continue; + } + + // Match found, write to file + // TODO This is a draft format based on the redfish event logs written + // in json, the final openbmc format is to be determined + efile << "\t{" << std::endl; + efile << "\t\"@" << data << "\"," << std::endl; + + // Include the journal message + rc = sd_journal_get_data(j, "MESSAGE", (const void **)&data, &length); + if (rc < 0) + { + continue; + } + efile << "\t\"@" << data << "\"," << std::endl; + + // Search for the metadata variables in the current journal entry + for (auto i : metaList) + { + rc = sd_journal_get_data(j, i, (const void **)&data, &length); + if (rc < 0) + { + // Not found, continue to next metadata variable + logging::log<logging::level::INFO>("Failed to find metadata", + logging::entry("META_FIELD=%s", i)); + continue; + } + + // Metatdata variable found, write to file + efile << "\t\"@" << data << "\"," << std::endl; + } + efile << "\t}" << std::endl; + + // TODO Break only once all metadata fields have been found. Implement + // once this function reads the metadata fields from the header file. + break; + } + sd_journal_close(j); + + efile << "}" << std::endl; + efile.close(); + return sd_bus_reply_method_return(msg, nullptr); } constexpr sdbusplus::vtable::vtable_t log_vtable[] = { sdbusplus::vtable::start(), - - sdbusplus::vtable::method("Commit", "i", "i", commit), + sdbusplus::vtable::method("Commit", "sas", "", commit), sdbusplus::vtable::end() }; |

