blob: bb164d92ee02ccd2e7c561814e09faba171181e4 [file] [log] [blame]
#pragma once
#include "interfaces/clock.hpp"
#include "interfaces/json_storage.hpp"
#include "interfaces/metric.hpp"
#include "interfaces/metric_listener.hpp"
#include "interfaces/report.hpp"
#include "interfaces/report_factory.hpp"
#include "interfaces/report_manager.hpp"
#include "state.hpp"
#include "types/error_message.hpp"
#include "types/readings.hpp"
#include "types/report_action.hpp"
#include "types/report_types.hpp"
#include "types/report_updates.hpp"
#include "types/reporting_type.hpp"
#include "utils/circular_vector.hpp"
#include "utils/dbus_path_utils.hpp"
#include "utils/ensure.hpp"
#include "utils/messanger.hpp"
#include <boost/asio/io_context.hpp>
#include <boost/asio/steady_timer.hpp>
#include <sdbusplus/asio/object_server.hpp>
#include <chrono>
#include <memory>
#include <unordered_set>
class Report : public interfaces::Report, public interfaces::MetricListener
{
class OnChangeContext
{
public:
OnChangeContext(Report& report) : report(report) {}
~OnChangeContext()
{
if (updated)
{
report.updateReadings();
}
}
void metricUpdated()
{
updated = true;
}
private:
Report& report;
bool updated = false;
};
public:
Report(boost::asio::io_context& ioc,
const std::shared_ptr<sdbusplus::asio::object_server>& objServer,
const std::string& reportId, const std::string& reportName,
const ReportingType reportingType,
std::vector<ReportAction> reportActions, const Milliseconds period,
const uint64_t appendLimitIn, const ReportUpdates reportUpdatesIn,
interfaces::ReportManager& reportManager,
interfaces::JsonStorage& reportStorage,
std::vector<std::shared_ptr<interfaces::Metric>> metrics,
const interfaces::ReportFactory& reportFactory, const bool enabled,
std::unique_ptr<interfaces::Clock> clock, Readings);
~Report();
Report(const Report&) = delete;
Report(Report&&) = delete;
Report& operator=(const Report&) = delete;
Report& operator=(Report&&) = delete;
std::string getId() const override
{
return id;
}
std::string getPath() const override
{
return path.str;
}
void metricUpdated() override;
void activate();
void deactivate();
private:
std::unique_ptr<sdbusplus::asio::dbus_interface>
makeReportInterface(const interfaces::ReportFactory& reportFactory);
static void timerProcForPeriodicReport(boost::system::error_code,
Report& self);
static void timerProcForOnChangeReport(boost::system::error_code,
Report& self);
void scheduleTimerForPeriodicReport(Milliseconds interval);
void scheduleTimerForOnChangeReport();
uint64_t deduceBufferSize(const ReportUpdates reportUpdatesIn,
const ReportingType reportingTypeIn) const;
void setReadingBuffer(const ReportUpdates newReportUpdates);
void setReportUpdates(const ReportUpdates newReportUpdates);
static uint64_t getMetricCount(
const std::vector<std::shared_ptr<interfaces::Metric>>& metrics);
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 scheduleTimer();
static std::vector<ErrorMessage> verify(ReportingType, Milliseconds);
std::string id;
const sdbusplus::message::object_path path;
std::string name;
ReportingType reportingType;
Milliseconds interval;
std::unordered_set<ReportAction> reportActions;
ReadingParameters readingParameters;
bool persistency = false;
uint64_t metricCount;
uint64_t appendLimit;
ReportUpdates reportUpdates;
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;
std::vector<std::shared_ptr<interfaces::Metric>> metrics;
boost::asio::steady_timer timer;
std::unordered_set<std::string> triggerIds;
interfaces::JsonStorage& reportStorage;
std::unique_ptr<interfaces::Clock> clock;
utils::Messanger messanger;
std::optional<OnChangeContext> onChangeContext;
utils::Ensure<std::function<void()>> unregisterFromMetrics;
State<ReportFlags, Report, ReportFlags::enabled, ReportFlags::valid> state{
*this};
public:
static constexpr const char* reportIfaceName =
"xyz.openbmc_project.Telemetry.Report";
static constexpr const char* deleteIfaceName =
"xyz.openbmc_project.Object.Delete";
static constexpr size_t reportVersion = 7;
};