summaryrefslogtreecommitdiffstats
path: root/log_manager.cpp
diff options
context:
space:
mode:
authorMatt Spinler <spinler@us.ibm.com>2019-05-23 14:29:16 -0500
committerMatt Spinler <spinler@us.ibm.com>2019-07-16 21:30:24 +0000
commit99c2b4059e708a7cba6740a0e832ef5f480a9f12 (patch)
treee7279c67ccf6281dde4adea17162e822eb031b38 /log_manager.cpp
parent3b81846a764c4f87977b726188df224c0107c760 (diff)
downloadphosphor-logging-99c2b4059e708a7cba6740a0e832ef5f480a9f12.tar.gz
phosphor-logging-99c2b4059e708a7cba6740a0e832ef5f480a9f12.zip
OpenPower PEL Extension support framework
The goal of extensions is to extend phosphor-logging's `xyz.openbmc_project.Logging.Entry` log support to allow other log formats to be created without incurring extra D-Bus call overhead. The README.md change in this commit provides additional documentation on how extensions work. The summary is that they allow code that resides in this repository to provide functions that can be called at certain points (startup, log creation/deletion) such that the code can then create their own logs based on the contents of an OpenBMC log. A specific extension's code is compiled in using a --enable configure option, so platforms that did not use those log formats would incur no performance/size penalties. This commit provides the support for extensions, plus a basic OpenPower PEL (Platform Event Log) extension as the first extension. PELs are event logs used only on some OpenPower systems. Signed-off-by: Matt Spinler <spinler@us.ibm.com> Change-Id: Ifbb31325261c157678c29bbebc7f6d32d282582f
Diffstat (limited to 'log_manager.cpp')
-rw-r--r--log_manager.cpp87
1 files changed, 79 insertions, 8 deletions
diff --git a/log_manager.cpp b/log_manager.cpp
index 3dc14d7..0f4e57c 100644
--- a/log_manager.cpp
+++ b/log_manager.cpp
@@ -5,6 +5,7 @@
#include "elog_entry.hpp"
#include "elog_meta.hpp"
#include "elog_serialize.hpp"
+#include "extensions.hpp"
#include <poll.h>
#include <sys/inotify.h>
@@ -12,6 +13,7 @@
#include <systemd/sd-journal.h>
#include <unistd.h>
+#include <cassert>
#include <chrono>
#include <cstdio>
#include <cstring>
@@ -77,20 +79,24 @@ void Manager::commitWithLvl(uint64_t transactionId, std::string errMsg,
void Manager::_commit(uint64_t transactionId, std::string&& errMsg,
Entry::Level errLvl)
{
- if (errLvl < Entry::sevLowerLimit)
+ if (!Extensions::disableDefaultLogCaps())
{
- if (realErrors.size() >= ERROR_CAP)
+ if (errLvl < Entry::sevLowerLimit)
{
- erase(realErrors.front());
+ if (realErrors.size() >= ERROR_CAP)
+ {
+ erase(realErrors.front());
+ }
}
- }
- else
- {
- if (infoErrors.size() >= ERROR_INFO_CAP)
+ else
{
- erase(infoErrors.front());
+ if (infoErrors.size() >= ERROR_INFO_CAP)
+ {
+ erase(infoErrors.front());
+ }
}
}
+
constexpr const auto transactionIdVar = "TRANSACTION_ID";
// Length of 'TRANSACTION_ID' string.
constexpr const auto transactionIdVarSize = std::strlen(transactionIdVar);
@@ -217,9 +223,39 @@ void Manager::_commit(uint64_t transactionId, std::string&& errMsg,
std::move(additionalData),
std::move(objects), fwVersion, *this);
serialize(*e);
+
+ doExtensionLogCreate(*e);
+
entries.insert(std::make_pair(entryId, std::move(e)));
}
+void Manager::doExtensionLogCreate(const Entry& entry)
+{
+ // Make the association <endpointpath>/<endpointtype> paths
+ std::vector<std::string> assocs;
+ for (const auto& [forwardType, reverseType, endpoint] :
+ entry.associations())
+ {
+ std::string e{endpoint};
+ e += '/' + reverseType;
+ assocs.push_back(e);
+ }
+
+ for (auto& create : Extensions::getCreateFunctions())
+ {
+ try
+ {
+ create(entry.message(), entry.id(), entry.timestamp(),
+ entry.severity(), entry.additionalData(), assocs);
+ }
+ catch (std::exception& e)
+ {
+ log<level::ERR>("An extension's create function threw an exception",
+ phosphor::logging::entry("ERROR=%s", e.what()));
+ }
+ }
+}
+
void Manager::processMetadata(const std::string& errorName,
const std::vector<std::string>& additionalData,
AssociationList& objects) const
@@ -246,6 +282,27 @@ void Manager::erase(uint32_t entryId)
auto entryFound = entries.find(entryId);
if (entries.end() != entryFound)
{
+ for (auto& func : Extensions::getDeleteProhibitedFunctions())
+ {
+ try
+ {
+ bool prohibited = false;
+ func(entryId, prohibited);
+ if (prohibited)
+ {
+ // Future work remains to throw an error here.
+ return;
+ }
+ }
+ catch (std::exception& e)
+ {
+ log<level::ERR>(
+ "An extension's deleteProhibited function threw "
+ "an exception",
+ entry("ERROR=%s", e.what()));
+ }
+ }
+
// Delete the persistent representation of this error.
fs::path errorPath(ERRLOG_PERSIST_PATH);
errorPath /= std::to_string(entryId);
@@ -267,6 +324,20 @@ void Manager::erase(uint32_t entryId)
removeId(realErrors, entryId);
}
entries.erase(entryFound);
+
+ for (auto& remove : Extensions::getDeleteFunctions())
+ {
+ try
+ {
+ remove(entryId);
+ }
+ catch (std::exception& e)
+ {
+ log<level::ERR>("An extension's delete function threw an "
+ "exception",
+ entry("ERROR=%s", e.what()));
+ }
+ }
}
else
{
OpenPOWER on IntegriCloud