Implement ability to override default error level
Errors reported by the phosphor-logging app have a default error level,
and this level is specified in the error's YAML definition.
Enable users of the error's report() API to specify an error level. A
user may perceive a different error level for an error scenario, for eg
there may be certain host errors (for which we set the level as 'Error')
that may just be 'Warnings'.
Change-Id: I666a0ddcb099e530c423358a3b1c65f33b0ad01e
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
diff --git a/elog.cpp b/elog.cpp
index 27dfef5..363553b 100644
--- a/elog.cpp
+++ b/elog.cpp
@@ -1,5 +1,6 @@
#include "config.h"
#include <phosphor-logging/elog.hpp>
+#include <stdexcept>
namespace phosphor
{
@@ -7,7 +8,9 @@
{
namespace details
{
-void commit(const char* name)
+using namespace sdbusplus::xyz::openbmc_project::Logging::server;
+
+auto _prepareMsg(const char* funcName)
{
using phosphor::logging::log;
constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
@@ -29,16 +32,14 @@
auto mapperResponseMsg = b.call(mapper);
if (mapperResponseMsg.is_method_error())
{
- log<level::ERR>("Error in mapper call");
- return;
+ throw std::runtime_error("Error in mapper call");
}
std::map<std::string, std::vector<std::string>> mapperResponse;
mapperResponseMsg.read(mapperResponse);
if (mapperResponse.empty())
{
- log<level::ERR>("Error reading mapper response");
- return;
+ throw std::runtime_error("Error reading mapper response");
}
const auto& host = mapperResponse.cbegin()->first;
@@ -46,10 +47,26 @@
host.c_str(),
OBJ_INTERNAL,
IFACE_INTERNAL,
- "Commit");
+ funcName);
+ return m;
+}
+
+void commit(const char* name)
+{
+ auto msg = _prepareMsg("Commit");
uint64_t id = sdbusplus::server::transaction::get_id();
- m.append(id, name);
- b.call_noreply(m);
+ msg.append(id, name);
+ auto bus = sdbusplus::bus::new_default();
+ bus.call_noreply(msg);
+}
+
+void commit(const char* name, Entry::Level level)
+{
+ auto msg = _prepareMsg("CommitWithLvl");
+ uint64_t id = sdbusplus::server::transaction::get_id();
+ msg.append(id, name, static_cast<uint32_t>(level));
+ auto bus = sdbusplus::bus::new_default();
+ bus.call_noreply(msg);
}
} // namespace details
diff --git a/log_manager.cpp b/log_manager.cpp
index cc5e187..92454fe 100644
--- a/log_manager.cpp
+++ b/log_manager.cpp
@@ -25,17 +25,37 @@
{
namespace internal
{
-void Manager::commit(uint64_t transactionId, std::string errMsg)
-{
- auto reqLevel = level::ERR; // Default to ERR
- auto levelmap = g_errLevelMap.find(errMsg);
+inline auto getLevel(const std::string& errMsg)
+{
+ auto reqLevel = Entry::Level::Error; // Default to Error
+
+ auto levelmap = g_errLevelMap.find(errMsg);
if (levelmap != g_errLevelMap.end())
{
- reqLevel = levelmap->second;
+ reqLevel = static_cast<Entry::Level>(levelmap->second);
}
- if (static_cast<Entry::Level>(reqLevel) < Entry::sevLowerLimit)
+ return reqLevel;
+}
+
+void Manager::commit(uint64_t transactionId, std::string errMsg)
+{
+ auto level = getLevel(errMsg);
+ _commit(transactionId, std::move(errMsg), level);
+}
+
+void Manager::commitWithLvl(uint64_t transactionId, std::string errMsg,
+ uint32_t errLvl)
+{
+ _commit(transactionId, std::move(errMsg),
+ static_cast<Entry::Level>(errLvl));
+}
+
+void Manager::_commit(uint64_t transactionId, std::string&& errMsg,
+ Entry::Level errLvl)
+{
+ if (errLvl < Entry::sevLowerLimit)
{
if (realErrors.size() >= ERROR_CAP)
{
@@ -158,7 +178,7 @@
// Create error Entry dbus object
entryId++;
- if (static_cast<Entry::Level>(reqLevel) >= Entry::sevLowerLimit)
+ if (errLvl >= Entry::sevLowerLimit)
{
infoErrors.push_back(entryId);
}
@@ -179,7 +199,7 @@
objPath,
entryId,
ms, // Milliseconds since 1970
- static_cast<Entry::Level>(reqLevel),
+ errLvl,
std::move(errMsg),
std::move(additionalData),
std::move(objects),
diff --git a/log_manager.hpp b/log_manager.hpp
index b165ff3..9339a6f 100644
--- a/log_manager.hpp
+++ b/log_manager.hpp
@@ -68,6 +68,19 @@
*/
void commit(uint64_t transactionId, std::string errMsg) override;
+ /*
+ * @fn commit()
+ * @brief sd_bus CommitWithLvl method implementation callback.
+ * @details Create an error/event log based on transaction id and
+ * error message.
+ * @param[in] transactionId - Unique identifier of the journal entries
+ * to be committed.
+ * @param[in] errMsg - The error exception message associated with the
+ * error log to be committed.
+ * @param[in] errLvl - level of the error
+ */
+ void commitWithLvl(uint64_t transactionId, std::string errMsg,
+ uint32_t errLvl) override;
/** @brief Erase specified entry d-bus object
*
@@ -95,6 +108,18 @@
}
private:
+ /*
+ * @fn _commit()
+ * @brief commit() helper
+ * @param[in] transactionId - Unique identifier of the journal entries
+ * to be committed.
+ * @param[in] errMsg - The error exception message associated with the
+ * error log to be committed.
+ * @param[in] errLvl - level of the error
+ */
+ void _commit(uint64_t transactionId, std::string&& errMsg,
+ Entry::Level errLvl);
+
/** @brief Call metadata handler(s), if any. Handlers may create
* associations.
* @param[in] errorName - name of the error
diff --git a/phosphor-logging/elog.hpp b/phosphor-logging/elog.hpp
index 8a6b9c1..b76bd6c 100644
--- a/phosphor-logging/elog.hpp
+++ b/phosphor-logging/elog.hpp
@@ -3,12 +3,16 @@
#include <utility>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/exception.hpp>
+#include "xyz/openbmc_project/Logging/Entry/server.hpp"
+
namespace phosphor
{
namespace logging
{
+using namespace sdbusplus::xyz::openbmc_project::Logging::server;
+
/**
* @brief Structure used by callers to indicate they want to use the last value
* put in the journal for input parameter.
@@ -90,6 +94,10 @@
*/
void commit(const char* name);
+/** @fn commit() - override that accepts error level
+ */
+void commit(const char* name, Entry::Level level);
+
} // namespace details
/** @fn commit()
@@ -115,6 +123,22 @@
details::commit(T::errName);
}
+/** @fn commit()
+ * @brief Create an error log entry based on journal
+ * entry with a specified MSG_ID. This override accepts error level.
+ * @param[in] level - level of the error
+ */
+template <typename T>
+void commit(Entry::Level level)
+{
+ // Validate if the exception is derived from sdbusplus::exception.
+ static_assert(
+ std::is_base_of<sdbusplus::exception::exception, T>::value,
+ "T must be a descendant of sdbusplus::exception::exception"
+ );
+ details::commit(T::errName, level);
+}
+
/** @fn elog()
* @brief Create a journal log entry based on predefined
@@ -176,6 +200,39 @@
commit<T>();
}
+
+/** @fn report()
+ * @brief Create a journal log entry based on predefined
+ * error log information and commit the error. Accepts error
+ * level.
+ * @tparam T - exception
+ * @param[in] level - level of the error
+ * @param[in] i_args - Metadata fields to be added to the journal entry
+ */
+template <typename T, typename ...Args>
+void report(Entry::Level level, Args... i_args)
+{
+ //validate if the exception is derived from sdbusplus::exception.
+ static_assert(
+ std::is_base_of<sdbusplus::exception::exception, T>::value,
+ "T must be a descendant of sdbusplus::exception::exception"
+ );
+
+ // Validate the caller passed in the required parameters
+ static_assert(std::is_same<typename details::
+ map_exception_type_t<T>::metadata_types,
+ std::tuple<
+ details::deduce_entry_type_t<Args>...>>
+ ::value,
+ "You are not passing in required arguments for this error");
+
+ log<details::map_exception_type_t<T>::L>(
+ T::errDesc,
+ details::deduce_entry_type<Args>{i_args}.get()...);
+
+ commit<T>(level);
+}
+
} // namespace logging
} // namespace phosphor
diff --git a/xyz/openbmc_project/Logging/Internal/Manager.interface.yaml b/xyz/openbmc_project/Logging/Internal/Manager.interface.yaml
index 97ed3c9..4c1c8ce 100644
--- a/xyz/openbmc_project/Logging/Internal/Manager.interface.yaml
+++ b/xyz/openbmc_project/Logging/Internal/Manager.interface.yaml
@@ -6,7 +6,8 @@
- name: Commit
description: >
Write the requested error/event entry with its associated metadata
- fields to flash.
+ fields to flash. The "level" of the committed error log is same as the
+ level defined in error YAML definitions.
parameters:
- name: transactionId
type: uint64
@@ -17,3 +18,22 @@
description: >
The error exception message associated with the error
event log to be committed.
+ - name: CommitWithLvl
+ description: >
+ Write the requested error/event entry with its associated metadata
+ fields to flash. This interface allows the caller to override the
+ error level specified in the error YAML definition.
+ parameters:
+ - name: transactionId
+ type: uint64
+ description: >
+ The unique identifier of the journal entry(ies) to be committed.
+ - name: errMsg
+ type: string
+ description: >
+ The error exception message associated with the error
+ event log to be committed.
+ - name: errLvl
+ type: uint32
+ description: >
+ The error level/severity indicator.