Skip to content

Commit

Permalink
Stats collection for NAT traffic in openstack and exporting the packe…
Browse files Browse the repository at this point in the history
…t count, byte count to promethues
  • Loading branch information
Bhavanaashok33 authored and pkharat committed Feb 17, 2024
1 parent 17199ba commit be71cb9
Show file tree
Hide file tree
Showing 18 changed files with 2,216 additions and 14 deletions.
9 changes: 6 additions & 3 deletions agent-ovs/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,8 @@ noinst_HEADERS = \
ovs/include/OvsdbMonitorMessage.h \
ovs/include/OvsdbTransactMessage.h \
ovs/include/OvsdbState.h \
ovs/include/DnsManager.h
ovs/include/DnsManager.h \
ovs/include/NatStatsManager.h

libopflex_agent_la_SOURCES = \
lib/AgentLogHandler.cpp \
Expand Down Expand Up @@ -291,7 +292,8 @@ if RENDERER_OVS
ovs/OvsdbMessage.cpp \
ovs/OvsdbMonitorMessage.cpp \
ovs/CtZoneManager.cpp \
ovs/DnsManager.cpp
ovs/DnsManager.cpp \
ovs/NatStatsManager.cpp

librenderer_openvswitch_la_CFLAGS = \
$(libopenvswitch_CFLAGS) \
Expand Down Expand Up @@ -531,7 +533,8 @@ if RENDERER_OVS
ovs/test/PacketDecoder_test.cpp \
ovs/test/TableDropStatsManager_test.cpp \
ovs/test/OvsdbConnection_test.cpp \
ovs/test/DnsManager_test.cpp
ovs/test/DnsManager_test.cpp \
ovs/test/NatStatsManager_test.cpp
endif


Expand Down
294 changes: 294 additions & 0 deletions agent-ovs/lib/AgentPrometheusManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,22 @@ static string table_drop_family_help[] =
"opflex table drop packets"
};

static string nat_family_names[] =
{
"opflex_endpoint_to_extnetwork_bytes",
"opflex_endpoint_to_extnetwork_packets",
"opflex_extnetwork_to_endpoint_bytes",
"opflex_extnetwork_to_endpoint_packets"
};

static string nat_family_help[] =
{
"endpoint to extnetwork bytes",
"endpoint to extnetwork packets",
"extnetwork to endpoint bytes",
"extnetwork to endpoint bytes"
};

#define RETURN_IF_DISABLED if (disabled) {return;}

// construct AgentPrometheusManager for opflex agent
Expand Down Expand Up @@ -412,6 +428,12 @@ void AgentPrometheusManager::removeDynamicGauges ()
const lock_guard<mutex> lock(contract_stats_mutex);
removeDynamicGaugeContractClassifier();
}

// Remove Nat Stats related gauges
{
const lock_guard<mutex> lock(nat_counter_mutex);
removeDynamicGaugeNatStats();
}
}

// remove all static ep counters during stop
Expand Down Expand Up @@ -720,6 +742,11 @@ void AgentPrometheusManager::createStaticGaugeFamilies (void)
const lock_guard<mutex> lock(contract_stats_mutex);
createStaticGaugeFamiliesContractClassifier();
}

{
const lock_guard<mutex> lock(nat_counter_mutex);
createStaticGaugeFamiliesNatCounter();
}
}

// remove gauges during stop
Expand Down Expand Up @@ -871,6 +898,15 @@ void AgentPrometheusManager::init ()
gauge_contract_family_ptr[metric] = nullptr;
}
}

{
const lock_guard<mutex> lock(nat_counter_mutex);
for (NAT_METRICS metric=NAT_METRICS_MIN;
metric <= NAT_METRICS_MAX;
metric = NAT_METRICS(metric+1)) {
gauge_nat_counter_family_ptr[metric] = nullptr;
}
}
}

// Stop of AgentPrometheusManager instance
Expand Down Expand Up @@ -2309,6 +2345,15 @@ void AgentPrometheusManager::removeStaticGaugeFamiliesTableDrop()
}
}

void AgentPrometheusManager::removeStaticGaugeFamiliesNatCounter()
{
for (NAT_METRICS metric=NAT_METRICS_MIN;
metric <= NAT_METRICS_MAX;
metric = NAT_METRICS(metric+1)) {
gauge_nat_counter_family_ptr[metric] = nullptr;
}
}

