Skip to content

Commit

Permalink
Merge "Issue: Requirement of DBTable and TaskStats counters for Intro…
Browse files Browse the repository at this point in the history
…spect in R2.22.x Fix: Added support for DBTable and TaskStats counters in release R2.22.x. Added support for FlowStats as well." into R2.22.x
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed May 17, 2016
2 parents c8369e3 + 30c2da3 commit 7b17cee
Show file tree
Hide file tree
Showing 9 changed files with 573 additions and 44 deletions.
13 changes: 13 additions & 0 deletions src/vnsw/agent/cmn/agent.h
Expand Up @@ -201,6 +201,19 @@ extern void RouterIdDepInit(Agent *agent);

#define VROUTER_SERVER_PORT 20914

#define kInterfaceDbTablePrefix "db.interface"
#define kVnDbTablePrefix "db.vn"
#define kVmDbTablePrefix "db.vm"
#define kVrfDbTablePrefix "db.vrf.0"
#define kLoadBalnceDbTablePrefix "db.loadbalancer.0"
#define kMplsDbTablePrefix "db.mpls"
#define kAclDbTablePrefix "db.acl"
#define kV4UnicastRouteDbTableSuffix "uc.route.0"
#define kV6UnicastRouteDbTableSuffix "uc.route6.0"
#define kL2RouteDbTableSuffix "l2.route.0"
#define kMcastRouteDbTableSuffix "mc.route.0"
#define kEvpnRouteDbTableSuffix "evpn.route.0"

