//------------------------------------------------------------------------------ // Author: Andrey Kuznetsov // Description: Representer of statistics // Copyright (c) 2015 EPAM Systems //------------------------------------------------------------------------------ /* This file is part of Nfstrace. Nfstrace is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2 of the License. Nfstrace is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Nfstrace. If not, see . */ //------------------------------------------------------------------------------ #include #include #include #include "representer.h" //------------------------------------------------------------------------------ using namespace NST::breakdown; //------------------------------------------------------------------------------ NST::breakdown::Representer::Representer(std::ostream& o, NST::breakdown::CommandRepresenter* cmd_representer, size_t space_for_cmd_name) : out(o) , cmd_representer(cmd_representer) , space_for_cmd_name(space_for_cmd_name) { } void Representer::flush_statistics(const Statistics& statistics) { out << "### Breakdown analyzer ###" << std::endl << cmd_representer->protocol_name() << " protocol"; if(statistics.has_session()) { out << std::endl; statistics.for_each_procedure([&](const BreakdownCounter& breakdown, size_t procedure) { onProcedureInfoPrinted(out, breakdown, procedure); size_t procedure_count = breakdown[procedure].get_count(); out.width(space_for_cmd_name); out << std::left << cmd_representer->command_name(procedure); out.width(5); out << std::right << procedure_count; out.width(7); out.setf(std::ios::fixed, std::ios::floatfield); out.precision(2); out << (breakdown.get_total_count() ? ((1.0 * procedure_count / breakdown.get_total_count()) * 100.0) : 0); out.setf(std::ios::fixed | std::ios::scientific, std::ios::floatfield); out << '%' << std::endl; }); out << "Per connection info: " << std::endl; statistics.for_each_session([&](const Session& session) { std::stringstream ssession; print_session(ssession, session); print_per_session(statistics, session, ssession.str()); std::ofstream file("breakdown_" + ssession.str() + ".dat", std::ios::out | std::ios::trunc); store_per_session(file, statistics, session, ssession.str()); }); } else { out << ": Data transmission has not been detected." << std::endl; } } void Representer::store_per_session(std::ostream& file, const Statistics& statistics, const Session& session, const std::string& ssession) const { //TODO: does it make sense to join store_per_session & print_per_session? file << "Session: " << ssession << std::endl; statistics.for_each_procedure_in_session(session, [&](const BreakdownCounter& breakdown, size_t procedure) { uint64_t s_total_proc = breakdown.get_total_count(); file << cmd_representer->command_name(procedure); file << ' ' << breakdown[procedure].get_count() << ' '; file << (s_total_proc ? (((long double)(breakdown[procedure].get_count()) / s_total_proc) * 100) : 0); file << ' ' << to_sec(breakdown[procedure].get_min()) << ' ' << to_sec(breakdown[procedure].get_max()) << ' ' << breakdown[procedure].get_avg() << ' ' << breakdown[procedure].get_st_dev() << std::endl; }); } void Representer::print_per_session(const Statistics& statistics, const Session& session, const std::string& ssession) const { out << "Session: " << ssession << std::endl; statistics.for_each_procedure_in_session(session, [&](const BreakdownCounter& breakdown, size_t procedure) { uint64_t s_total_proc = breakdown.get_total_count(); onProcedureInfoPrinted(out, breakdown, procedure); out.width(22); out << std::left << cmd_representer->command_name(procedure); out.width(6); out << " Count:"; out.width(5); out << std::right << breakdown[procedure].get_count() << ' '; out.precision(2); out << '('; out.width(6); out << std::fixed << (s_total_proc ? (static_cast(breakdown[procedure].get_count()) * 100 / s_total_proc) : 0); out << "%) Min: "; out.precision(3); out << std::fixed << to_sec(breakdown[procedure].get_min()) << " Max: " << std::fixed << to_sec(breakdown[procedure].get_max()) << " Avg: " << std::fixed << breakdown[procedure].get_avg(); out.precision(8); out << " StDev: " << std::fixed << breakdown[procedure].get_st_dev() << std::endl; }); } void Representer::onProcedureInfoPrinted(std::ostream& o, const BreakdownCounter& breakdown, unsigned procedure) const { if(procedure == 0) { o << "Total operations: " << breakdown.get_total_count() << ". Per operation:" << std::endl; } } //------------------------------------------------------------------------------