made MetricValues persistent
MetricValues are persistent for reportUpdates AppendStopsWhenFull and
reportingType different than OnRequest.
Tested:
- New unit tests are passing
- Confirmed MetricValues are preserved after restarting telemetry
service
Change-Id: I7e1990fb391da9debb0d7df2f1dbda86473350cc
Signed-off-by: Krzysztof Grobelny <krzysztof.grobelny@intel.com>
diff --git a/src/interfaces/report_factory.hpp b/src/interfaces/report_factory.hpp
index e1f9f2a..d8e076a 100644
--- a/src/interfaces/report_factory.hpp
+++ b/src/interfaces/report_factory.hpp
@@ -4,6 +4,7 @@
#include "interfaces/metric.hpp"
#include "interfaces/report.hpp"
#include "interfaces/report_manager.hpp"
+#include "types/readings.hpp"
#include "types/report_action.hpp"
#include "types/report_types.hpp"
#include "types/report_updates.hpp"
@@ -42,7 +43,7 @@
const ReportUpdates reportUpdates, ReportManager& reportManager,
JsonStorage& reportStorage,
std::vector<LabeledMetricParameters> labeledMetricParams,
- bool enabled) const = 0;
+ bool enabled, Readings) const = 0;
};
} // namespace interfaces
diff --git a/src/report.cpp b/src/report.cpp
index d9d89b8..945d4e6 100644
--- a/src/report.cpp
+++ b/src/report.cpp
@@ -27,14 +27,16 @@
interfaces::JsonStorage& reportStorageIn,
std::vector<std::shared_ptr<interfaces::Metric>> metricsIn,
const interfaces::ReportFactory& reportFactory,
- const bool enabledIn, std::unique_ptr<interfaces::Clock> clock) :
+ const bool enabledIn, std::unique_ptr<interfaces::Clock> clock,
+ Readings readingsIn) :
id(reportId),
name(reportName), reportingType(reportingTypeIn), interval(intervalIn),
reportActions(reportActionsIn.begin(), reportActionsIn.end()),
sensorCount(getSensorCount(metricsIn)),
appendLimit(deduceAppendLimit(appendLimitIn)),
- reportUpdates(reportUpdatesIn),
- readingsBuffer(deduceBufferSize(reportUpdates, reportingType)),
+ reportUpdates(reportUpdatesIn), readings(std::move(readingsIn)),
+ readingsBuffer(std::get<1>(readings),
+ deduceBufferSize(reportUpdates, reportingType)),
objServer(objServer), metrics(std::move(metricsIn)), timer(ioc),
triggerIds(collectTriggerIds(ioc)), reportStorage(reportStorageIn),
enabled(enabledIn), clock(std::move(clock)), messanger(ioc)
@@ -62,8 +64,11 @@
dbusIface.register_method("Delete", [this, &ioc, &reportManager] {
if (persistency)
{
- reportStorage.remove(fileName());
+ persistency = false;
+
+ reportIface->signal_property("Persistency");
}
+
boost::asio::post(ioc, [this, &reportManager] {
reportManager.removeReport(this);
});
@@ -117,6 +122,21 @@
});
}
+Report::~Report()
+{
+ if (persistency)
+ {
+ if (shouldStoreMetricValues())
+ {
+ storeConfiguration();
+ }
+ }
+ else
+ {
+ reportStorage.remove(reportFileName());
+ }
+}
+
uint64_t Report::getSensorCount(
const std::vector<std::shared_ptr<interfaces::Metric>>& metrics)
{
@@ -242,7 +262,7 @@
}
else
{
- reportStorage.remove(fileName());
+ reportStorage.remove(reportFileName());
persistency = false;
}
return 1;
@@ -458,10 +478,9 @@
}
}
- readings = {
+ std::get<0>(readings) =
std::chrono::duration_cast<Milliseconds>(clock->systemTimestamp())
- .count(),
- std::vector<ReadingData>(readingsBuffer.begin(), readingsBuffer.end())};
+ .count();
if (utils::contains(reportActions, ReportAction::emitsReadingsUpdate))
{
@@ -469,6 +488,12 @@
}
}
+bool Report::shouldStoreMetricValues() const
+{
+ return reportingType != ReportingType::onRequest &&
+ reportUpdates == ReportUpdates::appendStopsWhenFull;
+}
+
bool Report::storeConfiguration() const
{
try
@@ -493,7 +518,12 @@
return metric->dumpConfiguration();
});
- reportStorage.store(fileName(), data);
+ if (shouldStoreMetricValues())
+ {
+ data["MetricValues"] = utils::toLabeledReadings(readings);
+ }
+
+ reportStorage.store(reportFileName(), data);
}
catch (const std::exception& e)
{
@@ -506,7 +536,7 @@
return true;
}
-interfaces::JsonStorage::FilePath Report::fileName() const
+interfaces::JsonStorage::FilePath Report::reportFileName() const
{
return interfaces::JsonStorage::FilePath{
std::to_string(std::hash<std::string>{}(id))};
diff --git a/src/report.hpp b/src/report.hpp
index 213265c..6d8c6b4 100644
--- a/src/report.hpp
+++ b/src/report.hpp
@@ -7,6 +7,7 @@
#include "interfaces/report.hpp"
#include "interfaces/report_factory.hpp"
#include "interfaces/report_manager.hpp"
+#include "types/readings.hpp"
#include "types/report_action.hpp"
#include "types/report_types.hpp"
#include "types/report_updates.hpp"
@@ -60,7 +61,8 @@
interfaces::JsonStorage& reportStorage,
std::vector<std::shared_ptr<interfaces::Metric>> metrics,
const interfaces::ReportFactory& reportFactory, const bool enabled,
- std::unique_ptr<interfaces::Clock> clock);
+ std::unique_ptr<interfaces::Clock> clock, Readings);
+ ~Report();
Report(const Report&) = delete;
Report(Report&&) = delete;
@@ -96,10 +98,11 @@
void setReportUpdates(const ReportUpdates newReportUpdates);
static uint64_t getSensorCount(
const std::vector<std::shared_ptr<interfaces::Metric>>& metrics);
- interfaces::JsonStorage::FilePath fileName() const;
+ interfaces::JsonStorage::FilePath reportFileName() const;
std::unordered_set<std::string>
collectTriggerIds(boost::asio::io_context& ioc) const;
bool storeConfiguration() const;
+ bool shouldStoreMetricValues() const;
void updateReadings();
void updateReportingType(ReportingType);
@@ -114,8 +117,8 @@
uint64_t sensorCount;
std::optional<uint64_t> appendLimit;
ReportUpdates reportUpdates;
- CircularVector<ReadingData> readingsBuffer;
Readings readings = {};
+ CircularVector<ReadingData> readingsBuffer;
std::shared_ptr<sdbusplus::asio::object_server> objServer;
std::unique_ptr<sdbusplus::asio::dbus_interface> reportIface;
std::unique_ptr<sdbusplus::asio::dbus_interface> deleteIface;
diff --git a/src/report_factory.cpp b/src/report_factory.cpp
index 0d7f011..1c530f3 100644
--- a/src/report_factory.cpp
+++ b/src/report_factory.cpp
@@ -23,8 +23,8 @@
uint64_t appendLimit, const ReportUpdates reportUpdates,
interfaces::ReportManager& reportManager,
interfaces::JsonStorage& reportStorage,
- std::vector<LabeledMetricParameters> labeledMetricParams,
- bool enabled) const
+ std::vector<LabeledMetricParameters> labeledMetricParams, bool enabled,
+ Readings readings) const
{
auto metrics = utils::transform(
labeledMetricParams,
@@ -40,11 +40,11 @@
std::make_unique<Clock>());
});
- return std::make_unique<Report>(bus->get_io_context(), objServer, id, name,
- reportingType, reportActions, period,
- appendLimit, reportUpdates, reportManager,
- reportStorage, std::move(metrics), *this,
- enabled, std::make_unique<Clock>());
+ return std::make_unique<Report>(
+ bus->get_io_context(), objServer, id, name, reportingType,
+ reportActions, period, appendLimit, reportUpdates, reportManager,
+ reportStorage, std::move(metrics), *this, enabled,
+ std::make_unique<Clock>(), std::move(readings));
}
void ReportFactory::updateMetrics(
diff --git a/src/report_factory.hpp b/src/report_factory.hpp
index 8431f40..e8729b1 100644
--- a/src/report_factory.hpp
+++ b/src/report_factory.hpp
@@ -38,7 +38,7 @@
interfaces::ReportManager& reportManager,
interfaces::JsonStorage& reportStorage,
std::vector<LabeledMetricParameters> labeledMetricParams,
- bool enabled) const override;
+ bool enabled, Readings) const override;
private:
Sensors getSensors(const std::vector<LabeledSensorInfo>& sensorPaths) const;
diff --git a/src/report_manager.cpp b/src/report_manager.cpp
index 7600088..926b642 100644
--- a/src/report_manager.cpp
+++ b/src/report_manager.cpp
@@ -205,7 +205,7 @@
return addReport(reportId, reportName, reportingType, reportActions,
interval, appendLimit, reportUpdates,
- std::move(labeledMetricParams), enabled);
+ std::move(labeledMetricParams), enabled, Readings{});
}
interfaces::Report& ReportManager::addReport(
@@ -214,7 +214,7 @@
const std::vector<ReportAction>& reportActions, Milliseconds interval,
const uint64_t appendLimit, const ReportUpdates reportUpdates,
std::vector<LabeledMetricParameters> labeledMetricParams,
- const bool enabled)
+ const bool enabled, Readings readings)
{
const auto existingReportIds = utils::transform(
reports, [](const auto& report) { return report->getId(); });
@@ -225,9 +225,10 @@
verifyAddReport(id, name, reportingType, interval, reportUpdates,
appendLimit, labeledMetricParams);
- reports.emplace_back(reportFactory->make(
- id, name, reportingType, reportActions, interval, appendLimit,
- reportUpdates, *this, *reportStorage, labeledMetricParams, enabled));
+ reports.emplace_back(
+ reportFactory->make(id, name, reportingType, reportActions, interval,
+ appendLimit, reportUpdates, *this, *reportStorage,
+ labeledMetricParams, enabled, std::move(readings)));
return *reports.back();
}
@@ -263,10 +264,19 @@
data->at("ReadingParameters")
.get<std::vector<LabeledMetricParameters>>();
+ Readings readings = {};
+
+ if (auto it = data->find("MetricValues"); it != data->end())
+ {
+ const auto labeledReadings = it->get<LabeledReadings>();
+ readings = utils::toReadings(labeledReadings);
+ }
+
addReport(id, name, utils::toReportingType(reportingType),
reportActions, Milliseconds(interval), appendLimit,
utils::toReportUpdates(reportUpdates),
- std::move(readingParameters), enabled);
+ std::move(readingParameters), enabled,
+ std::move(readings));
}
catch (const std::exception& e)
{
diff --git a/src/report_manager.hpp b/src/report_manager.hpp
index 96e7cab..d5653b2 100644
--- a/src/report_manager.hpp
+++ b/src/report_manager.hpp
@@ -50,12 +50,14 @@
const std::vector<ReportAction>& reportActions, Milliseconds interval,
const uint64_t appendLimit, const ReportUpdates reportUpdates,
ReadingParameters metricParams, const bool enabled);
- interfaces::Report& addReport(
- const std::string& reportId, const std::string& reportName,
- const ReportingType reportingType,
- const std::vector<ReportAction>& reportActions, Milliseconds interval,
- const uint64_t appendLimit, const ReportUpdates reportUpdates,
- std::vector<LabeledMetricParameters> metricParams, const bool enabled);
+ interfaces::Report&
+ addReport(const std::string& reportId, const std::string& reportName,
+ const ReportingType reportingType,
+ const std::vector<ReportAction>& reportActions,
+ Milliseconds interval, const uint64_t appendLimit,
+ const ReportUpdates reportUpdates,
+ std::vector<LabeledMetricParameters> metricParams,
+ const bool enabled, Readings);
void loadFromPersistent();
public:
diff --git a/src/types/readings.cpp b/src/types/readings.cpp
new file mode 100644
index 0000000..2f6246b
--- /dev/null
+++ b/src/types/readings.cpp
@@ -0,0 +1,28 @@
+#include "types/readings.hpp"
+
+#include "utils/transform.hpp"
+
+namespace utils
+{
+
+namespace ts = utils::tstring;
+
+LabeledReadings toLabeledReadings(const Readings& readings)
+{
+ return LabeledReadings{
+ std::get<0>(readings),
+ utils::transform(std::get<1>(readings), [](const auto& readingData) {
+ return LabeledReadingData{readingData};
+ })};
+}
+
+Readings toReadings(const LabeledReadings& labeledReadings)
+{
+ return Readings{labeledReadings.at_label<ts::Timestamp>(),
+ utils::transform(labeledReadings.at_label<ts::Readings>(),
+ [](const auto& labeledReadingData) {
+ return labeledReadingData.to_tuple();
+ })};
+}
+
+} // namespace utils
diff --git a/src/types/readings.hpp b/src/types/readings.hpp
new file mode 100644
index 0000000..6749bbf
--- /dev/null
+++ b/src/types/readings.hpp
@@ -0,0 +1,24 @@
+#pragma once
+
+#include "utils/labeled_tuple.hpp"
+#include "utils/tstring.hpp"
+
+using ReadingData = std::tuple<std::string, std::string, double, uint64_t>;
+using Readings = std::tuple<uint64_t, std::vector<ReadingData>>;
+
+using LabeledReadingData =
+ utils::LabeledTuple<ReadingData, utils::tstring::MetricId,
+ utils::tstring::MetricProperty,
+ utils::tstring::MetricValue, utils::tstring::Timestamp>;
+
+using LabeledReadings =
+ utils::LabeledTuple<std::tuple<uint64_t, std::vector<LabeledReadingData>>,
+ utils::tstring::Timestamp, utils::tstring::Readings>;
+
+namespace utils
+{
+
+LabeledReadings toLabeledReadings(const Readings&);
+Readings toReadings(const LabeledReadings&);
+
+} // namespace utils
diff --git a/src/types/report_types.hpp b/src/types/report_types.hpp
index c0f7b39..d927d0e 100644
--- a/src/types/report_types.hpp
+++ b/src/types/report_types.hpp
@@ -30,9 +30,5 @@
utils::tstring::Id, utils::tstring::CollectionTimeScope,
utils::tstring::CollectionDuration>;
-using ReadingData = std::tuple<std::string, std::string, double, uint64_t>;
-
-using Readings = std::tuple<uint64_t, std::vector<ReadingData>>;
-
ReadingParameters
toReadingParameters(const std::vector<LabeledMetricParameters>& labeled);
diff --git a/src/utils/circular_vector.hpp b/src/utils/circular_vector.hpp
index ba185ec..f7ac8e5 100644
--- a/src/utils/circular_vector.hpp
+++ b/src/utils/circular_vector.hpp
@@ -4,7 +4,8 @@
class CircularVector
{
public:
- explicit CircularVector(size_t maxSizeIn) : maxSize(maxSizeIn)
+ explicit CircularVector(std::vector<T>& externalVec, size_t maxSizeIn) :
+ vec(externalVec), maxSize(maxSizeIn)
{}
template <class... Args>
@@ -53,7 +54,7 @@
}
private:
+ std::vector<T>& vec;
size_t maxSize = 0;
size_t idx = 0;
- std::vector<T> vec;
};
diff --git a/src/utils/labeled_tuple.hpp b/src/utils/labeled_tuple.hpp
index 71bf4b0..e6203dd 100644
--- a/src/utils/labeled_tuple.hpp
+++ b/src/utils/labeled_tuple.hpp
@@ -76,6 +76,11 @@
return j;
}
+ const tuple_type& to_tuple() const
+ {
+ return value;
+ }
+
void from_json(const nlohmann::json& j)
{
from_json_all(j, std::make_index_sequence<sizeof...(Args)>());
diff --git a/src/utils/tstring.hpp b/src/utils/tstring.hpp
index e4529d8..67ad3c4 100644
--- a/src/utils/tstring.hpp
+++ b/src/utils/tstring.hpp
@@ -144,5 +144,45 @@
}
};
+struct MetricId
+{
+ static std::string str()
+ {
+ return "MetricId";
+ }
+};
+
+struct MetricProperty
+{
+ static std::string str()
+ {
+ return "MetricProperty";
+ }
+};
+
+struct MetricValue
+{
+ static std::string str()
+ {
+ return "MetricValue";
+ }
+};
+
+struct Timestamp
+{
+ static std::string str()
+ {
+ return "Timestamp";
+ }
+};
+
+struct Readings
+{
+ static std::string str()
+ {
+ return "Readings";
+ }
+};
+
} // namespace tstring
} // namespace utils