PEL: peltool: Print all PELs into JSON array
Added -a option to display all PELS at once into a JSON array.
Read message registry once to parse SRC sections in PELs.
Signed-off-by: Harisuddin Mohamed Isa <harisuddin@gmail.com>
Change-Id: I19690a866a3348cf2d8a9a89be38bc09e3eb7f9f
diff --git a/extensions/openpower-pels/pel.cpp b/extensions/openpower-pels/pel.cpp
index 568b4c6..625546e 100644
--- a/extensions/openpower-pels/pel.cpp
+++ b/extensions/openpower-pels/pel.cpp
@@ -210,7 +210,8 @@
}
void PEL::printSectionInJSON(const Section& section, std::string& buf,
- std::map<uint16_t, size_t>& pluralSections) const
+ std::map<uint16_t, size_t>& pluralSections,
+ message::Registry& registry) const
{
char tmpB[5];
uint8_t id[] = {static_cast<uint8_t>(section.header().id >> 8),
@@ -231,15 +232,17 @@
if (section.valid())
{
- auto json = section.getJSON();
+ auto json = (sectionID == "PS" || sectionID == "SS")
+ ? section.getJSON(registry)
+ : section.getJSON();
if (json)
{
- buf += "\n\"" + sectionName + "\": {\n";
+ buf += "\"" + sectionName + "\": {\n";
buf += *json + "\n},\n";
}
else
{
- buf += "\n\"" + sectionName + "\": [\n";
+ buf += "\"" + sectionName + "\": [\n";
std::vector<uint8_t> data;
Stream s{data};
section.flatten(s);
@@ -283,16 +286,16 @@
return sections;
}
-void PEL::toJSON() const
+void PEL::toJSON(message::Registry& registry) const
{
auto sections = getPluralSections();
- std::string buf = "{";
- printSectionInJSON(*(_ph.get()), buf, sections);
- printSectionInJSON(*(_uh.get()), buf, sections);
+ std::string buf = "{\n";
+ printSectionInJSON(*(_ph.get()), buf, sections, registry);
+ printSectionInJSON(*(_uh.get()), buf, sections, registry);
for (auto& section : this->optionalSections())
{
- printSectionInJSON(*(section.get()), buf, sections);
+ printSectionInJSON(*(section.get()), buf, sections, registry);
}
buf += "}";
std::size_t found = buf.rfind(",");
diff --git a/extensions/openpower-pels/pel.hpp b/extensions/openpower-pels/pel.hpp
index 5f14354..0475c1c 100644
--- a/extensions/openpower-pels/pel.hpp
+++ b/extensions/openpower-pels/pel.hpp
@@ -223,8 +223,9 @@
/**
* @brief Output a PEL in JSON.
+ * @param[in] registry - Registry object reference
*/
- void toJSON() const;
+ void toJSON(message::Registry& registry) const;
/**
* @brief Sets the host transmission state in the User Header
@@ -321,9 +322,11 @@
* @param[in] std::string - PEL string
* @param[in|out] pluralSections - Map used to track sections counts for
* when there is more than 1.
+ * @param[in] registry - Registry object reference
*/
void printSectionInJSON(const Section& section, std::string& buf,
- std::map<uint16_t, size_t>& pluralSections) const;
+ std::map<uint16_t, size_t>& pluralSections,
+ message::Registry& registry) const;
/**
* @brief The maximum size a PEL can be in bytes.
diff --git a/extensions/openpower-pels/section.hpp b/extensions/openpower-pels/section.hpp
index 6353e2d..96a1aad 100644
--- a/extensions/openpower-pels/section.hpp
+++ b/extensions/openpower-pels/section.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include "registry.hpp"
#include "section_header.hpp"
#include <optional>
@@ -51,13 +52,25 @@
/**
* @brief Get section in JSON. Derived classes to override when required to.
* @return std::optional<std::string> - If a section comes with a JSON
- * repressentation, this would return the string for it.
+ * representation, this would return the string for it.
*/
virtual std::optional<std::string> getJSON() const
{
return std::nullopt;
}
+ /**
+ * @brief Get section in JSON. Derived classes to override when required to.
+ * @param[in] registry - Registry object reference
+ * @return std::optional<std::string> - If a section comes with a JSON
+ * representation, this would return the string for it.
+ */
+ virtual std::optional<std::string>
+ getJSON(message::Registry& registry) const
+ {
+ return std::nullopt;
+ }
+
protected:
/**
* @brief Returns the flattened size of the section header
diff --git a/extensions/openpower-pels/src.cpp b/extensions/openpower-pels/src.cpp
index 4067fe8..6619d3f 100644
--- a/extensions/openpower-pels/src.cpp
+++ b/extensions/openpower-pels/src.cpp
@@ -428,7 +428,7 @@
return printOut;
}
-std::optional<std::string> SRC::getJSON() const
+std::optional<std::string> SRC::getJSON(message::Registry& registry) const
{
std::string ps;
jsonInsert(ps, "Section Version", getNumberString("%d", _header.version),
@@ -462,8 +462,7 @@
jsonInsert(ps, "Backplane CCIN", ccinString, 1);
}
- rg::Registry registry(getMessageRegistryPath() / rg::registryFileName);
- auto errorDetails = getErrorDetails(registry, DetailLevel::json);
+ auto errorDetails = getErrorDetails(registry, DetailLevel::json, true);
if (errorDetails)
{
ps.append(errorDetails.value());
diff --git a/extensions/openpower-pels/src.hpp b/extensions/openpower-pels/src.hpp
index 7cfa311..51ded24 100644
--- a/extensions/openpower-pels/src.hpp
+++ b/extensions/openpower-pels/src.hpp
@@ -225,9 +225,11 @@
/**
* @brief Get section in JSON.
+ * @param[in] registry - Registry object reference
* @return std::optional<std::string> - SRC section's JSON
*/
- std::optional<std::string> getJSON() const override;
+ std::optional<std::string>
+ getJSON(message::Registry& registry) const override;
/**
* @brief Get error details based on refcode and hexwords
diff --git a/extensions/openpower-pels/tools/peltool.cpp b/extensions/openpower-pels/tools/peltool.cpp
index fb4153e..142a712 100644
--- a/extensions/openpower-pels/tools/peltool.cpp
+++ b/extensions/openpower-pels/tools/peltool.cpp
@@ -39,7 +39,8 @@
namespace pv = openpower::pels::pel_values;
using PELFunc = std::function<void(const PEL&)>;
-
+message::Registry registry(getMessageRegistryPath() /
+ message::registryFileName);
namespace service
{
constexpr auto logging = "xyz.openbmc_project.Logging";
@@ -202,8 +203,17 @@
}
}
+/**
+ * @brief Creates JSON string of a PEL entry if fullPEL is false or prints to
+ * stdout the full PEL in JSON if fullPEL is true
+ * @param[in] itr - std::map iterator of <uint32_t, BCDTime>
+ * @param[in] hidden - Boolean to include hidden PELs
+ * @param[in] fullPEL - Boolean to print full JSON representation of PEL
+ * @param[in] foundPEL - Boolean to check if any PEL is present
+ * @return std::string - JSON string of PEL entry (empty if fullPEL is true)
+ */
template <typename T>
-std::string genPELJSON(T itr, bool hidden, message::Registry& registry)
+std::string genPELJSON(T itr, bool hidden, bool fullPEL, bool& foundPEL)
{
std::size_t found;
std::string val;
@@ -219,11 +229,30 @@
try
{
std::vector<uint8_t> data = getFileData(fileName);
- if (!data.empty())
+ if (data.empty())
{
- PEL pel{data};
- std::bitset<16> actionFlags{pel.userHeader().actionFlags()};
- if (pel.valid() && (hidden || !actionFlags.test(hiddenFlagBit)))
+ log<level::ERR>("Empty PEL file",
+ entry("FILENAME=%s", fileName.c_str()));
+ return listStr;
+ }
+ PEL pel{data};
+ std::bitset<16> actionFlags{pel.userHeader().actionFlags()};
+ if (pel.valid() && (hidden || !actionFlags.test(hiddenFlagBit)))
+ {
+ if (fullPEL)
+ {
+ if (!foundPEL)
+ {
+ std::cout << "[" << std::endl;
+ foundPEL = true;
+ }
+ else
+ {
+ std::cout << ",\n" << std::endl;
+ }
+ pel.toJSON(registry);
+ }
+ else
{
// id
sprintf(tmpValStr, "0x%X", pel.privateHeader().id());
@@ -292,12 +321,6 @@
}
}
}
- else
- {
- log<level::ERR>("Empty PEL file",
- entry("FILENAME=%s", fileName.c_str()),
- entry("ERROR=%s", "Empty PEL file"));
- }
}
catch (std::exception& e)
{
@@ -307,14 +330,17 @@
}
return listStr;
}
+
/**
- * @brief Print a list of PELs
+ * @brief Print a list of PELs or a JSON array of PELs
+ * @param[in] order - Boolean to print in reverse orser
+ * @param[in] hidden - Boolean to include hidden PELs
+ * @param[in] fullPEL - Boolean to print full PEL into a JSON array
*/
-void printList(bool order, bool hidden)
+void printPELs(bool order, bool hidden, bool fullPEL)
{
std::string listStr;
std::map<uint32_t, BCDTime> PELs;
- std::size_t found;
listStr = "{\n";
for (auto it = fs::directory_iterator(EXTENSION_PERSIST_DIR "/pels/logs");
it != fs::directory_iterator(); ++it)
@@ -329,10 +355,9 @@
fileNameToTimestamp((*it).path().filename()));
}
}
- message::Registry registry(getMessageRegistryPath() /
- message::registryFileName);
- auto buildJSON = [&listStr, &hidden, ®istry](const auto& i) {
- listStr += genPELJSON(i, hidden, registry);
+ bool foundPEL = false;
+ auto buildJSON = [&listStr, &hidden, &fullPEL, &foundPEL](const auto& i) {
+ listStr += genPELJSON(i, hidden, fullPEL, foundPEL);
};
if (order)
{
@@ -343,12 +368,20 @@
std::for_each(PELs.begin(), PELs.end(), buildJSON);
}
- found = listStr.rfind(",");
- if (found != std::string::npos)
+ if (!fullPEL)
{
- listStr.replace(found, 1, "");
- listStr += "\n}\n";
- printf("%s", listStr.c_str());
+ std::size_t found;
+ found = listStr.rfind(",");
+ if (found != std::string::npos)
+ {
+ listStr.replace(found, 1, "");
+ listStr += "\n}\n";
+ printf("%s", listStr.c_str());
+ }
+ }
+ else if (foundPEL)
+ {
+ std::cout << "]" << std::endl;
}
}
@@ -477,7 +510,7 @@
{
if (pel.valid())
{
- pel.toJSON();
+ pel.toJSON(registry);
}
else
{
@@ -536,11 +569,13 @@
bool hidden = false;
bool deleteAll = false;
bool showPELCount = false;
+ bool fullPEL = false;
app.set_help_flag("--help", "Print this help message and exit");
app.add_option("-f,--file", fileName,
"Display a PEL using its Raw PEL file");
app.add_option("-i, --id", idPEL, "Display a PEL based on its ID");
+ app.add_flag("-a", fullPEL, "Display all PELs");
app.add_flag("-l", listPEL, "List PELs");
app.add_flag("-n", showPELCount, "Show number of PELs");
app.add_flag("-r", listPELDescOrd, "Reverse order of output");
@@ -556,7 +591,7 @@
if (!data.empty())
{
PEL pel{data};
- pel.toJSON();
+ pel.toJSON(registry);
}
else
{
@@ -564,14 +599,13 @@
"Raw PEL file can't be read.");
}
}
-
else if (!idPEL.empty())
{
callFunctionOnPEL(idPEL, displayPEL);
}
- else if (listPEL)
+ else if (fullPEL || listPEL)
{
- printList(listPELDescOrd, hidden);
+ printPELs(listPELDescOrd, hidden, fullPEL);
}
else if (showPELCount)
{
@@ -587,8 +621,7 @@
}
else
{
- exitWithError(app.help("", CLI::AppFormatMode::All),
- "Raw PEL file path not specified.");
+ std::cout << app.help("", CLI::AppFormatMode::All) << std::endl;
}
return 0;
}