diff --git a/project/CMakeLists.txt b/project/CMakeLists.txt
index ed299d8..4db24b7 100644
--- a/project/CMakeLists.txt
+++ b/project/CMakeLists.txt
@@ -23,4 +23,9 @@ add_subdirectory(doct-cpp)
configure_file(
${CMAKE_SOURCE_DIR}/doct-cpp/res/demo_flow.json
${CMAKE_BINARY_DIR}/bin/demo_flow.json
+ COPYONLY)
+
+configure_file(
+ ${CMAKE_SOURCE_DIR}/doct-cpp/res/sysinfo_flow.json
+ ${CMAKE_BINARY_DIR}/bin/sysinfo_flow.json
COPYONLY)
\ No newline at end of file
diff --git a/project/doct-cpp/CMakeLists.txt b/project/doct-cpp/CMakeLists.txt
index 9a33324..4097916 100644
--- a/project/doct-cpp/CMakeLists.txt
+++ b/project/doct-cpp/CMakeLists.txt
@@ -12,6 +12,8 @@ add_library(doct-cpp-lib
src/data/collector_task.cpp
src/data/tweaker_task.cpp
src/data/flow.cpp
+ src/data/sysinfo_task.cpp
+ src/systeminfo_task_runner.cpp
)
target_link_libraries(doct-cpp-lib LINK_PUBLIC ext_tools)
target_include_directories(doct-cpp-lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
diff --git a/project/doct-cpp/include/data/sysinfo_task.hpp b/project/doct-cpp/include/data/sysinfo_task.hpp
new file mode 100644
index 0000000..949ca1b
--- /dev/null
+++ b/project/doct-cpp/include/data/sysinfo_task.hpp
@@ -0,0 +1,26 @@
+// Copyright © doWhile 2020
+
+#ifndef DOCT_DATA_SYSINFO_TASK_H
+#define DOCT_DATA_SYSINFO_TASK_H
+
+#include "task.hpp"
+
+#include <nlohmann/json.hpp>
+
+#include <string>
+
+
+namespace doWhile::doct::data
+{
+
+struct SysInfoTask : public Task
+{
+ virtual ~SysInfoTask() = default;
+ virtual std::string str() const override;
+};
+
+void from_json(const nlohmann::json& json, SysInfoTask& sysInfoTask);
+
+}
+
+#endif // DOCT_DATA_SYSINFO_TASK_H
diff --git a/project/doct-cpp/include/systeminfo_task_runner.hpp b/project/doct-cpp/include/systeminfo_task_runner.hpp
new file mode 100644
index 0000000..020c0f8
--- /dev/null
+++ b/project/doct-cpp/include/systeminfo_task_runner.hpp
@@ -0,0 +1,37 @@
+// Copyright © doWhile 2020
+
+#ifndef DOCT_SYSINFO_TASK_RUNNER_H
+#define DOCT_SYSINFO_TASK_RUNNER_H
+
+#include "task_result.hpp"
+#include "sysinfo_task.hpp"
+#include "system_info.hpp"
+
+#include <string>
+
+namespace doWhile::doct
+{
+
+class SystemInfoTaskRunner
+{
+ public:
+ SystemInfoTaskRunner() = delete;
+
+ /**
+ * \brief Fetches and reports the system information for the given host
+ *
+ * \param task A SystemInfpTask to run
+ * \param collector The Collector to run the task on
+ * \return Results of running the task, format depends on task type
+ */
+ static TaskResult runTask(std::shared_ptr<data::SysInfoTask> task, ext_tools::SystemInfo* systemInfo);
+
+ private:
+
+ static std::string humanise(long input);
+ static std::string getHosname(ext_tools::SystemInfo* systemInfo);
+};
+
+}
+
+#endif // DOCT_SYSINFO_TASK_RUNNER_H
diff --git a/project/doct-cpp/res/sysinfo_flow.json b/project/doct-cpp/res/sysinfo_flow.json
new file mode 100644
index 0000000..e7cbb57
--- /dev/null
+++ b/project/doct-cpp/res/sysinfo_flow.json
@@ -0,0 +1,9 @@
+{
+ "hostname": "host.name",
+ "tasks": [
+ {
+ "type": "SysInfoTask",
+ "description": "Report sysinfo"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/project/doct-cpp/src/data/flow.cpp b/project/doct-cpp/src/data/flow.cpp
index 15269dd..d895fb8 100644
--- a/project/doct-cpp/src/data/flow.cpp
+++ b/project/doct-cpp/src/data/flow.cpp
@@ -4,6 +4,7 @@
#include "collector_task.hpp"
#include "tweaker_task.hpp"
+#include "sysinfo_task.hpp"
#include <stdexcept>
@@ -32,6 +33,12 @@ void from_json(const nlohmann::json& json, Flow& flow)
from_json(jsonTask, *task);
flow.tasks.push_back(task);
}
+ else if (jsonTask.at(TYPE) == "SysInfoTask")
+ {
+ auto task = std::make_shared<SysInfoTask>();
+ from_json(jsonTask, *task);
+ flow.tasks.push_back(task);
+ }
else
{
throw std::invalid_argument("Error while parsing flow file, unknown task type: " + jsonTask.at(TYPE).get<std::string>());
diff --git a/project/doct-cpp/src/data/sysinfo_task.cpp b/project/doct-cpp/src/data/sysinfo_task.cpp
new file mode 100644
index 0000000..007b779
--- /dev/null
+++ b/project/doct-cpp/src/data/sysinfo_task.cpp
@@ -0,0 +1,18 @@
+// Copyright © doWhile 2020
+
+#include "sysinfo_task.hpp"
+
+namespace doWhile::doct::data
+{
+
+std::string SysInfoTask::str() const
+{
+ return "SystemInfoTask";
+}
+
+void from_json(const nlohmann::json& json, SysInfoTask& sysInfoTask)
+{
+ json.at("description").get_to(sysInfoTask.description);
+}
+
+}
\ No newline at end of file
diff --git a/project/doct-cpp/src/flow_runner.cpp b/project/doct-cpp/src/flow_runner.cpp
index 7c1976f..74a67c3 100644
--- a/project/doct-cpp/src/flow_runner.cpp
+++ b/project/doct-cpp/src/flow_runner.cpp
@@ -4,6 +4,9 @@
#include "collector_task_runner.hpp"
#include "tweaker_task_runner.hpp"
#include "tweaker.hpp"
+#include "system_info.hpp"
+#include "systeminfo_task_runner.hpp"
+#include "sysinfo_task.hpp"
#include <nlohmann/json.hpp>
@@ -51,6 +54,11 @@ TaskResult FlowRunner::runTask(std::shared_ptr<data::Task>& task, const std::str
ext_tools::Tweaker* tweaker = ext_tools::Tweaker::lookup(hostname);
return TweakerTaskRunner::runTask(tweakerTask, tweaker);
}
+ if (task != nullptr)
+ {
+ auto sysInfoTask = std::dynamic_pointer_cast<SysInfoTask>(task);
+ return SystemInfoTaskRunner::runTask(sysInfoTask, ext_tools::SystemInfo::get(hostname));
+ }
throw std::invalid_argument("Unknown task type");
}
diff --git a/project/doct-cpp/src/systeminfo_task_runner.cpp b/project/doct-cpp/src/systeminfo_task_runner.cpp
new file mode 100644
index 0000000..6084a82
--- /dev/null
+++ b/project/doct-cpp/src/systeminfo_task_runner.cpp
@@ -0,0 +1,70 @@
+// Copyright © doWhile 2020
+
+#include "systeminfo_task_runner.hpp"
+#include "system_info.hpp"
+
+#include <string>
+#include <vector>
+#include <sstream>
+#include <algorithm>
+
+namespace doWhile::doct
+{
+
+TaskResult SystemInfoTaskRunner::runTask(std::shared_ptr<data::SysInfoTask> task, ext_tools::SystemInfo* systemInfo)
+{
+ TaskResult taskResult{task};
+ taskResult.setSuccess(true);
+
+ std::vector<std::string> tableRows;
+ tableRows.push_back("----------------------------------------");
+ tableRows.push_back("| Hostname: " + getHosname(systemInfo));
+ tableRows.push_back("| Cpus: " + std::to_string(systemInfo->getCpus().size()));
+ for(int i = 0; i < systemInfo->getCpus().size(); i++)
+ {
+ auto c = systemInfo->getCpus()[i];
+ tableRows.push_back("| - Cpu #" + std::to_string(i) + " core: " + std::to_string(c->getCore()));
+ tableRows.push_back("| - Cpu #" + std::to_string(i) + " utilisation: " + std::to_string(c->getCpuUtilization()));
+ }
+
+ auto cpus = systemInfo->getCpus();
+ std::vector<double> cpuUtilizations;
+ std::transform(cpus.begin(), cpus.end(), std::back_inserter(cpuUtilizations), [](std::shared_ptr<ext_tools::CpuCoreInfo> cpu) { return cpu->getCpuUtilization(); });
+ auto average = std::to_string(std::accumulate(cpuUtilizations.begin(), cpuUtilizations.end(), 0.0) / cpuUtilizations.size());
+
+ tableRows.push_back("| Avarege utilisation: " + average.substr(0,4));
+
+ auto memTotal = humanise(systemInfo->getTotalMemory() * 1000 * 1000 /* To bytes for humanisation */);
+ auto memUsedl = humanise(systemInfo->getMemoryUsage() * 1000 * 1000 /* To bytes for humanisation */);
+ tableRows.push_back("| Memory: " + memUsedl + " of " + memTotal);
+ tableRows.push_back("-------------------------------------");
+
+ for (const auto row : tableRows)
+ taskResult.addMessage(row);
+
+ return taskResult;
+}
+
+std::string SystemInfoTaskRunner::humanise(long input)
+{
+ std::vector<std::string> _orders { "B", "kB", "MB", "GB", "PB", "TB" };
+
+ int divisions = 0;
+ while (input > 1024)
+ {
+ input = input / 1024;
+ divisions = divisions + 1;
+ }
+
+ std::ostringstream stream;
+ stream << input << " " << _orders[divisions];
+
+ return stream.str();
+}
+
+std::string SystemInfoTaskRunner::getHosname(ext_tools::SystemInfo* systemInfo)
+{
+ return systemInfo->hostname;
+}
+
+}
\ No newline at end of file
diff --git a/project/ext_tools/include/system_info.hpp b/project/ext_tools/include/system_info.hpp
index ccd7dd9..0e3b7fe 100644
--- a/project/ext_tools/include/system_info.hpp
+++ b/project/ext_tools/include/system_info.hpp
@@ -11,10 +11,13 @@
#include <memory>
#include <map>
-namespace doWhile::doct::ext_tools
+namespace doWhile::doct
{
+ class SystemInfoTaskRunner;
+}
-//class CpuCoreInfo;
+namespace doWhile::doct::ext_tools
+{
class SystemInfo
{
@@ -52,6 +55,9 @@ class SystemInfo
SystemInfo(std::string hostname);
std::string hostname;
int targetMemoryUsage;
+
+ friend doWhile::doct::SystemInfoTaskRunner;
+
};
}