// Remove all statically allocated gauge families
void AgentPrometheusManager::removeStaticGaugeFamilies()
{
Expand Down Expand Up @@ -2368,6 +2413,11 @@ void AgentPrometheusManager::removeStaticGaugeFamilies()
const lock_guard<mutex> lock(contract_stats_mutex);
removeStaticGaugeFamiliesContractClassifier();
}
// Nat Stat counter specific
{
const lock_guard<mutex> lock(nat_counter_mutex);
removeStaticGaugeFamiliesNatCounter();
}
}

// Return a rolling hash of attribute map for the ep
Expand Down Expand Up @@ -3281,4 +3331,248 @@ void AgentPrometheusManager::updateTableDropGauge (const string& bridge_name,
}
}

/* Function called from IntFlowManager to update NAT Stats Counter */
void AgentPrometheusManager::addNUpdateNatStats (const string& uuid,
const string& dir,
uint64_t bytes,
uint64_t pkts,
const string& mappedIp,
const string& FIp,
const string& sepg,
const string& depg)
{
RETURN_IF_DISABLED
const lock_guard<mutex> lock(nat_counter_mutex);

if(dir=="FromVm") {
// Update the metrics for Vm to External network Flow Stats
for(NAT_METRICS metric=NAT_METRICS_MIN; metric <= NAT_VM2EXT_MAX; metric = NAT_METRICS(metric+1)){
// Create the gauge counters if they arent present already
if(!createDynamicGaugeNatStats(metric, uuid, mappedIp, FIp, dir, sepg, depg)) {
break;
}
hgauge_pair_t hgauge = getDynamicGaugeNatCounter(metric, uuid);
optional<uint64_t> metric_opt;
switch (metric) {
case NAT_VM2EXT_BYTES:
metric_opt = bytes;
break;
case NAT_VM2EXT_PKTS:
metric_opt = pkts;
break;
default:
LOG(WARNING) << "Unhandled metric: " << metric;
}
if (metric_opt && hgauge){
hgauge.get().second->Set(static_cast<double>(metric_opt.get()));
}
if (!hgauge) {
LOG(WARNING) << "nat stats invalid update for uuid: " << uuid;
break;
}
}
} else {
// Update the metrics for External network to Vm Flow Stats
for(NAT_METRICS metric=NAT_EXT2VM_MIN; metric <= NAT_METRICS_MAX; metric = NAT_METRICS(metric+1)) {
// Create the gauge counters if they arent present already
if(!createDynamicGaugeNatStats(metric, uuid, mappedIp, FIp, dir, sepg, depg)) {
break;
}
hgauge_pair_t hgauge = getDynamicGaugeNatCounter(metric, uuid);
optional<uint64_t> metric_opt;
switch (metric) {
case NAT_EXT2VM_BYTES:
metric_opt = bytes;
break;
case NAT_EXT2VM_PKTS:
metric_opt = pkts;
break;
default:
LOG(WARNING) << "Unhandled metric: " << metric;
}
if (metric_opt && hgauge){
hgauge.get().second->Set(static_cast<double>(metric_opt.get()));
}
if (!hgauge) {
LOG(WARNING) << "nat stats invalid update for uuid: " << uuid;
break;
}
}
}
return;
}

// Function called from IntFlowManager to remove NatStats Counter
void AgentPrometheusManager::removeNatCounter(const string& dir, const string& uuid) {
RETURN_IF_DISABLED
const lock_guard<mutex> lock(nat_counter_mutex);

LOG(DEBUG) << "remove nat counter uuid: " << uuid;
if(dir == "VmToExt") {
for(NAT_METRICS metric=NAT_METRICS_MIN; metric <=
NAT_VM2EXT_MAX; metric = NAT_METRICS(metric+1)) {
if(!removeDynamicGaugeNatStats(metric, uuid)){
break;
}
}
}else {
for(NAT_METRICS metric=NAT_EXT2VM_MIN; metric <=
NAT_METRICS_MAX; metric = NAT_METRICS(metric+1)){
if(!removeDynamicGaugeNatStats(metric, uuid)){
break;
}
}
}
}

