diff --git a/examples/cpp/HelloWorldExample/Monitor.cpp b/examples/cpp/HelloWorldExample/Monitor.cpp index 3dc318b98..0c7fbc147 100644 --- a/examples/cpp/HelloWorldExample/Monitor.cpp +++ b/examples/cpp/HelloWorldExample/Monitor.cpp @@ -18,6 +18,8 @@ #include #include +#include +#include #include #include #include @@ -61,11 +63,16 @@ void Monitor::stop() bool Monitor::init( uint32_t domain, uint32_t n_bins, - uint32_t t_interval) + uint32_t t_interval, + std::string dump_file /* = "" */, + bool reset /* = false */) { n_bins_ = n_bins; t_interval_ = t_interval; monitor_id_ = StatisticsBackend::init_monitor(domain); + dump_file_ = dump_file; + reset_ = reset; + if (!monitor_id_.is_valid()) { std::cout << "Error creating monitor" << std::endl; @@ -97,9 +104,48 @@ void Monitor::run() std::cout << std::endl; get_fastdds_latency_mean(); get_publication_throughput_mean(); + + // Dump data to file and THEN remove the inactive entities. This means inactive entities would appear in this dump file. + if (!dump_file_.empty()) + { + dump_in_file(); + } + + if (reset_) + { + clear_inactive_entities(); + std::cout << "Removing inactive entities from Statistics Backend." << std::endl; + } } } +void Monitor::dump_in_file() +{ + // Get current timestamp + auto t = std::time(nullptr); + auto tm = *std::localtime(&t); + std::ostringstream oss; + oss << std::put_time(&tm, "%Y-%m-%d_%H-%M-%S"); + std::string current_time = oss.str(); + + // Get file name + std::string complete_file_name = dump_file_ + "_" + current_time + ".json"; + std::cout << "Dumping info in file " << complete_file_name << std::endl; + + // Bump to get json + auto dump = StatisticsBackend::dump_database(reset_); + + // Store it in json file + std::ofstream file(complete_file_name); + // Pretty print json + file << std::setw(4) << dump << std::endl; +} + +void Monitor::clear_inactive_entities() +{ + StatisticsBackend::clear_inactive_entities(); +} + /*************************************************************** * Implementation of the functions to collect the data. ***************************************************************/ diff --git a/examples/cpp/HelloWorldExample/Monitor.h b/examples/cpp/HelloWorldExample/Monitor.h index 58eaace71..f13a8e870 100644 --- a/examples/cpp/HelloWorldExample/Monitor.h +++ b/examples/cpp/HelloWorldExample/Monitor.h @@ -45,7 +45,9 @@ class Monitor bool init( uint32_t domain, uint32_t n_bins, - uint32_t t_interval); + uint32_t t_interval, + std::string dump_file = "", + bool reset = false); //! Run the monitor void run(); @@ -68,6 +70,19 @@ class Monitor protected: + /** + * @brief Bump the internal database in file \c dump_file_ . + * + * If \c reset_ is active, it clears the statistical data. + */ + void dump_in_file(); + + /** + * @brief Clear the inactive entities of the StatisticsBackend + * + */ + void clear_inactive_entities(); + class Listener : public eprosima::statistics_backend::PhysicalListener { public: @@ -132,6 +147,12 @@ class Monitor //! Time interval of the returned measures uint32_t t_interval_; + //! Path where the dump_file will be stored + std::string dump_file_; + + //! Whether the internal data must be removed every interval + bool reset_; + //! Member used for control flow purposes static std::atomic stop_; diff --git a/examples/cpp/HelloWorldExample/arg_configuration.h b/examples/cpp/HelloWorldExample/arg_configuration.h index 6488cbf47..9814d618d 100644 --- a/examples/cpp/HelloWorldExample/arg_configuration.h +++ b/examples/cpp/HelloWorldExample/arg_configuration.h @@ -109,7 +109,9 @@ enum optionIndex INTERVAL, DOMAIN_ID, N_BINS, - T_INTERVAL + T_INTERVAL, + DUMP_FILE, + RESET }; const option::Descriptor usage[] = { @@ -139,7 +141,10 @@ const option::Descriptor usage[] = { " (0 => no mean calculation, return raw data)." }, { T_INTERVAL, 0, "t", "time", Arg::Numeric, " -t \t--time= \tDuration in seconds of each time frame (Default: 5)." }, - + { DUMP_FILE, 0, "f", "dump-file", Arg::String, + " -f \t--dump-file \tIf set, path where the dump file will be stored (timestamp will be added to file name)." }, + { RESET, 0, "r", "reset", Arg::None, + " -r \t--reset \tIf set, the Monitor will remove internal data and inactive entities every time interval ." }, { 0, 0, 0, 0, 0, 0 } }; diff --git a/examples/cpp/HelloWorldExample/main.cpp b/examples/cpp/HelloWorldExample/main.cpp index 2268697cb..fe3f1b851 100644 --- a/examples/cpp/HelloWorldExample/main.cpp +++ b/examples/cpp/HelloWorldExample/main.cpp @@ -61,6 +61,9 @@ int main( // Monitor params int n_bins = 1; int t_interval = 5; + bool reset = false; + std::string dump_file = ""; + if (argc > 1) { if (!strcmp(argv[1], "publisher")) @@ -177,6 +180,28 @@ int main( } break; + case optionIndex::RESET: + if (type == MONITOR) + { + reset = true; + } + else + { + print_warning("monitor", opt.name); + } + break; + + case optionIndex::DUMP_FILE: + if (type == MONITOR) + { + dump_file = opt.arg; + } + else + { + print_warning("monitor", opt.name); + } + break; + case optionIndex::UNKNOWN_OPT: std::cerr << "ERROR: " << opt.name << " is not a valid argument." << std::endl; option::printUsage(fwrite, stdout, usage, columns); @@ -215,8 +240,12 @@ int main( case MONITOR: { Monitor monitor; - if (monitor.init(static_cast(domain), static_cast(n_bins), - static_cast(t_interval))) + if (monitor.init( + static_cast(domain), + static_cast(n_bins), + static_cast(t_interval), + dump_file, + reset)) { monitor.run(); }