crit-service: initial service and parsing
This is an initial commit in a series of commits that will introduce a
service monitoring feature within the current target monitoring
function.
This new feature will allow a user to pass in a json file with systemd
service names that they wish this function to monitor. If a monitored
services goes into an error state (exhausted all retries and service has
been stopped) then the monitor service will create an error and collect
appropriate debug data.
This commit focuses on defining the new json service file and adapting
the existing target monitor to take this file as input. Future commits
in this series will build on this.
Tested:
- Verified new service json could be input to application and it was
parsed correctly
Signed-off-by: Andrew Geissler <geissonator@yahoo.com>
Change-Id: Ifcc512b8fc868e2a1004a184fa50e4d4c826e8ee
diff --git a/data/phosphor-service-monitor-default.json b/data/phosphor-service-monitor-default.json
new file mode 100644
index 0000000..99877e7
--- /dev/null
+++ b/data/phosphor-service-monitor-default.json
@@ -0,0 +1,21 @@
+{
+ "services" : [
+ "xyz.openbmc_project.biosconfig_manager.service",
+ "xyz.openbmc_project.Dump.Manager.service",
+ "xyz.openbmc_project.EntityManager.service",
+ "xyz.openbmc_project.Inventory.Manager.service",
+ "xyz.openbmc_project.Logging.service",
+ "xyz.openbmc_project.Network.service",
+ "xyz.openbmc_project.ObjectMapper.service",
+ "xyz.openbmc_project.Settings.service",
+ "xyz.openbmc_project.Software.BMC.Updater.service",
+ "xyz.openbmc_project.Software.Download.service",
+ "xyz.openbmc_project.Software.Version.service",
+ "xyz.openbmc_project.State.BMC.service",
+ "xyz.openbmc_project.State.Chassis.service",
+ "xyz.openbmc_project.State.Host.service",
+ "xyz.openbmc_project.Time.Manager.service",
+ "xyz.openbmc_project.User.Manager.service",
+ "bmcweb.service"
+ ]
+}
diff --git a/meson.build b/meson.build
index d87b837..be2a2ba 100644
--- a/meson.build
+++ b/meson.build
@@ -144,6 +144,7 @@
)
executable('phosphor-systemd-target-monitor',
+ 'systemd_service_parser.cpp',
'systemd_target_monitor.cpp',
'systemd_target_parser.cpp',
'systemd_target_signal.cpp',
diff --git a/systemd_service_parser.cpp b/systemd_service_parser.cpp
new file mode 100644
index 0000000..46d9156
--- /dev/null
+++ b/systemd_service_parser.cpp
@@ -0,0 +1,29 @@
+#include "systemd_service_parser.hpp"
+
+#include <fstream>
+#include <iostream>
+
+ServiceMonitorData parseServiceFiles(const std::vector<std::string>& filePaths)
+{
+ ServiceMonitorData systemdServiceMap;
+ for (const auto& jsonFile : filePaths)
+ {
+ if (gVerbose)
+ {
+ std::cout << "Parsing input service file " << jsonFile << std::endl;
+ }
+ std::ifstream fileStream(jsonFile);
+ auto j = json::parse(fileStream);
+
+ for (auto& service : j["services"].items())
+ {
+ if (gVerbose)
+ {
+ std::cout << "service: " << service.value() << std::endl;
+ }
+
+ systemdServiceMap.push_back(service.value());
+ }
+ }
+ return systemdServiceMap;
+}
diff --git a/systemd_service_parser.hpp b/systemd_service_parser.hpp
new file mode 100644
index 0000000..54d36b2
--- /dev/null
+++ b/systemd_service_parser.hpp
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <nlohmann/json.hpp>
+
+#include <map>
+#include <string>
+#include <vector>
+
+/** @brief Array of services to monitor */
+using ServiceMonitorData = std::vector<std::string>;
+
+using json = nlohmann::json;
+
+extern bool gVerbose;
+
+/** @brief Parse input json file(s) for services to monitor
+ *
+ * @note This function will throw exceptions for an invalid json file
+ * @note See phosphor-service-monitor-default.json for example of json file
+ * format
+ *
+ * @param[in] filePaths - The file(s) to parse
+ *
+ * @return Service(s) to monitor for errors
+ */
+ServiceMonitorData parseServiceFiles(const std::vector<std::string>& filePaths);
diff --git a/systemd_target_monitor.cpp b/systemd_target_monitor.cpp
index cc13711..0d8ae74 100644
--- a/systemd_target_monitor.cpp
+++ b/systemd_target_monitor.cpp
@@ -1,3 +1,4 @@
+#include "systemd_service_parser.hpp"
#include "systemd_target_parser.hpp"
#include "systemd_target_signal.hpp"
@@ -34,6 +35,9 @@
std::cout << "[-f <file1> -f <file2> ...] : Full path to json file(s) with "
"target/error mappings"
<< std::endl;
+ std::cout << "[-s <file1> -s <file2> ...] : Full path to json file(s) with "
+ "services to monitor for errors"
+ << std::endl;
return;
}
@@ -42,24 +46,27 @@
auto bus = sdbusplus::bus::new_default();
auto event = sdeventplus::Event::get_default();
bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
- std::vector<std::string> filePaths;
+ std::vector<std::string> targetFilePaths;
+ std::vector<std::string> serviceFilePaths;
- CLI::App app{"OpenBmc systemd target monitor"};
- app.add_option("-f,--file", filePaths,
+ CLI::App app{"OpenBmc systemd target and service monitor"};
+ app.add_option("-f,--file", targetFilePaths,
"Full path to json file(s) with target/error mappings");
+ app.add_option("-s,--service", serviceFilePaths,
+ "Full path to json file(s) with services to monitor");
app.add_flag("-v", gVerbose, "Enable verbose output");
CLI11_PARSE(app, argc, argv);
- if (filePaths.empty())
+ // target file input required
+ if (targetFilePaths.empty())
{
error("No input files");
print_usage();
exit(-1);
}
- TargetErrorData targetData = parseFiles(filePaths);
-
+ TargetErrorData targetData = parseFiles(targetFilePaths);
if (targetData.size() == 0)
{
error("Invalid input files, no targets found");
@@ -67,6 +74,12 @@
exit(-1);
}
+ ServiceMonitorData serviceData;
+ if (!serviceFilePaths.empty())
+ {
+ serviceData = parseServiceFiles(serviceFilePaths);
+ }
+
if (gVerbose)
{
dump_targets(targetData);