perf: 优化metrics的性能
* 使用自定义的HASH_KEYCMP代替memcmp, 优先比较sf_profile_id
* 减少sf_metrics_inc函数入参的个数
This commit is contained in:
@@ -7,13 +7,20 @@ extern "C"
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "uthash.h"
|
|
||||||
|
struct sf_metrics_key
|
||||||
|
{
|
||||||
|
uint64_t rule_id;
|
||||||
|
uint32_t sf_profile_id;
|
||||||
|
uint32_t sff_profile_id;
|
||||||
|
uint32_t vsys_id;
|
||||||
|
};
|
||||||
|
|
||||||
struct sf_metrics *sf_metrics_create(const char *profile);
|
struct sf_metrics *sf_metrics_create(const char *profile);
|
||||||
void sf_metrics_destory(struct sf_metrics *handle);
|
void sf_metrics_destory(struct sf_metrics *handle);
|
||||||
void sf_metrics_reset(struct sf_metrics *handle);
|
void sf_metrics_reset(struct sf_metrics *handle);
|
||||||
|
|
||||||
void sf_metrics_inc(struct sf_metrics *handle, int vsys_id, uint64_t rule_id, int sff_profile_id, int sf_profile_id, uint64_t rx_pkts, uint64_t rx_bytes, uint64_t tx_pkts, uint64_t tx_bytes);
|
void sf_metrics_inc(struct sf_metrics *handle, struct sf_metrics_key *key, uint64_t rx_pkts, uint64_t rx_bytes, uint64_t tx_pkts, uint64_t tx_bytes);
|
||||||
void sf_metrics_send(struct sf_metrics *handle);
|
void sf_metrics_send(struct sf_metrics *handle);
|
||||||
int sf_metrics_get_interval(struct sf_metrics *handle);
|
int sf_metrics_get_interval(struct sf_metrics *handle);
|
||||||
|
|
||||||
|
|||||||
@@ -623,7 +623,12 @@ static inline void action_mirr_forward(struct session_ctx *session_ctx, marsio_b
|
|||||||
int nsend = send_packet_to_sf(session_ctx, new_buff, meta, sf, thread_ctx);
|
int nsend = send_packet_to_sf(session_ctx, new_buff, meta, sf, thread_ctx);
|
||||||
throughput_metrics_inc(&(thread_metrics->data_pkt.mirr_tx), 1, raw_len);
|
throughput_metrics_inc(&(thread_metrics->data_pkt.mirr_tx), 1, raw_len);
|
||||||
throughput_metrics_inc(&sf->tx, 1, nsend);
|
throughput_metrics_inc(&sf->tx, 1, nsend);
|
||||||
sf_metrics_inc(thread_ctx->sf_metrics, sf->rule_vsys_id, sf->rule_id, sf->sff_profile_id, sf->sf_profile_id, 0, 0, 1, nsend);
|
struct sf_metrics_key key = {0};
|
||||||
|
key.rule_id = sf->rule_id;
|
||||||
|
key.sff_profile_id = sf->sff_profile_id;
|
||||||
|
key.sf_profile_id = sf->sf_profile_id;
|
||||||
|
key.vsys_id = sf->rule_vsys_id;
|
||||||
|
sf_metrics_inc(thread_ctx->sf_metrics, &key, 0, 0, 1, nsend);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void action_stee_bypass(marsio_buff_t *rx_buff, struct metadata *meta, struct selected_sf *sf, struct thread_ctx *thread_ctx)
|
static inline void action_stee_bypass(marsio_buff_t *rx_buff, struct metadata *meta, struct selected_sf *sf, struct thread_ctx *thread_ctx)
|
||||||
@@ -653,7 +658,12 @@ static inline void action_stee_forward(struct session_ctx *session_ctx, marsio_b
|
|||||||
int nsend = send_packet_to_sf(session_ctx, rx_buff, meta, sf, thread_ctx);
|
int nsend = send_packet_to_sf(session_ctx, rx_buff, meta, sf, thread_ctx);
|
||||||
throughput_metrics_inc(&(thread_metrics->data_pkt.stee_tx), 1, raw_len);
|
throughput_metrics_inc(&(thread_metrics->data_pkt.stee_tx), 1, raw_len);
|
||||||
throughput_metrics_inc(&sf->tx, 1, nsend);
|
throughput_metrics_inc(&sf->tx, 1, nsend);
|
||||||
sf_metrics_inc(thread_ctx->sf_metrics, sf->rule_vsys_id, sf->rule_id, sf->sff_profile_id, sf->sf_profile_id, 0, 0, 1, nsend);
|
struct sf_metrics_key key = {0};
|
||||||
|
key.rule_id = sf->rule_id;
|
||||||
|
key.sff_profile_id = sf->sff_profile_id;
|
||||||
|
key.sf_profile_id = sf->sf_profile_id;
|
||||||
|
key.vsys_id = sf->rule_vsys_id;
|
||||||
|
sf_metrics_inc(thread_ctx->sf_metrics, &key, 0, 0, 1, nsend);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void action_sf_chaining(struct thread_ctx *thread_ctx, struct session_ctx *session_ctx, struct selected_chaining *chaining, marsio_buff_t *rx_buff, struct metadata *meta, int next_sf_index)
|
static void action_sf_chaining(struct thread_ctx *thread_ctx, struct session_ctx *session_ctx, struct selected_chaining *chaining, marsio_buff_t *rx_buff, struct metadata *meta, int next_sf_index)
|
||||||
@@ -1222,7 +1232,12 @@ static void handle_inject_vxlan_packet(marsio_buff_t *rx_buff, struct thread_ctx
|
|||||||
struct selected_sf *sf = &(chaining->chaining[sf_index]);
|
struct selected_sf *sf = &(chaining->chaining[sf_index]);
|
||||||
throughput_metrics_inc(&sf->rx, 1, raw_len);
|
throughput_metrics_inc(&sf->rx, 1, raw_len);
|
||||||
throughput_metrics_inc(&(thread_metrics->data_pkt.stee_rx), 1, meta.raw_len);
|
throughput_metrics_inc(&(thread_metrics->data_pkt.stee_rx), 1, meta.raw_len);
|
||||||
sf_metrics_inc(thread_ctx->sf_metrics, sf->rule_vsys_id, sf->rule_id, sf->sff_profile_id, sf->sf_profile_id, 1, raw_len, 0, 0);
|
struct sf_metrics_key key = {0};
|
||||||
|
key.rule_id = sf->rule_id;
|
||||||
|
key.sff_profile_id = sf->sff_profile_id;
|
||||||
|
key.sf_profile_id = sf->sf_profile_id;
|
||||||
|
key.vsys_id = sf->rule_vsys_id;
|
||||||
|
sf_metrics_inc(thread_ctx->sf_metrics, &key, 1, raw_len, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
marsio_buff_adj(rx_buff, raw_len - meta.raw_len);
|
marsio_buff_adj(rx_buff, raw_len - meta.raw_len);
|
||||||
|
|||||||
@@ -12,17 +12,13 @@
|
|||||||
|
|
||||||
#define SCE_SF_METRICS "service_chaining_rule_hits,vsys_id=%d,rule_id=%lu,sff_profile_id=%d,sf_profile_id=%d sent_pkts=%lu,sent_bytes=%lu,recv_pkts=%lu,recv_bytes=%lu"
|
#define SCE_SF_METRICS "service_chaining_rule_hits,vsys_id=%d,rule_id=%lu,sff_profile_id=%d,sf_profile_id=%d sent_pkts=%lu,sent_bytes=%lu,recv_pkts=%lu,recv_bytes=%lu"
|
||||||
|
|
||||||
struct key_tuple
|
// Must be defined before including uthash.h
|
||||||
{
|
#define HASH_KEYCMP(a, b, len) sf_metrics_key_cmp((struct sf_metrics_key *)(a), (struct sf_metrics_key *)(b))
|
||||||
int vsys_id;
|
#include "uthash.h"
|
||||||
uint64_t rule_id;
|
|
||||||
int sff_profile_id;
|
|
||||||
int sf_profile_id;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct node
|
struct node
|
||||||
{
|
{
|
||||||
struct key_tuple key;
|
struct sf_metrics_key key;
|
||||||
uint64_t sent_pkts;
|
uint64_t sent_pkts;
|
||||||
uint64_t sent_bytes;
|
uint64_t sent_bytes;
|
||||||
uint64_t recv_pkts;
|
uint64_t recv_pkts;
|
||||||
@@ -31,17 +27,13 @@ struct node
|
|||||||
UT_hash_handle hh;
|
UT_hash_handle hh;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sf_metrics_config
|
struct sf_metrics
|
||||||
{
|
{
|
||||||
int enable;
|
int enable;
|
||||||
int interval_s;
|
int interval_s;
|
||||||
int telegraf_listen_port;
|
int telegraf_listen_port;
|
||||||
char telegraf_bind_address[2048];
|
char telegraf_bind_address[2048];
|
||||||
};
|
|
||||||
|
|
||||||
struct sf_metrics
|
|
||||||
{
|
|
||||||
struct sf_metrics_config config;
|
|
||||||
struct sockaddr_in sock_addr;
|
struct sockaddr_in sock_addr;
|
||||||
int sockfd;
|
int sockfd;
|
||||||
|
|
||||||
@@ -49,38 +41,54 @@ struct sf_metrics
|
|||||||
uint64_t htable_elem_count;
|
uint64_t htable_elem_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void sf_metrics_parse_config(const char *profile, struct sf_metrics_config *config)
|
static inline int sf_metrics_key_cmp(struct sf_metrics_key *a, struct sf_metrics_key *b)
|
||||||
{
|
{
|
||||||
MESA_load_profile_int_def(profile, "METRICS", "enable", &(config->enable), 1);
|
if (a->sf_profile_id != b->sf_profile_id)
|
||||||
MESA_load_profile_int_def(profile, "METRICS", "interval_s", &(config->interval_s), 1);
|
{
|
||||||
MESA_load_profile_int_def(profile, "METRICS", "telegraf_listen_port", &(config->telegraf_listen_port), 8300);
|
return 1;
|
||||||
MESA_load_profile_string_def(profile, "METRICS", "telegraf_bind_address", config->telegraf_bind_address, sizeof(config->telegraf_bind_address), "127.0.0.1");
|
}
|
||||||
|
|
||||||
// LOG_DEBUG("%s: METRICS->enable : %d", LOG_TAG_SF_METRICS, config->enable);
|
if (a->sff_profile_id != b->sff_profile_id)
|
||||||
// LOG_DEBUG("%s: METRICS->interval_s : %d", LOG_TAG_SF_METRICS, config->interval_s);
|
{
|
||||||
// LOG_DEBUG("%s: METRICS->telegraf_listen_port : %d", LOG_TAG_SF_METRICS, config->telegraf_listen_port);
|
return 1;
|
||||||
// LOG_DEBUG("%s: METRICS->telegraf_bind_address : %s", LOG_TAG_SF_METRICS, config->telegraf_bind_address);
|
}
|
||||||
|
|
||||||
|
if (a->rule_id != b->rule_id)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a->vsys_id != b->vsys_id)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sf_metrics *sf_metrics_create(const char *profile)
|
struct sf_metrics *sf_metrics_create(const char *profile)
|
||||||
{
|
{
|
||||||
struct sf_metrics *handle = (struct sf_metrics *)calloc(1, sizeof(struct sf_metrics));
|
struct sf_metrics *handle = (struct sf_metrics *)calloc(1, sizeof(struct sf_metrics));
|
||||||
assert(handle);
|
assert(handle);
|
||||||
sf_metrics_parse_config(profile, &(handle->config));
|
|
||||||
|
|
||||||
if (handle->config.enable == 0)
|
MESA_load_profile_int_def(profile, "METRICS", "enable", &(handle->enable), 1);
|
||||||
|
MESA_load_profile_int_def(profile, "METRICS", "interval_s", &(handle->interval_s), 1);
|
||||||
|
MESA_load_profile_int_def(profile, "METRICS", "telegraf_listen_port", &(handle->telegraf_listen_port), 8300);
|
||||||
|
MESA_load_profile_string_def(profile, "METRICS", "telegraf_bind_address", handle->telegraf_bind_address, sizeof(handle->telegraf_bind_address), "127.0.0.1");
|
||||||
|
|
||||||
|
if (handle->enable == 0)
|
||||||
{
|
{
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle->sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
handle->sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
handle->sock_addr.sin_family = AF_INET;
|
handle->sock_addr.sin_family = AF_INET;
|
||||||
handle->sock_addr.sin_port = htons(handle->config.telegraf_listen_port);
|
handle->sock_addr.sin_port = htons(handle->telegraf_listen_port);
|
||||||
handle->sock_addr.sin_addr.s_addr = inet_addr(handle->config.telegraf_bind_address);
|
handle->sock_addr.sin_addr.s_addr = inet_addr(handle->telegraf_bind_address);
|
||||||
handle->htable_elem_count = 0;
|
handle->htable_elem_count = 0;
|
||||||
if (handle->sockfd == -1)
|
if (handle->sockfd == -1)
|
||||||
{
|
{
|
||||||
LOG_ERROR("%s: failed to create udp sockfd %s:%d, errno: %d, %s", LOG_TAG_SF_METRICS, handle->config.telegraf_bind_address, handle->config.telegraf_listen_port, errno, strerror(errno));
|
LOG_ERROR("%s: failed to create udp sockfd %s:%d, errno: %d, %s", LOG_TAG_SF_METRICS, handle->telegraf_bind_address, handle->telegraf_listen_port, errno, strerror(errno));
|
||||||
sf_metrics_destory(handle);
|
sf_metrics_destory(handle);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -121,7 +129,7 @@ void sf_metrics_reset(struct sf_metrics *handle)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle->config.enable == 0)
|
if (handle->enable == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -138,22 +146,15 @@ void sf_metrics_reset(struct sf_metrics *handle)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sf_metrics_inc(struct sf_metrics *handle, int vsys_id, uint64_t rule_id, int sff_profile_id, int sf_profile_id, uint64_t rx_pkts, uint64_t rx_bytes, uint64_t tx_pkts, uint64_t tx_bytes)
|
void sf_metrics_inc(struct sf_metrics *handle, struct sf_metrics_key *key, uint64_t rx_pkts, uint64_t rx_bytes, uint64_t tx_pkts, uint64_t tx_bytes)
|
||||||
{
|
{
|
||||||
if (handle->config.enable == 0)
|
if (handle->enable == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct key_tuple key;
|
|
||||||
memset(&key, 0, sizeof(struct key_tuple));
|
|
||||||
key.vsys_id = vsys_id;
|
|
||||||
key.rule_id = rule_id;
|
|
||||||
key.sff_profile_id = sff_profile_id;
|
|
||||||
key.sf_profile_id = sf_profile_id;
|
|
||||||
|
|
||||||
struct node *temp = NULL;
|
struct node *temp = NULL;
|
||||||
HASH_FIND(hh, handle->htable, &key, sizeof(struct key_tuple), temp);
|
HASH_FIND(hh, handle->htable, key, sizeof(struct sf_metrics_key), temp);
|
||||||
if (temp)
|
if (temp)
|
||||||
{
|
{
|
||||||
temp->recv_pkts += rx_pkts;
|
temp->recv_pkts += rx_pkts;
|
||||||
@@ -164,16 +165,16 @@ void sf_metrics_inc(struct sf_metrics *handle, int vsys_id, uint64_t rule_id, in
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
temp = (struct node *)calloc(1, sizeof(struct node));
|
temp = (struct node *)calloc(1, sizeof(struct node));
|
||||||
temp->key.vsys_id = vsys_id;
|
temp->key.vsys_id = key->vsys_id;
|
||||||
temp->key.rule_id = rule_id;
|
temp->key.rule_id = key->rule_id;
|
||||||
temp->key.sff_profile_id = sff_profile_id;
|
temp->key.sff_profile_id = key->sff_profile_id;
|
||||||
temp->key.sf_profile_id = sf_profile_id;
|
temp->key.sf_profile_id = key->sf_profile_id;
|
||||||
temp->recv_pkts = rx_pkts;
|
temp->recv_pkts = rx_pkts;
|
||||||
temp->recv_bytes = rx_bytes;
|
temp->recv_bytes = rx_bytes;
|
||||||
temp->sent_pkts = tx_pkts;
|
temp->sent_pkts = tx_pkts;
|
||||||
temp->sent_bytes = tx_bytes;
|
temp->sent_bytes = tx_bytes;
|
||||||
|
|
||||||
HASH_ADD(hh, handle->htable, key, sizeof(struct key_tuple), temp);
|
HASH_ADD(hh, handle->htable, key, sizeof(struct sf_metrics_key), temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,7 +187,7 @@ void sf_metrics_send(struct sf_metrics *handle)
|
|||||||
struct node *temp = NULL;
|
struct node *temp = NULL;
|
||||||
struct node *node = NULL;
|
struct node *node = NULL;
|
||||||
|
|
||||||
if (handle->config.enable == 0)
|
if (handle->enable == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -214,5 +215,5 @@ void sf_metrics_send(struct sf_metrics *handle)
|
|||||||
|
|
||||||
int sf_metrics_get_interval(struct sf_metrics *handle)
|
int sf_metrics_get_interval(struct sf_metrics *handle)
|
||||||
{
|
{
|
||||||
return handle->config.interval_s;
|
return handle->interval_s;
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,21 @@ TEST(SF_METRICS, TEST)
|
|||||||
{
|
{
|
||||||
struct sf_metrics *metrics = sf_metrics_create("./test_resource/sce.conf");
|
struct sf_metrics *metrics = sf_metrics_create("./test_resource/sce.conf");
|
||||||
EXPECT_TRUE(sf_metrics_get_interval(metrics) == 1);
|
EXPECT_TRUE(sf_metrics_get_interval(metrics) == 1);
|
||||||
sf_metrics_inc(metrics, 1, 1, 2, 3, 4, 5, 6, 7);
|
|
||||||
|
struct sf_metrics_key key1 = {0};
|
||||||
|
key1.rule_id = 1;
|
||||||
|
key1.sff_profile_id = 2;
|
||||||
|
key1.sf_profile_id = 3;
|
||||||
|
key1.vsys_id = 4;
|
||||||
|
sf_metrics_inc(metrics, &key1, 4, 5, 6, 7);
|
||||||
|
|
||||||
|
struct sf_metrics_key key2 = {0};
|
||||||
|
key2.rule_id = 1;
|
||||||
|
key2.sff_profile_id = 2;
|
||||||
|
key2.sf_profile_id = 3;
|
||||||
|
key2.vsys_id = 4;
|
||||||
|
sf_metrics_inc(metrics, &key2, 4, 5, 6, 7);
|
||||||
|
|
||||||
sf_metrics_send(metrics);
|
sf_metrics_send(metrics);
|
||||||
sf_metrics_destory(metrics);
|
sf_metrics_destory(metrics);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user