Program Listing for File file_sink_registerer.hpp

Return to documentation for file (rcppsw/metrics/file_sink_registerer.hpp)

#pragma once

/*******************************************************************************
 * Includes
 ******************************************************************************/
#include <memory>
#include <utility>
#include <string>

#include "rcppsw/metrics/config/file_sink_config.hpp"
#include "rcppsw/metrics/fs_output_manager.hpp"
#include "rcppsw/utils/maskable_enum.hpp"
#include "rcppsw/metrics/creatable_collector_set.hpp"
#include "rcppsw/metrics/file_sink.hpp"

/*******************************************************************************
 * Namespaces/Decls
 ******************************************************************************/
namespace rcppsw::metrics {

/*******************************************************************************
 * Class Definitions
 ******************************************************************************/

class file_sink_registerer : public rer::client<file_sink_registerer> {
 public:
  file_sink_registerer(void)
      : ER_CLIENT_INIT() {}

  file_sink_registerer& operator=(const file_sink_registerer&) = default;
  file_sink_registerer(const file_sink_registerer&) = default;

  template <typename TIterator, typename TSink>
  void emit_diagnostic(const TIterator& it,
                       const collector_registration_spec<TSink>& spec) {
      ER_INFO("Metrics enabled: "
              "xml_name='%s',scoped_name='%s',fpath='%s',output_interval=%lu,"
              "mode=%x",
              it->input_name.c_str(),
              it->scoped_name.c_str(),
              spec.sink->fpath().c_str(),
              spec.sink->output_interval().v(),
              rcppsw::as_underlying(spec.sink->output_mode()));
  }

  template<typename TSink>
  collector_registration_spec<TSink>
  calc_registration_spec(fs_output_manager* manager,
                         const rmconfig::file_sink_config* const config,
                         const std::string& xml_name,
                         const rmetrics::output_mode& allowed) const {
    auto append_it = config->append.enabled.find(xml_name);
    auto truncate_it = config->truncate.enabled.find(xml_name);
    auto create_it = config->create.enabled.find(xml_name);
    size_t sum =
        static_cast<size_t>(append_it != config->append.enabled.end()) +
        static_cast<size_t>(truncate_it != config->truncate.enabled.end()) +
        static_cast<size_t>(create_it != config->create.enabled.end());
    ER_ASSERT(sum <= 1,
              "Collector '%s' present in more than 1 FILE sink collector group in XML file",
              xml_name.c_str());

    collector_registration_spec<TSink> ret;
    if (append_it != config->append.enabled.end()) {
      ER_ASSERT(allowed & rmetrics::output_mode::ekAPPEND,
                "Output mode %d for collector '%s' does not contain ekAPPEND",
                rcppsw::as_underlying(allowed),
                xml_name.c_str());
      ret.is_enabled = true;
      ret.sink = std::make_unique<TSink>(manager->metrics_path() / append_it->second,
                                         rmetrics::output_mode::ekAPPEND,
                                         config->append.output_interval);
    } else if (truncate_it != config->truncate.enabled.end()) {
      ER_ASSERT(allowed & rmetrics::output_mode::ekTRUNCATE,
                "Output mode %d for collector '%s' does not contain ekTRUNCATE",
                rcppsw::as_underlying(allowed),
                xml_name.c_str());

      ret.is_enabled = true;
      ret.sink = std::make_unique<TSink>(manager->metrics_path() / truncate_it->second,
                                         rmetrics::output_mode::ekTRUNCATE,
                                         config->truncate.output_interval);
    } else if (create_it != config->create.enabled.end()) {
      ER_ASSERT(allowed & rmetrics::output_mode::ekCREATE,
                "Output mode %d for collector '%s' does not contain ekCREATE",
                rcppsw::as_underlying(allowed),
                xml_name.c_str());
      /* Give them their own directory to output stuff into for cleanliness */
      auto file_dir = fs::path(create_it->second);
      file_dir.replace_extension(fs::path());
      auto dirpath = manager->metrics_path() / file_dir;
      fs::create_directories(dirpath);

      ret.is_enabled = true;
      ret.sink = std::make_unique<TSink>(dirpath / create_it->second,
                                         rmetrics::output_mode::ekCREATE,
                                         config->create.output_interval);
    }
    return ret;
  }
};

} /* namespace rcppsw::metrics */