class Agent {
public:
static const uint32_t kDefaultMaxLinkLocalOpenFds = 2048;
Expand Down
1 change: 1 addition & 0 deletions src/vnsw/agent/oper/SConscript
Expand Up @@ -15,6 +15,7 @@ if '-fno-exceptions' in cflags:
except_env.Replace(CCFLAGS=cflags)

SandeshGenFiles = env.SandeshGenCpp('agent.sandesh')
SandeshGenFiles += env.SandeshGenCpp('agent_profile.sandesh')
SandeshGenFiles += env.SandeshGenCpp('multicast.sandesh')
SandeshGenSrcs = env.ExtractCpp(SandeshGenFiles)
sandesh_objs = AgentEnv.BuildExceptionCppObj(env, SandeshGenSrcs)
Expand Down
336 changes: 295 additions & 41 deletions src/vnsw/agent/oper/agent_profile.cc
Expand Up @@ -3,18 +3,25 @@
*/

#include <boost/uuid/uuid_io.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <vnc_cfg_types.h>
#include <base/util.h>

#include <db/db_partition.h>
#include <sandesh/sandesh.h>
#include <sandesh/sandesh_types.h>
#include <oper/agent_profile_types.h>
#include <cmn/agent_cmn.h>
#include <cfg/cfg_init.h>
#include <oper/operdb_init.h>
#include <oper/agent_profile.h>

#include <oper/vn.h>
#include <oper/physical_device_vn.h>
#include <oper/vm.h>
#include <oper/interface_common.h>
#include <filter/acl.h>
#include "db/db.h"

using namespace std;

AgentProfile::AgentProfile(Agent *agent, bool enable) :
Expand All @@ -36,55 +43,302 @@ AgentProfile::~AgentProfile() {
}

bool AgentProfile::TimerRun() {
ProfileData *data = GetLastProfileData();
data->Get(agent_);
if (pkt_flow_stats_cb_.empty() == false) {
pkt_flow_stats_cb_(data);
}
Log();
return true;
}

string GetProfileString(DBTable *table, const char *name) {
stringstream str;
str << setw(16) << name
<< " Size " << setw(8) << table->Size()
<< " Enqueue " << setw(8) << table->enqueue_count()
<< " Input " << setw(8) << table->input_count()
<< " Notify " << setw(8) << table->notify_count();
<< " Size " << setw(6) << table->Size()
<< " Enqueue " << setw(6) << table->enqueue_count()
<< " Input " << setw(6) << table->input_count()
<< " Notify " << setw(6) << table->notify_count();
return str.str();
}

string GetInterfaceProfileString(InterfaceTable *table, const char *name) {
stringstream str;
str << setw(4) << " LI " << setw(6) << table->li_count()
<< " VMI " << table->vmi_count() << " / "
<< setw(6) << table->active_vmi_count() << " / "
<< setw(6) << table->vmi_ifnode_to_req() << " / "
<< setw(6) << table->li_ifnode_to_req();
return GetProfileString(table, name) + str.str();
void AgentProfile::Log() {
}

void AgentProfile::Log() {
time_t now;
time(&now);

DBPartition *partition = agent_->db()->GetPartition(0);
TaskScheduler *sched = agent_->task_scheduler();
cout << "Time : " << setw(4) << (now - start_time_)
<< " #DBQueueLen(Curr/Total/Max) <"
<< " " << partition->request_queue_len()
<< " " << partition->total_request_count()
<< " " << partition->max_request_queue_len() << ">"
<< " #Task(Req/Done/Cancel) <" << sched->enqueue_count()
<< " " << sched->done_count()
<< " " << sched->cancel_count() << ">"
<< endl;

AgentConfig *cfg = agent_->cfg();
cout << " " << GetInterfaceProfileString(agent_->interface_table(),
"Interface") << endl;
cout << " " << GetProfileString(agent_->vn_table(), "VN") << endl;
cout << " " << GetProfileString(agent_->physical_device_vn_table(),
"Dev-Vn") << endl;
cout << " " << GetProfileString(cfg->cfg_vm_interface_table(),
"Cfg-VMI") << endl;
cout << " " << GetProfileString(cfg->cfg_logical_port_table(),
"Cfg-LI") << endl;
cout << endl;
ProfileData *AgentProfile::GetLastProfileData() {
uint16_t index = seconds_history_index_ % kSecondsHistoryCount;
seconds_history_index_++;
return &seconds_history_data_[index];
}

ProfileData *AgentProfile::GetProfileData(uint16_t index) {
return &seconds_history_data_[index];
}
//////////////////////////////////////////////////////////////////////////////
// ProfileData collection routines
//////////////////////////////////////////////////////////////////////////////
void ProfileData::DBTableStats::Reset() {
db_entry_count_ = 0;
walker_count_ = 0;
enqueue_count_ = 0;
input_count_ = 0;
notify_count_ = 0;
}

void ProfileData::DBTableStats::Get(const DBTable *table) {
db_entry_count_ = table->Size();
walker_count_ = table->walker_count();
enqueue_count_ = table->enqueue_count();
input_count_ = table->input_count();
notify_count_ = table->notify_count();
}

void ProfileData::DBTableStats::Accumulate(const DBTableBase *table) {
db_entry_count_ += table->Size();
walker_count_ += table->walker_count();
enqueue_count_ += table->enqueue_count();
input_count_ += table->input_count();
notify_count_ += table->notify_count();
}

void ProfileData::Get(Agent *agent) {
std::ostringstream str;
str << boost::posix_time::second_clock::local_time();
time_ = str.str();

DB::TableMap::const_iterator itr =
agent->db()->const_begin();
DB::TableMap::const_iterator itrend =
agent->db()->const_end();

profile_stats_table_.clear();
for ( ;itr != itrend; ++itr) {
if(itr->first.rfind(kV4UnicastRouteDbTableSuffix) !=
std::string::npos) {
inet4_routes_.Accumulate(itr->second);
} else if (itr->first.rfind(kV6UnicastRouteDbTableSuffix) !=
std::string::npos) {
inet6_routes_.Accumulate(itr->second);
} else if (itr->first.rfind(kL2RouteDbTableSuffix) !=
std::string::npos) {
bridge_routes_.Accumulate(itr->second);
} else if (itr->first.rfind(kMcastRouteDbTableSuffix) !=
std::string::npos) {
multicast_routes_.Accumulate(itr->second);
} else if (itr->first.rfind(kEvpnRouteDbTableSuffix) !=
std::string::npos) {
evpn_routes_.Accumulate(itr->second);
} else {
ProfileData::DBTableStats stats;
stats.Get(dynamic_cast<DBTable*>(itr->second));
profile_stats_table_.insert(make_pair(itr->first,stats));
}
}

TaskScheduler *sched = TaskScheduler::GetInstance();
task_stats_[0] = *sched->GetTaskGroupStats(sched->GetTaskId("Agent::FlowHandler"));
task_stats_[1] = *sched->GetTaskGroupStats(sched->GetTaskId("db::DBTable"));
task_stats_[2] = *sched->GetTaskGroupStats(sched->GetTaskId("Agent::StatsCollector"));
task_stats_[3] = *sched->GetTaskGroupStats(sched->GetTaskId("io::ReaderTask"));
task_stats_[4] = *sched->GetTaskGroupStats(sched->GetTaskId("Agent::PktFlowResponder"));
task_stats_[5] = *sched->GetTaskGroupStats(sched->GetTaskId("sandesh::RecvQueue"));
task_stats_[6] = *sched->GetTaskGroupStats(sched->GetTaskId("bgp::Config"));
task_stats_[7] = *sched->GetTaskGroupStats(sched->GetTaskId("Agent::KSync"));
}

//////////////////////////////////////////////////////////////////////////////
// Sandesh ProfileData routines
//////////////////////////////////////////////////////////////////////////////
static void DBStatsToSandesh(SandeshDBTableStats *stats, const string &table,
const ProfileData::DBTableStats &db_stats) {
stats->set_table(table);
stats->set_db_entry_count(db_stats.db_entry_count_);
stats->set_input_count(db_stats.input_count_);
stats->set_walker_count(db_stats.walker_count_);
stats->set_enqueue_count(db_stats.enqueue_count_);
stats->set_notify_count(db_stats.notify_count_);
}

static void GetDBTableStats(SandeshDBTableStatsInfo *stats, int index,
ProfileData *data) {
stats->set_index(index);
stats->set_time_str(data->time_);
std::vector<SandeshDBTableStats> db_stats_list;

SandeshDBTableStats db_stats;
std::map<std::string, ProfileData::DBTableStats >::iterator itr =
data->profile_stats_table_.begin();

DBStatsToSandesh(&db_stats, "Ipv4 Unicast route", data->inet4_routes_);
db_stats_list.push_back(db_stats);
DBStatsToSandesh(&db_stats, "Ipv6 Unicast route", data->inet6_routes_);
db_stats_list.push_back(db_stats);
DBStatsToSandesh(&db_stats, "Multicast route", data->multicast_routes_);
db_stats_list.push_back(db_stats);
DBStatsToSandesh(&db_stats, "Evpn route", data->evpn_routes_);
db_stats_list.push_back(db_stats);
DBStatsToSandesh(&db_stats, "Bridge", data->bridge_routes_);
db_stats_list.push_back(db_stats);
while (itr != data->profile_stats_table_.end()) {
if(itr->first.find(kInterfaceDbTablePrefix) != std::string::npos) {
DBStatsToSandesh(&db_stats, "Interface", itr->second);
db_stats_list.push_back(db_stats);
} else if (itr->first.find(kMplsDbTablePrefix) != std::string::npos) {
DBStatsToSandesh(&db_stats, "Mpls", itr->second);
db_stats_list.push_back(db_stats);
} else if (itr->first.find(kLoadBalnceDbTablePrefix) !=
std::string::npos) {
DBStatsToSandesh(&db_stats, "Loadbalancer", itr->second);
db_stats_list.push_back(db_stats);
} else if (itr->first.find(kVnDbTablePrefix) != std::string::npos) {
DBStatsToSandesh(&db_stats, "Vn", itr->second);
db_stats_list.push_back(db_stats);
} else if (itr->first.find(kVmDbTablePrefix) != std::string::npos) {
DBStatsToSandesh(&db_stats, "Vm", itr->second);
db_stats_list.push_back(db_stats);
} else if (itr->first.find(kVrfDbTablePrefix) != std::string::npos) {
DBStatsToSandesh(&db_stats, "Vrf", itr->second);
db_stats_list.push_back(db_stats);
} else if (itr->first.find(kAclDbTablePrefix) != std::string::npos) {
DBStatsToSandesh(&db_stats, "Acl", itr->second);
db_stats_list.push_back(db_stats);
}
++itr;
}

stats->set_stats(db_stats_list);
}

void SandeshDBTableStatsRequest::HandleRequest() const {
SandeshDBTableStatsList *resp = new SandeshDBTableStatsList();
resp->set_context(context());

Agent *agent = Agent::GetInstance();
AgentProfile *profile = agent->oper_db()->agent_profile();
uint16_t end = profile->seconds_history_index();
uint16_t start = 0;
if (end > AgentProfile::kSecondsHistoryCount)
start = end - AgentProfile::kSecondsHistoryCount;

std::vector<SandeshDBTableStatsInfo> stats_list;
for (uint16_t i = start; i < end; i++) {
uint16_t index = i % AgentProfile::kSecondsHistoryCount;
ProfileData *data = profile->GetProfileData(index);
SandeshDBTableStatsInfo stats;
GetDBTableStats(&stats, index, data);
stats_list.push_back(stats);
}
resp->set_stats(stats_list);

resp->Response();
}

static void GetFlowStats(SandeshFlowStats *stats, int index,
ProfileData *data) {
stats->set_index(index);
stats->set_time_str(data->time_);
stats->set_add_count(data->flow_.add_count_);
stats->set_del_count(data->flow_.del_count_);
stats->set_reval_count(data->flow_.reval_count_);
stats->set_recompute_count(data->flow_.recompute_count_);
}

void SandeshFlowStatsRequest::HandleRequest() const {
SandeshFlowStatsList *resp = new SandeshFlowStatsList();
resp->set_context(context());

Agent *agent = Agent::GetInstance();
AgentProfile *profile = agent->oper_db()->agent_profile();
uint16_t end = profile->seconds_history_index();
uint16_t start = 0;
if (end > AgentProfile::kSecondsHistoryCount)
start = end - AgentProfile::kSecondsHistoryCount;

std::vector<SandeshFlowStats> stats_list;
for (uint16_t i = start; i < end; i++) {
uint16_t index = i % AgentProfile::kSecondsHistoryCount;
ProfileData *data = profile->GetProfileData(index);
SandeshFlowStats stats;
GetFlowStats(&stats, index, data);
stats_list.push_back(stats);
}
resp->set_stats(stats_list);
resp->Response();
}

static void GetTaskStats(TaskProfileStats *stats, int index,
ProfileData *data) {
stats->set_index(index);

TaskStats *task_stats = NULL;
// Flow Handler
task_stats = &data->task_stats_[0];
stats->set_flow_wait(task_stats->wait_count_);
stats->set_flow_run(task_stats->enqueue_count_);
stats->set_flow_defer(task_stats->defer_count_);

// DB
task_stats = &data->task_stats_[1];
stats->set_db_wait(task_stats->wait_count_);
stats->set_db_run(task_stats->enqueue_count_);
stats->set_db_defer(task_stats->defer_count_);

// Stats Collector
task_stats = &data->task_stats_[2];
stats->set_stats_wait(task_stats->wait_count_);
stats->set_stats_run(task_stats->enqueue_count_);
stats->set_stats_defer(task_stats->defer_count_);

// Io-Reader
task_stats = &data->task_stats_[3];
stats->set_io_wait(task_stats->wait_count_);
stats->set_io_run(task_stats->enqueue_count_);
stats->set_io_defer(task_stats->defer_count_);

// Agent::PktFlowResponder
task_stats = &data->task_stats_[4];
stats->set_flow_resp_wait(task_stats->wait_count_);
stats->set_flow_resp_run(task_stats->enqueue_count_);
stats->set_flow_resp_defer(task_stats->defer_count_);

// Sadnesh::RecvQueue
task_stats = &data->task_stats_[5];
stats->set_sandesh_rcv_wait(task_stats->wait_count_);
stats->set_sandesh_rcv_run(task_stats->enqueue_count_);
stats->set_sandesh_rcv_defer(task_stats->defer_count_);

// bgp::Config
task_stats = &data->task_stats_[6];
stats->set_bgp_cfg_wait(task_stats->wait_count_);
stats->set_bgp_cfg_run(task_stats->enqueue_count_);
stats->set_bgp_cfg_defer(task_stats->defer_count_);

// KSync
task_stats = &data->task_stats_[7];
stats->set_ksync_wait(task_stats->wait_count_);
stats->set_ksync_run(task_stats->enqueue_count_);
stats->set_ksync_defer(task_stats->defer_count_);
}

void SandeshTaskStatsRequest::HandleRequest() const {
SandeshTaskStatsList *resp = new SandeshTaskStatsList();
resp->set_context(context());

Agent *agent = Agent::GetInstance();
AgentProfile *profile = agent->oper_db()->agent_profile();
uint16_t end = profile->seconds_history_index();
uint16_t start = 0;
if (end > AgentProfile::kSecondsHistoryCount)
start = end - AgentProfile::kSecondsHistoryCount;

std::vector<TaskProfileStats> stats_list;
for (uint16_t i = start; i < end; i++) {
uint16_t index = i % AgentProfile::kSecondsHistoryCount;
ProfileData *data = profile->GetProfileData(index);
TaskProfileStats stats;
GetTaskStats(&stats, index, data);
stats_list.push_back(stats);
}
resp->set_stats(stats_list);
resp->Response();
}

0 comments on commit 7b17cee

Please sign in to comment.