blob: f09420a662f2014c29ee11db982c25226c8aa637 [file] [log] [blame]
#ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_COLLECTOR_METRIC_COLLECTOR_H_
#define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_COLLECTOR_METRIC_COLLECTOR_H_
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "absl/container/flat_hash_map.h"
#include "absl/status/statusor.h"
#include "boost/asio.hpp" //NOLINT: boost::asio is commonly used in BMC
#include "thread/thread.h"
#include "time/clock.h"
#include "nlohmann/json.hpp"
#include "tlbmc/collector/collector.h"
#include "software_metrics_config.pb.h"
#include "tlbmc/metrics/software_metrics.h"
#include "software_metrics.pb.h"
#include "tlbmc/scheduler/scheduler.h"
#include "tlbmc/utils/command_executor.h"
namespace milotic_tlbmc {
struct MetricThreadManager {
explicit MetricThreadManager(ecclesia::Clock* clock)
: task_scheduler(std::make_unique<TaskScheduler>(clock)) {}
~MetricThreadManager();
std::vector<std::unique_ptr<ecclesia::ThreadInterface>> threads;
std::vector<std::shared_ptr<boost::asio::io_context>> io_contexts;
std::vector<
boost::asio::executor_work_guard<boost::asio::io_context::executor_type>>
work_guards;
std::unique_ptr<TaskScheduler> task_scheduler;
int task_id;
};
class MetricCollector : public Collector {
public:
// Parameters for creating a metric collector.
struct Params {
// Using a thread factory to allow us to switch to fibers in future when it
// gets open sourced.
ecclesia::ThreadFactoryInterface* thread_factory =
ecclesia::GetDefaultThreadFactory();
ecclesia::Clock* clock = ecclesia::Clock::RealClock();
SoftwareMetricsConfig metric_configs;
absl::flat_hash_map<std::string, absl::StatusOr<std::string>>
executor_command_map;
};
static absl::StatusOr<std::unique_ptr<MetricCollector>> Create(
const Params& params);
static absl::StatusOr<std::unique_ptr<MetricCollector>> CreateForUnitTest(
MetricCollector::Params& params);
virtual SoftwareMetricsValue GetMetricValues() const;
virtual SocketStatStates GetSocketStatMetricsValues() const;
virtual NetFilterStates GetNetFilterValues() const;
nlohmann::json ToJson() const override;
nlohmann::json GetSchedulerStats() const override {
return thread_manager_->task_scheduler->ToJson();
}
CommandExecutor* GetSoftwareMetricsExecutorForTest() const;
protected:
// Protected constructor to allow mocking.
MetricCollector() = default;
private:
MetricCollector(std::shared_ptr<SoftwareMetrics>&& metrics,
std::unique_ptr<MetricThreadManager>&& thread_manager)
: metrics_table_(std::move(metrics)),
thread_manager_(std::move(thread_manager)) {}
nlohmann::json ExtractSocketStats() const;
nlohmann::json ExtractNetfilterStats() const;
// In today's use case, we will never have dynamic set of metrics. All metrics
// are created during daemon start-up.
const std::shared_ptr<SoftwareMetrics> metrics_table_;
const std::unique_ptr<MetricThreadManager> thread_manager_;
};
class EmptyMetricCollector final : public MetricCollector {
public:
static std::unique_ptr<EmptyMetricCollector> Create();
SoftwareMetricsValue GetMetricValues() const override;
SocketStatStates GetSocketStatMetricsValues() const override;
NetFilterStates GetNetFilterValues() const override;
nlohmann::json GetSchedulerStats() const override;
nlohmann::json ToJson() const override;
};
} // namespace milotic_tlbmc
#endif // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_COLLECTOR_METRIC_COLLECTOR_H_