diff options
author | Harisuddin Mohamed Isa <harisuddin@gmail.com> | 2019-12-20 12:42:26 +0800 |
---|---|---|
committer | Harisuddin Mohamed Isa <harisuddin@gmail.com> | 2020-01-09 00:04:34 +0800 |
commit | 600d15afba0c72ab4e7bf6769dccffffe08ca5aa (patch) | |
tree | a2d73dc372b4617636205d6556e47642500b183a | |
parent | b3f5186e89a1ff8887e41863da39d30d373e3c08 (diff) | |
download | phosphor-logging-600d15afba0c72ab4e7bf6769dccffffe08ca5aa.tar.gz phosphor-logging-600d15afba0c72ab4e7bf6769dccffffe08ca5aa.zip |
PEL: Print action flags into JSON aligned
"User Header": {
"Section Version": "1",
"Sub-section type": "0",
"Log Committed by": "0x4552",
"Subsystem": "System Hypervisor Firmware",
"Event Scope": "Entire Platform",
"Event Severity": "Informational Event",
"Event Type": "Miscellaneous, Informational Only",
"Action Flags": [
"Report Externally"
]
}
Testing: Manually run peltool and verified output
Signed-off-by: Harisuddin Mohamed Isa <harisuddin@gmail.com>
Change-Id: Ie8376953b5f1baa093fc0aa9564d50cd4208564e
-rw-r--r-- | extensions/openpower-pels/hexdump.hpp | 33 | ||||
-rw-r--r-- | extensions/openpower-pels/json_utils.cpp (renamed from extensions/openpower-pels/hexdump.cpp) | 68 | ||||
-rw-r--r-- | extensions/openpower-pels/json_utils.hpp | 55 | ||||
-rw-r--r-- | extensions/openpower-pels/openpower-pels.mk | 2 | ||||
-rw-r--r-- | extensions/openpower-pels/pel.cpp | 11 | ||||
-rw-r--r-- | extensions/openpower-pels/pel_values.cpp | 18 | ||||
-rw-r--r-- | extensions/openpower-pels/pel_values.hpp | 10 | ||||
-rw-r--r-- | extensions/openpower-pels/user_header.cpp | 23 | ||||
-rw-r--r-- | test/openpower-pels/Makefile.include | 2 |
9 files changed, 167 insertions, 55 deletions
diff --git a/extensions/openpower-pels/hexdump.hpp b/extensions/openpower-pels/hexdump.hpp deleted file mode 100644 index bd26884..0000000 --- a/extensions/openpower-pels/hexdump.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include <ctype.h> -#include <stdio.h> - -#include <fstream> -#include <iomanip> -#include <iostream> -#include <string> -#include <vector> - -namespace openpower -{ -namespace pels -{ - -/** - * @brief escape json - use it for PEL hex dumps. - * @param[in] std::string - the unescaped JSON as a string literal - * @return std::string - escaped JSON string literal - */ -std::string escapeJSON(const std::string& input); - -/** - * @brief get hex dump for PEL section in json format. - * @param[in] const void* - Raw PEL data - * @param[i] size_t - size of Raw PEL - * @return char * - the Hex dump - */ -char* dumpHex(const void* data, size_t size); - -} // namespace pels -} // namespace openpower diff --git a/extensions/openpower-pels/hexdump.cpp b/extensions/openpower-pels/json_utils.cpp index ee4aef8..c6ea9f6 100644 --- a/extensions/openpower-pels/hexdump.cpp +++ b/extensions/openpower-pels/json_utils.cpp @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "hexdump.hpp" +#include "json_utils.hpp" #include <stdio.h> @@ -70,6 +70,8 @@ std::string escapeJSON(const std::string& input) char* dumpHex(const void* data, size_t size) { const int symbolSize = 100; + std::string jsonIndent(indentLevel, 0x20); + jsonIndent.append("\""); char* buffer = (char*)calloc(10 * size, sizeof(char)); char* symbol = (char*)calloc(symbolSize, sizeof(char)); char ascii[17]; @@ -79,7 +81,7 @@ char* dumpHex(const void* data, size_t size) { if (i % 16 == 0) { - strcat(buffer, "\""); + strcat(buffer, jsonIndent.c_str()); } snprintf(symbol, symbolSize, "%02X ", ((unsigned char*)data)[i]); strcat(buffer, symbol); @@ -103,11 +105,11 @@ char* dumpHex(const void* data, size_t size) { if (i + 1 != size) { - snprintf(symbol, symbolSize, "| %s\", \n ", asciiToPrint); + snprintf(symbol, symbolSize, "| %s\",\n", asciiToPrint); } else { - snprintf(symbol, symbolSize, "| %s\" \n ", asciiToPrint); + snprintf(symbol, symbolSize, "| %s\"\n", asciiToPrint); } strcat(buffer, symbol); memset(symbol, 0, strlen(symbol)); @@ -126,7 +128,7 @@ char* dumpHex(const void* data, size_t size) std::string asciiString2(ascii); asciiString2 = escapeJSON(asciiString2); asciiToPrint = asciiString2.c_str(); - snprintf(symbol, symbolSize, "| %s\" \n ", asciiToPrint); + snprintf(symbol, symbolSize, "| %s\"\n", asciiToPrint); strcat(buffer, symbol); memset(symbol, 0, strlen(symbol)); } @@ -135,5 +137,61 @@ char* dumpHex(const void* data, size_t size) free(symbol); return buffer; } + +void jsonInsert(std::string& jsonStr, const std::string& fieldName, + std::string& fieldValue, uint8_t indentCount) +{ + const int8_t spacesToAppend = + colAlign - (indentCount * indentLevel) - fieldName.length() - 3; + const std::string jsonIndent(indentCount * indentLevel, 0x20); + jsonStr.append(jsonIndent + "\"" + fieldName + "\":"); + if (spacesToAppend > 0) + { + jsonStr.append(spacesToAppend, 0x20); + } + else + { + jsonStr.append(1, 0x20); + } + jsonStr.append("\"" + fieldValue + "\",\n"); +} + +void jsonInsertArray(std::string& jsonStr, const std::string& fieldName, + std::vector<std::string>& values, uint8_t indentCount) +{ + const std::string jsonIndent(indentCount * indentLevel, 0x20); + if (!values.empty()) + { + jsonStr.append(jsonIndent + "\"" + fieldName + "\": [\n"); + for (size_t i = 0; i < values.size(); i++) + { + jsonStr.append(colAlign, 0x20); + if (i == values.size() - 1) + { + jsonStr.append("\"" + values[i] + "\"\n"); + } + else + { + jsonStr.append("\"" + values[i] + "\",\n"); + } + } + jsonStr.append(jsonIndent + "],\n"); + } + else + { + const int8_t spacesToAppend = + colAlign - (indentCount * indentLevel) - fieldName.length() - 3; + jsonStr.append(jsonIndent + "\"" + fieldName + "\":"); + if (spacesToAppend > 0) + { + jsonStr.append(spacesToAppend, 0x20); + } + else + { + jsonStr.append(1, 0x20); + } + jsonStr.append("[],\n"); + } +} } // namespace pels } // namespace openpower diff --git a/extensions/openpower-pels/json_utils.hpp b/extensions/openpower-pels/json_utils.hpp new file mode 100644 index 0000000..14c2ce4 --- /dev/null +++ b/extensions/openpower-pels/json_utils.hpp @@ -0,0 +1,55 @@ +#pragma once + +#include <ctype.h> +#include <stdio.h> + +#include <fstream> +#include <iomanip> +#include <iostream> +#include <string> +#include <vector> + +namespace openpower +{ +namespace pels +{ +const uint8_t indentLevel = 4; +const uint8_t colAlign = 32; +/** + * @brief escape json - use it for PEL hex dumps. + * @param[in] std::string - the unescaped JSON as a string literal + * @return std::string - escaped JSON string literal + */ +std::string escapeJSON(const std::string& input); + +/** + * @brief get hex dump for PEL section in json format. + * @param[in] const void* - Raw PEL data + * @param[i] size_t - size of Raw PEL + * @return char * - the Hex dump + */ +char* dumpHex(const void* data, size_t size); + +/** + * @brief Inserts key-value into a JSON string + * + * @param[in] jsonStr - The JSON string + * @param[in] fieldName - The JSON key to insert + * @param[in] fieldValue - The JSON value to insert + * @param[in] indentCount - Indent count for the line + */ +void jsonInsert(std::string& jsonStr, const std::string& fieldName, + std::string& fieldValue, uint8_t indentCount); + +/** + * @brief Inserts key-value array into a JSON string + * + * @param[in] jsonStr - The JSON string + * @param[in] fieldName - The JSON key to insert + * @param[in] values - The JSON array to insert + * @param[in] indentCount - Indent count for the line + */ +void jsonInsertArray(std::string& jsonStr, const std::string& fieldName, + std::vector<std::string>& values, uint8_t indentCount); +} // namespace pels +} // namespace openpower diff --git a/extensions/openpower-pels/openpower-pels.mk b/extensions/openpower-pels/openpower-pels.mk index 5bce70d..d974e06 100644 --- a/extensions/openpower-pels/openpower-pels.mk +++ b/extensions/openpower-pels/openpower-pels.mk @@ -18,7 +18,7 @@ libpel_la_SOURCES = \ extensions/openpower-pels/failing_mtms.cpp \ extensions/openpower-pels/fru_identity.cpp \ extensions/openpower-pels/generic.cpp \ - extensions/openpower-pels/hexdump.cpp \ + extensions/openpower-pels/json_utils.cpp \ extensions/openpower-pels/log_id.cpp \ extensions/openpower-pels/mru.cpp \ extensions/openpower-pels/mtms.cpp \ diff --git a/extensions/openpower-pels/pel.cpp b/extensions/openpower-pels/pel.cpp index 022ac05..74d46bd 100644 --- a/extensions/openpower-pels/pel.cpp +++ b/extensions/openpower-pels/pel.cpp @@ -18,7 +18,7 @@ #include "bcd_time.hpp" #include "extended_user_header.hpp" #include "failing_mtms.hpp" -#include "hexdump.hpp" +#include "json_utils.hpp" #include "log_id.hpp" #include "pel_rules.hpp" #include "pel_values.hpp" @@ -229,12 +229,12 @@ void PEL::printSectionInJSON(const Section& section, std::string& buf) const auto json = section.getJSON(); if (json) { - buf += "\n\"" + sectionName + "\":[\n "; - buf += *json + "\n],\n"; + buf += "\n\"" + sectionName + "\": {\n"; + buf += *json + "\n},\n"; } else { - buf += "\n\"" + sectionName + "\":[\n "; + buf += "\n\"" + sectionName + "\": [\n"; std::vector<uint8_t> data; Stream s{data}; section.flatten(s); @@ -244,7 +244,7 @@ void PEL::printSectionInJSON(const Section& section, std::string& buf) const } else { - buf += "\n\"Invalid Section \":[\n invalid \n],\n"; + buf += "\n\"Invalid Section\": [\n \"invalid\"\n],\n"; } } @@ -263,5 +263,6 @@ void PEL::toJSON() const buf.replace(found, 1, ""); std::cout << buf << std::endl; } + } // namespace pels } // namespace openpower diff --git a/extensions/openpower-pels/pel_values.cpp b/extensions/openpower-pels/pel_values.cpp index 3502f92..f8c877c 100644 --- a/extensions/openpower-pels/pel_values.cpp +++ b/extensions/openpower-pels/pel_values.cpp @@ -196,8 +196,10 @@ const PELValues actionFlagsValues = { {0x8000, "service_action", "Service Action Required"}, {0x4000, "hidden", "Event not customer viewable"}, {0x2000, "report", "Report Externally"}, - {0x1000, "dont_report", "Do Not Report"}, + {0x1000, "dont_report", "Do Not Report To Hypervisor"}, {0x0800, "call_home", "HMC Call Home"}, + {0x0400, "isolation_incomplete", + "Isolation Incomplete, further analysis required"}, {0x0100, "termination", "Service Processor Call Home Required"}}; /** @@ -276,6 +278,20 @@ std::string getValue(const uint8_t field, const pel_values::PELValues& values) return "invalid"; } } + +std::vector<std::string> getValuesBitwise(uint16_t value, + const pel_values::PELValues& table) +{ + std::vector<std::string> foundValues; + std::for_each( + table.begin(), table.end(), [&value, &foundValues](const auto& entry) { + if (value & std::get<fieldValuePos>(entry)) + { + foundValues.push_back(std::get<descriptionPos>(entry)); + } + }); + return foundValues; +} } // namespace pel_values } // namespace pels } // namespace openpower diff --git a/extensions/openpower-pels/pel_values.hpp b/extensions/openpower-pels/pel_values.hpp index 8d86acf..9a1ed88 100644 --- a/extensions/openpower-pels/pel_values.hpp +++ b/extensions/openpower-pels/pel_values.hpp @@ -33,6 +33,16 @@ using PELValues = std::vector<PELFieldValue>; std::string getValue(const uint8_t field, const pel_values::PELValues& values); /** + * @brief Helper function to get value vector from lookup tables. + * + * @param[in] value - the value to lookup + * @param[in] table - lookup table + * + * @return std::vector<std::string> - the value vector + */ +std::vector<std::string> getValuesBitwise(uint16_t value, + const pel_values::PELValues& table); +/** * @brief Find the desired entry in a PELValues table based on the * field value. * diff --git a/extensions/openpower-pels/user_header.cpp b/extensions/openpower-pels/user_header.cpp index 5aef28d..b70da94 100644 --- a/extensions/openpower-pels/user_header.cpp +++ b/extensions/openpower-pels/user_header.cpp @@ -15,6 +15,7 @@ */ #include "user_header.hpp" +#include "json_utils.hpp" #include "pel_types.hpp" #include "pel_values.hpp" #include "severity.hpp" @@ -135,10 +136,13 @@ std::optional<std::string> UserHeader::getJSON() const std::string subsystem; std::string eventScope; std::string eventType; + std::vector<std::string> actionFlags; severity = pv::getValue(_eventSeverity, pel_values::severityValues); subsystem = pv::getValue(_eventSubsystem, pel_values::subsystemValues); eventScope = pv::getValue(_eventScope, pel_values::eventScopeValues); eventType = pv::getValue(_eventType, pel_values::eventTypeValues); + actionFlags = + pv::getValuesBitwise(_actionFlags, pel_values::actionFlagsValues); char tmpUhVal[8]; sprintf(tmpUhVal, "%d", userHeaderVersion); std::string uhVerStr(tmpUhVal); @@ -147,15 +151,16 @@ std::optional<std::string> UserHeader::getJSON() const sprintf(tmpUhVal, "%d", _header.subType); std::string uhStStr(tmpUhVal); - std::string uh = "{\"Section Version\": \"" + uhVerStr + - "\"}, \n {\"Sub-section type\": \"" + uhStStr + - "\"}, \n " - "{\"Log Committed by\": \"" + - uhCbStr + "\"}, \n {\"Subsystem\": \"" + subsystem + - "\"},\n " - "{\"Event Scope\": \"" + - eventScope + "\"}, \n {\"Event Severity\":\"" + severity + - "\"},\n {\"Event Type\": \"" + eventType + "\"}"; + std::string uh; + jsonInsert(uh, "Section Version", uhVerStr, 1); + jsonInsert(uh, "Sub-section type", uhStStr, 1); + jsonInsert(uh, "Log Committed by", uhCbStr, 1); + jsonInsert(uh, "Subsystem", subsystem, 1); + jsonInsert(uh, "Event Scope", eventScope, 1); + jsonInsert(uh, "Event Severity", severity, 1); + jsonInsert(uh, "Event Type", eventType, 1); + jsonInsertArray(uh, "Action Flags", actionFlags, 1); + uh.erase(uh.size() - 2); return uh; } } // namespace pels diff --git a/test/openpower-pels/Makefile.include b/test/openpower-pels/Makefile.include index dfa4156..d85f215 100644 --- a/test/openpower-pels/Makefile.include +++ b/test/openpower-pels/Makefile.include @@ -38,7 +38,7 @@ pel_objects = \ $(top_builddir)/extensions/openpower-pels/failing_mtms.o \ $(top_builddir)/extensions/openpower-pels/fru_identity.o \ $(top_builddir)/extensions/openpower-pels/generic.o \ - $(top_builddir)/extensions/openpower-pels/hexdump.o \ + $(top_builddir)/extensions/openpower-pels/json_utils.o \ $(top_builddir)/extensions/openpower-pels/log_id.o \ $(top_builddir)/extensions/openpower-pels/mtms.o \ $(top_builddir)/extensions/openpower-pels/mru.o \ |