// Create Nat Counter gauge given metric type and an uuid
bool AgentPrometheusManager::createDynamicGaugeNatStats (NAT_METRICS metric,
const string& uuid,
const string& mappedIp,
const string& FIp,
const string& dir,
const string& sepg,
const string& depg)
{
auto const &label_map = createLabelMapNatCounter(uuid, mappedIp, FIp, sepg, depg);
LabelHasher hasher;
auto hash_new = hasher(label_map);

// Retrieve the Gauge if its already created
auto hgauge = getDynamicGaugeNatCounter(metric, uuid);
if (hgauge) {
/**
* Detect attribute change by comparing hashes of cached label map
* with new label map
*/
if (hash_new == hgauge.get().first){
return true;
}
else {
LOG(DEBUG) << "addNupdate Vm2Ext counter uuid " << uuid
<< "existing Vm2Ext metric, but deleting: hash modified"
<< " metric: " << nat_family_names[metric]
<< " hash: " << hgauge.get().first
<< "gaugeptr: "<< hgauge.get().second;
removeDynamicGaugeNatStats(metric, uuid);

}
}

if (!hash_new) {
return false;
}
if(gauge_nat_counter_family_ptr[metric]){
LOG(DEBUG) << "adding nat counter gauge ";
auto& gauge = gauge_nat_counter_family_ptr[metric]->Add(label_map);

if (gauge_check.is_dup(&gauge)) {
LOG(WARNING) << "duplicate nat counter dyn gauge family"
<< " metric: " << metric
<< " uuid: " << uuid
<< " label hash: " << hash_new;
return true;
}
gauge_check.add(&gauge);
nat_gauge_map[metric][uuid] = make_pair(hash_new, &gauge);
auto hgauge = getDynamicGaugeNatCounter(metric, uuid);

Check notice

Code scanning / CodeQL

Declaration hides variable Note

Variable hgauge hides another variable of the same name (on
line 3442
).
return true;
}
return false;
}

// Create a label map that can be used for annotation, given the ep attributes
const map<string,string> AgentPrometheusManager::createLabelMapNatCounter(
const string& uuid,
const string& mappedIp,
const string& FIp,
const string& sepg,
const string& depg)
{
map<string,string> label_map;
label_map["uuid"] = uuid;
label_map["vm_ip"] = mappedIp;
label_map["floating_ip"] = FIp;
label_map["sepg"] = sepg;
label_map["depg"] = depg;
return label_map;
}

// Get Nat Counter gauge given the metric, uuid of EP
hgauge_pair_t AgentPrometheusManager::getDynamicGaugeNatCounter (NAT_METRICS metric,
const string& uuid)
{
hgauge_pair_t hgauge = boost::none;
auto itr = nat_gauge_map[metric].find(uuid);
if (itr == nat_gauge_map[metric].end()) {
LOG(INFO) << "Dyn Gauge Nat Counter not found for " << uuid;
} else {
LOG(INFO) << "Dyn Gauge Nat Counter found for "<< uuid;
hgauge = itr->second;
}

return hgauge;
}

void AgentPrometheusManager::createStaticGaugeFamiliesNatCounter (void)
{
// add a new gauge family to the registry (families combine values with the
// same name, but distinct label dimensions)
// Note: There is a unique ptr allocated and referencing the below reference
// during Register().

for (NAT_METRICS metric=NAT_METRICS_MIN;
metric <= NAT_METRICS_MAX;
metric = NAT_METRICS(metric+1)) {
auto& gauge_nat_family = BuildGauge()
.Name(nat_family_names[metric])
.Help(nat_family_help[metric])
.Labels({})
.Register(*registry_ptr);
gauge_nat_counter_family_ptr[metric] = &gauge_nat_family;
}
}


// func to remove gauge for NAT Counter given metric type, uuid
bool AgentPrometheusManager::removeDynamicGaugeNatStats (NAT_METRICS metric,
const string& uuid){

auto hgauge = getDynamicGaugeNatCounter(metric, uuid);
if (hgauge) {
nat_gauge_map[metric].erase(uuid);
gauge_check.remove(hgauge.get().second);
gauge_nat_counter_family_ptr[metric]->Remove(hgauge.get().second);
} else {
LOG(DEBUG) << "remove dynamic gauge nat stat not found uuid:" << uuid;
return false;
}
return true;
}

// func to remove gauge for NAT Counter given metric type
void AgentPrometheusManager::removeDynamicGaugeNatStats (NAT_METRICS metric){

auto itr = nat_gauge_map[metric].begin();
while (itr != nat_gauge_map[metric].end()) {
LOG(DEBUG) << "Deleting Nat Ep uuid: "<< itr->first
<< " hash: " << itr->second.get().first
<< " Gauge: " << itr->second.get().second;
gauge_check.remove(itr->second.get().second);
gauge_nat_counter_family_ptr[metric]->Remove(itr->second.get().second);
itr++;
}
}

// func to remove all gauges of every NAT Counter
void AgentPrometheusManager::removeDynamicGaugeNatStats () {

for (NAT_METRICS metric=NAT_METRICS_MIN;
metric <= NAT_METRICS_MAX;
metric = NAT_METRICS(metric+1)) {
removeDynamicGaugeNatStats(metric);
}

}

} /* namespace opflexagent */
Loading

0 comments on commit be71cb9

Please sign in to comment.