refactor stellar stat

This commit is contained in:
luwenpeng
2024-06-25 14:08:33 +08:00
parent 076b3c7b0b
commit 276bdd1b99
11 changed files with 331 additions and 520 deletions

View File

@@ -32,7 +32,7 @@ struct dumpfile_io
pcap_t *pcap; pcap_t *pcap;
struct lock_free_queue *queue[MAX_THREAD_NUM]; struct lock_free_queue *queue[MAX_THREAD_NUM];
struct io_stat stat[MAX_THREAD_NUM]; struct packet_io_stat stat[MAX_THREAD_NUM];
uint64_t io_thread_need_exit; uint64_t io_thread_need_exit;
uint64_t io_thread_is_runing; uint64_t io_thread_is_runing;
uint64_t io_thread_wait_exit; uint64_t io_thread_wait_exit;
@@ -385,7 +385,7 @@ int dumpfile_io_init(struct dumpfile_io *handle, uint16_t thr_idx)
int dumpfile_io_ingress(struct dumpfile_io *handle, uint16_t thr_idx, struct packet *pkts, int nr_pkts) int dumpfile_io_ingress(struct dumpfile_io *handle, uint16_t thr_idx, struct packet *pkts, int nr_pkts)
{ {
struct lock_free_queue *queue = handle->queue[thr_idx]; struct lock_free_queue *queue = handle->queue[thr_idx];
struct io_stat *stat = &handle->stat[thr_idx]; struct packet_io_stat *stat = &handle->stat[thr_idx];
struct pcap_pkt *pcap_pkt = NULL; struct pcap_pkt *pcap_pkt = NULL;
struct packet *pkt; struct packet *pkt;
int nr_parsed = 0; int nr_parsed = 0;
@@ -421,7 +421,7 @@ void dumpfile_io_egress(struct dumpfile_io *handle, uint16_t thr_idx, struct pac
{ {
int len; int len;
struct packet *pkt = NULL; struct packet *pkt = NULL;
struct io_stat *stat = &handle->stat[thr_idx]; struct packet_io_stat *stat = &handle->stat[thr_idx];
for (int i = 0; i < nr_pkts; i++) for (int i = 0; i < nr_pkts; i++)
{ {
@@ -446,7 +446,7 @@ void dumpfile_io_egress(struct dumpfile_io *handle, uint16_t thr_idx, struct pac
void dumpfile_io_drop(struct dumpfile_io *handle, uint16_t thr_idx, struct packet *pkts, int nr_pkts) void dumpfile_io_drop(struct dumpfile_io *handle, uint16_t thr_idx, struct packet *pkts, int nr_pkts)
{ {
struct packet *pkt = NULL; struct packet *pkt = NULL;
struct io_stat *stat = &handle->stat[thr_idx]; struct packet_io_stat *stat = &handle->stat[thr_idx];
for (int i = 0; i < nr_pkts; i++) for (int i = 0; i < nr_pkts; i++)
{ {
@@ -466,7 +466,7 @@ int dumpfile_io_inject(struct dumpfile_io *handle, uint16_t thr_idx, struct pack
{ {
int len; int len;
struct packet *pkt = NULL; struct packet *pkt = NULL;
struct io_stat *stat = &handle->stat[thr_idx]; struct packet_io_stat *stat = &handle->stat[thr_idx];
for (int i = 0; i < nr_pkts; i++) for (int i = 0; i < nr_pkts; i++)
{ {
@@ -495,7 +495,7 @@ void dumpfile_io_yield(struct dumpfile_io *handle, uint16_t thr_idx, uint64_t ti
return; return;
} }
struct io_stat *dumpfile_io_stat(struct dumpfile_io *handle, uint16_t thr_idx) struct packet_io_stat *dumpfile_io_stat(struct dumpfile_io *handle, uint16_t thr_idx)
{ {
return &handle->stat[thr_idx]; return &handle->stat[thr_idx];
} }

View File

@@ -18,7 +18,7 @@ void dumpfile_io_egress(struct dumpfile_io *handle, uint16_t thr_idx, struct pac
void dumpfile_io_drop(struct dumpfile_io *handle, uint16_t thr_idx, struct packet *pkts, int nr_pkts); void dumpfile_io_drop(struct dumpfile_io *handle, uint16_t thr_idx, struct packet *pkts, int nr_pkts);
int dumpfile_io_inject(struct dumpfile_io *handle, uint16_t thr_idx, struct packet *pkts, int nr_pkts); int dumpfile_io_inject(struct dumpfile_io *handle, uint16_t thr_idx, struct packet *pkts, int nr_pkts);
void dumpfile_io_yield(struct dumpfile_io *handle, uint16_t thr_idx, uint64_t timeout_ms); void dumpfile_io_yield(struct dumpfile_io *handle, uint16_t thr_idx, uint64_t timeout_ms);
struct io_stat *dumpfile_io_stat(struct dumpfile_io *handle, uint16_t thr_idx); struct packet_io_stat *dumpfile_io_stat(struct dumpfile_io *handle, uint16_t thr_idx);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -19,7 +19,7 @@ struct marsio_io
struct mr_vdev *mr_dev; struct mr_vdev *mr_dev;
struct mr_sendpath *mr_path; struct mr_sendpath *mr_path;
struct io_stat stat[MAX_THREAD_NUM]; struct packet_io_stat stat[MAX_THREAD_NUM];
}; };
/****************************************************************************** /******************************************************************************
@@ -263,7 +263,7 @@ int marsio_io_ingress(struct marsio_io *handle, uint16_t thr_idx, struct packet
struct packet *pkt; struct packet *pkt;
marsio_buff_t *mbuff; marsio_buff_t *mbuff;
marsio_buff_t *rx_buffs[RX_BURST_MAX]; marsio_buff_t *rx_buffs[RX_BURST_MAX];
struct io_stat *stat = &handle->stat[thr_idx]; struct packet_io_stat *stat = &handle->stat[thr_idx];
int nr_recv; int nr_recv;
int nr_parsed = 0; int nr_parsed = 0;
int len; int len;
@@ -321,7 +321,7 @@ void marsio_io_egress(struct marsio_io *handle, uint16_t thr_idx, struct packet
{ {
struct packet *pkt; struct packet *pkt;
marsio_buff_t *mbuff; marsio_buff_t *mbuff;
struct io_stat *stat = &handle->stat[thr_idx]; struct packet_io_stat *stat = &handle->stat[thr_idx];
int len; int len;
for (int i = 0; i < nr_pkts; i++) for (int i = 0; i < nr_pkts; i++)
@@ -356,7 +356,7 @@ void marsio_io_drop(struct marsio_io *handle, uint16_t thr_idx, struct packet *p
{ {
struct packet *pkt; struct packet *pkt;
marsio_buff_t *mbuff; marsio_buff_t *mbuff;
struct io_stat *stat = &handle->stat[thr_idx]; struct packet_io_stat *stat = &handle->stat[thr_idx];
for (int i = 0; i < nr_pkts; i++) for (int i = 0; i < nr_pkts; i++)
{ {
@@ -379,7 +379,7 @@ int marsio_io_inject(struct marsio_io *handle, uint16_t thr_idx, struct packet *
char *ptr; char *ptr;
struct packet *pkt; struct packet *pkt;
marsio_buff_t *mbuff; marsio_buff_t *mbuff;
struct io_stat *stat = &handle->stat[thr_idx]; struct packet_io_stat *stat = &handle->stat[thr_idx];
for (int i = 0; i < nr_pkts; i++) for (int i = 0; i < nr_pkts; i++)
{ {
@@ -423,7 +423,7 @@ void marsio_io_yield(struct marsio_io *handle, uint16_t thr_idx, uint64_t timeou
marsio_poll_wait(handle->mr_ins, vdevs, 1, thr_idx, timeout_ms); marsio_poll_wait(handle->mr_ins, vdevs, 1, thr_idx, timeout_ms);
} }
struct io_stat *marsio_io_stat(struct marsio_io *handle, uint16_t thr_idx) struct packet_io_stat *marsio_io_stat(struct marsio_io *handle, uint16_t thr_idx)
{ {
return &handle->stat[thr_idx]; return &handle->stat[thr_idx];
} }

View File

@@ -17,7 +17,7 @@ void marsio_io_egress(struct marsio_io *handle, uint16_t thr_idx, struct packet
void marsio_io_drop(struct marsio_io *handle, uint16_t thr_idx, struct packet *pkts, int nr_pkts); void marsio_io_drop(struct marsio_io *handle, uint16_t thr_idx, struct packet *pkts, int nr_pkts);
int marsio_io_inject(struct marsio_io *handle, uint16_t thr_idx, struct packet *pkts, int nr_pkts); int marsio_io_inject(struct marsio_io *handle, uint16_t thr_idx, struct packet *pkts, int nr_pkts);
void marsio_io_yield(struct marsio_io *handle, uint16_t thr_idx, uint64_t timeout_ms); void marsio_io_yield(struct marsio_io *handle, uint16_t thr_idx, uint64_t timeout_ms);
struct io_stat *marsio_io_stat(struct marsio_io *handle, uint16_t thr_idx); struct packet_io_stat *marsio_io_stat(struct marsio_io *handle, uint16_t thr_idx);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -141,7 +141,7 @@ void packet_io_yield(struct packet_io *packet_io, uint16_t thr_idx, uint64_t tim
} }
} }
struct io_stat *packet_io_stat(struct packet_io *packet_io, uint16_t thr_idx) struct packet_io_stat *packet_io_stat(struct packet_io *packet_io, uint16_t thr_idx)
{ {
if (likely(packet_io->mode == PACKET_IO_MARSIO)) if (likely(packet_io->mode == PACKET_IO_MARSIO))
{ {

View File

@@ -9,7 +9,7 @@ extern "C"
#include "macro.h" #include "macro.h"
struct io_stat struct packet_io_stat
{ {
// device packet // device packet
uint64_t dev_rx_pkts; uint64_t dev_rx_pkts;
@@ -77,7 +77,7 @@ void packet_io_egress(struct packet_io *packet_io, uint16_t thr_idx, struct pack
void packet_io_drop(struct packet_io *packet_io, uint16_t thr_idx, struct packet *pkts, int nr_pkts); void packet_io_drop(struct packet_io *packet_io, uint16_t thr_idx, struct packet *pkts, int nr_pkts);
int packet_io_inject(struct packet_io *packet_io, uint16_t thr_idx, struct packet *pkts, int nr_pkts); int packet_io_inject(struct packet_io *packet_io, uint16_t thr_idx, struct packet *pkts, int nr_pkts);
void packet_io_yield(struct packet_io *packet_io, uint16_t thr_idx, uint64_t timeout_ms); void packet_io_yield(struct packet_io *packet_io, uint16_t thr_idx, uint64_t timeout_ms);
struct io_stat *packet_io_stat(struct packet_io *packet_io, uint16_t thr_idx); struct packet_io_stat *packet_io_stat(struct packet_io *packet_io, uint16_t thr_idx);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -1,4 +1,4 @@
set(SOURCE config.cpp stat.cpp stellar.cpp inject.cpp) set(SOURCE config.cpp stellar_stat.cpp stellar.cpp inject.cpp)
set(LIBRARY times plugin_manager session_manager ip_reassembly packet_io pthread fieldstat4 toml) set(LIBRARY times plugin_manager session_manager ip_reassembly packet_io pthread fieldstat4 toml)
add_library(stellar_core STATIC ${SOURCE}) add_library(stellar_core STATIC ${SOURCE})

View File

@@ -1,495 +0,0 @@
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "log.h"
#include "stat.h"
#include "fieldstat/fieldstat_easy.h"
#include "fieldstat/fieldstat_exporter.h"
#define STAT_LOG_ERROR(format, ...) LOG_ERROR("stat", format, ##__VA_ARGS__)
#define IS_FREE 0
#define IS_BUSY 0xf
struct stat_id
{
// device packet
int dev_rx_pkts;
int dev_rx_bytes;
int dev_tx_pkts;
int dev_tx_bytes;
// keep-alive packet
int keep_alive_pkts;
int keep_alive_bytes;
// raw packet
int raw_rx_pkts;
int raw_rx_bytes;
int raw_tx_pkts;
int raw_tx_bytes;
// drop packet
int drop_pkts;
int drop_bytes;
// inject packet
int inject_pkts;
int inject_bytes;
// ctrl packet
int ctrl_rx_pkts;
int ctrl_rx_bytes;
int ctrl_tx_pkts;
int ctrl_tx_bytes;
// ip reassembly
int ip4_flow_find;
int ip4_flow_add;
int ip4_flow_del;
int ip4_flow_timeout;
int ip4_flow_fail_no_space;
int ip4_flow_fail_overlap;
int ip4_flow_fail_many_frag;
int ip4_flow_fail_invalid_length;
int ip4_flow_bypass_dup_fist_frag;
int ip4_flow_bypass_dup_last_frag;
int ip6_flow_find;
int ip6_flow_add;
int ip6_flow_del;
int ip6_flow_timeout;
int ip6_flow_fail_no_space;
int ip6_flow_fail_overlap;
int ip6_flow_fail_many_frag;
int ip6_flow_fail_invalid_length;
int ip6_flow_bypass_dup_fist_frag;
int ip6_flow_bypass_dup_last_frag;
// TCP session
int total_nr_tcp_sess_used;
int curr_nr_tcp_sess_used;
int curr_nr_tcp_sess_opening;
int curr_nr_tcp_sess_active;
int curr_nr_tcp_sess_closing;
int curr_nr_tcp_sess_discard;
int curr_nr_tcp_sess_closed;
// UDP session
int total_nr_udp_sess_used;
int curr_nr_udp_sess_used;
int curr_nr_udp_sess_opening;
int curr_nr_udp_sess_active;
int curr_nr_udp_sess_closing;
int curr_nr_udp_sess_discard;
int curr_nr_udp_sess_closed;
// Evicted session
int nr_tcp_sess_evicted;
int nr_udp_sess_evicted;
// Packet
int nr_udp_pkts_nospace_bypass;
int nr_tcp_pkts_nospace_bypass;
int nr_tcp_pkts_nosess_bypass;
int nr_tcp_pkts_duped_bypass;
int nr_udp_pkts_duped_bypass;
int nr_udp_pkts_evctd_bypass;
// TCP segments
int nr_tcp_seg_received;
int nr_tcp_seg_expired;
int nr_tcp_seg_retransmit;
int nr_tcp_seg_overlap;
int nr_tcp_seg_no_space;
int nr_tcp_seg_inorder;
int nr_tcp_seg_reorded;
int nr_tcp_seg_buffered;
int nr_tcp_seg_released;
};
struct stellar_stat
{
char output_file[2048];
// thread stat
uint16_t nr_thread;
int flag[MAX_THREAD_NUM]; // IS_FREE or IS_BUSY
struct io_stat thr_io_stat[MAX_THREAD_NUM];
struct ip_reassembly_stat thr_ip_stat[MAX_THREAD_NUM];
struct session_manager_stat thr_sess_stat[MAX_THREAD_NUM];
// global stat
struct io_stat io_stat;
struct ip_reassembly_stat ip_stat;
struct session_manager_stat sess_stat;
struct stat_id ids;
struct fieldstat_easy *fs;
};
// python3 -m pip install prettytable
// python3 -m pip install jinja2
// /opt/MESA/bin/fieldstat_exporter.py local -j log/stellar_fs4.json -e -l --clear-screen
struct stellar_stat *stellar_stat_new(uint16_t nr_thread)
{
char cwd[1024] = {0};
struct stellar_stat *stat = (struct stellar_stat *)calloc(1, sizeof(struct stellar_stat));
if (stat == NULL)
{
return NULL;
}
if (getcwd(cwd, sizeof(cwd)) == NULL)
{
STAT_LOG_ERROR("failed to get current working directory: %s", strerror(errno));
goto error_out;
}
snprintf(stat->output_file, sizeof(stat->output_file), "%s/log/stellar_fs4.json", cwd);
stat->fs = fieldstat_easy_new(1, "stellar", NULL, 0);
if (stat->fs == NULL)
{
STAT_LOG_ERROR("failed to create fieldstat_easy");
goto error_out;
}
stat->nr_thread = nr_thread;
for (int i = 0; i < MAX_THREAD_NUM; i++)
{
stat->flag[i] = IS_FREE;
}
// device packet
stat->ids.dev_rx_pkts = fieldstat_easy_register_counter(stat->fs, "dev_rx_pkts");
stat->ids.dev_rx_bytes = fieldstat_easy_register_counter(stat->fs, "dev_rx_bytes");
stat->ids.dev_tx_pkts = fieldstat_easy_register_counter(stat->fs, "dev_tx_pkts");
stat->ids.dev_tx_bytes = fieldstat_easy_register_counter(stat->fs, "dev_tx_bytes");
// keep-alive packet
stat->ids.keep_alive_pkts = fieldstat_easy_register_counter(stat->fs, "keep_alive_pkts");
stat->ids.keep_alive_bytes = fieldstat_easy_register_counter(stat->fs, "keep_alive_bytes");
// raw packet
stat->ids.raw_rx_pkts = fieldstat_easy_register_counter(stat->fs, "raw_rx_pkts");
stat->ids.raw_rx_bytes = fieldstat_easy_register_counter(stat->fs, "raw_rx_bytes");
stat->ids.raw_tx_pkts = fieldstat_easy_register_counter(stat->fs, "raw_tx_pkts");
stat->ids.raw_tx_bytes = fieldstat_easy_register_counter(stat->fs, "raw_tx_bytes");
// drop packet
stat->ids.drop_pkts = fieldstat_easy_register_counter(stat->fs, "drop_pkts");
stat->ids.drop_bytes = fieldstat_easy_register_counter(stat->fs, "drop_bytes");
// inject packet
stat->ids.inject_pkts = fieldstat_easy_register_counter(stat->fs, "inject_pkts");
stat->ids.inject_bytes = fieldstat_easy_register_counter(stat->fs, "inject_bytes");
// ctrl packet
stat->ids.ctrl_rx_pkts = fieldstat_easy_register_counter(stat->fs, "ctrl_rx_pkts");
stat->ids.ctrl_rx_bytes = fieldstat_easy_register_counter(stat->fs, "ctrl_rx_bytes");
stat->ids.ctrl_tx_pkts = fieldstat_easy_register_counter(stat->fs, "ctrl_tx_pkts");
stat->ids.ctrl_tx_bytes = fieldstat_easy_register_counter(stat->fs, "ctrl_tx_bytes");
// ip reassembly
stat->ids.ip4_flow_find = fieldstat_easy_register_counter(stat->fs, "ip4_flow_find");
stat->ids.ip4_flow_add = fieldstat_easy_register_counter(stat->fs, "ip4_flow_add");
stat->ids.ip4_flow_del = fieldstat_easy_register_counter(stat->fs, "ip4_flow_del");
stat->ids.ip4_flow_timeout = fieldstat_easy_register_counter(stat->fs, "ip4_flow_timeout");
stat->ids.ip4_flow_fail_no_space = fieldstat_easy_register_counter(stat->fs, "ip4_flow_fail_no_space");
stat->ids.ip4_flow_fail_overlap = fieldstat_easy_register_counter(stat->fs, "ip4_flow_fail_overlap");
stat->ids.ip4_flow_fail_many_frag = fieldstat_easy_register_counter(stat->fs, "ip4_flow_fail_many_frag");
stat->ids.ip4_flow_fail_invalid_length = fieldstat_easy_register_counter(stat->fs, "ip4_flow_fail_invalid_length");
stat->ids.ip4_flow_bypass_dup_fist_frag = fieldstat_easy_register_counter(stat->fs, "ip4_flow_bypass_dup_fist_frag");
stat->ids.ip4_flow_bypass_dup_last_frag = fieldstat_easy_register_counter(stat->fs, "ip4_flow_bypass_dup_last_frag");
stat->ids.ip6_flow_find = fieldstat_easy_register_counter(stat->fs, "ip6_flow_find");
stat->ids.ip6_flow_add = fieldstat_easy_register_counter(stat->fs, "ip6_flow_add");
stat->ids.ip6_flow_del = fieldstat_easy_register_counter(stat->fs, "ip6_flow_del");
stat->ids.ip6_flow_timeout = fieldstat_easy_register_counter(stat->fs, "ip6_flow_timeout");
stat->ids.ip6_flow_fail_no_space = fieldstat_easy_register_counter(stat->fs, "ip6_flow_fail_no_space");
stat->ids.ip6_flow_fail_overlap = fieldstat_easy_register_counter(stat->fs, "ip6_flow_fail_overlap");
stat->ids.ip6_flow_fail_many_frag = fieldstat_easy_register_counter(stat->fs, "ip6_flow_fail_many_frag");
stat->ids.ip6_flow_fail_invalid_length = fieldstat_easy_register_counter(stat->fs, "ip6_flow_fail_invalid_length");
stat->ids.ip6_flow_bypass_dup_fist_frag = fieldstat_easy_register_counter(stat->fs, "ip6_flow_bypass_dup_fist_frag");
stat->ids.ip6_flow_bypass_dup_last_frag = fieldstat_easy_register_counter(stat->fs, "ip6_flow_bypass_dup_last_frag");
// TCP session
stat->ids.total_nr_tcp_sess_used = fieldstat_easy_register_counter(stat->fs, "total_nr_tcp_sess_used");
stat->ids.curr_nr_tcp_sess_used = fieldstat_easy_register_counter(stat->fs, "curr_tcp_sess_used");
stat->ids.curr_nr_tcp_sess_opening = fieldstat_easy_register_counter(stat->fs, "curr_tcp_sess_opening");
stat->ids.curr_nr_tcp_sess_active = fieldstat_easy_register_counter(stat->fs, "curr_tcp_sess_active");
stat->ids.curr_nr_tcp_sess_closing = fieldstat_easy_register_counter(stat->fs, "curr_tcp_sess_closing");
stat->ids.curr_nr_tcp_sess_discard = fieldstat_easy_register_counter(stat->fs, "curr_tcp_sess_discard");
stat->ids.curr_nr_tcp_sess_closed = fieldstat_easy_register_counter(stat->fs, "curr_tcp_sess_closed");
// UDP session
stat->ids.total_nr_udp_sess_used = fieldstat_easy_register_counter(stat->fs, "total_nr_udp_sess_used");
stat->ids.curr_nr_udp_sess_used = fieldstat_easy_register_counter(stat->fs, "curr_udp_sess_used");
stat->ids.curr_nr_udp_sess_opening = fieldstat_easy_register_counter(stat->fs, "curr_udp_sess_opening");
stat->ids.curr_nr_udp_sess_active = fieldstat_easy_register_counter(stat->fs, "curr_udp_sess_active");
stat->ids.curr_nr_udp_sess_closing = fieldstat_easy_register_counter(stat->fs, "curr_udp_sess_closing");
stat->ids.curr_nr_udp_sess_discard = fieldstat_easy_register_counter(stat->fs, "curr_udp_sess_discard");
stat->ids.curr_nr_udp_sess_closed = fieldstat_easy_register_counter(stat->fs, "curr_udp_sess_closed");
// Evicted session
stat->ids.nr_tcp_sess_evicted = fieldstat_easy_register_counter(stat->fs, "tcp_sess_evicted");
stat->ids.nr_udp_sess_evicted = fieldstat_easy_register_counter(stat->fs, "udp_sess_evicted");
// Packet
stat->ids.nr_udp_pkts_nospace_bypass = fieldstat_easy_register_counter(stat->fs, "udp_pkts_nospace_bypass");
stat->ids.nr_tcp_pkts_nospace_bypass = fieldstat_easy_register_counter(stat->fs, "tcp_pkts_nospace_bypass");
stat->ids.nr_tcp_pkts_nosess_bypass = fieldstat_easy_register_counter(stat->fs, "tcp_pkts_nosess_bypass");
stat->ids.nr_tcp_pkts_duped_bypass = fieldstat_easy_register_counter(stat->fs, "tcp_pkts_duped_bypass");
stat->ids.nr_udp_pkts_duped_bypass = fieldstat_easy_register_counter(stat->fs, "udp_pkts_duped_bypass");
stat->ids.nr_udp_pkts_evctd_bypass = fieldstat_easy_register_counter(stat->fs, "udp_pkts_evctd_bypass");
// TCP segments
stat->ids.nr_tcp_seg_received = fieldstat_easy_register_counter(stat->fs, "tcp_seg_received");
stat->ids.nr_tcp_seg_expired = fieldstat_easy_register_counter(stat->fs, "tcp_seg_expired");
stat->ids.nr_tcp_seg_retransmit = fieldstat_easy_register_counter(stat->fs, "tcp_seg_retransmit");
stat->ids.nr_tcp_seg_overlap = fieldstat_easy_register_counter(stat->fs, "tcp_seg_overlap");
stat->ids.nr_tcp_seg_no_space = fieldstat_easy_register_counter(stat->fs, "tcp_seg_no_space");
stat->ids.nr_tcp_seg_inorder = fieldstat_easy_register_counter(stat->fs, "tcp_seg_inorder");
stat->ids.nr_tcp_seg_reorded = fieldstat_easy_register_counter(stat->fs, "tcp_seg_reorded");
stat->ids.nr_tcp_seg_buffered = fieldstat_easy_register_counter(stat->fs, "tcp_seg_buffered");
stat->ids.nr_tcp_seg_released = fieldstat_easy_register_counter(stat->fs, "tcp_seg_released");
return stat;
error_out:
stellar_stat_free(stat);
return NULL;
}
void stellar_stat_free(struct stellar_stat *stat)
{
if (stat)
{
if (stat->fs)
{
fieldstat_easy_free(stat->fs);
stat->fs = NULL;
}
free(stat);
stat = NULL;
}
}
void stellar_stat_output(struct stellar_stat *stat)
{
// merge thread stat to global stat
for (uint16_t i = 0; i < stat->nr_thread; i++)
{
if (ATOMIC_READ(&(stat->flag[i])) == IS_BUSY)
{
// packet io stat
stat->io_stat.dev_rx_pkts += stat->thr_io_stat[i].dev_rx_pkts;
stat->io_stat.dev_rx_bytes += stat->thr_io_stat[i].dev_rx_bytes;
stat->io_stat.dev_tx_pkts += stat->thr_io_stat[i].dev_tx_pkts;
stat->io_stat.dev_tx_bytes += stat->thr_io_stat[i].dev_tx_bytes;
stat->io_stat.keep_alive_pkts += stat->thr_io_stat[i].keep_alive_pkts;
stat->io_stat.keep_alive_bytes += stat->thr_io_stat[i].keep_alive_bytes;
stat->io_stat.raw_rx_pkts += stat->thr_io_stat[i].raw_rx_pkts;
stat->io_stat.raw_rx_bytes += stat->thr_io_stat[i].raw_rx_bytes;
stat->io_stat.raw_tx_pkts += stat->thr_io_stat[i].raw_tx_pkts;
stat->io_stat.raw_tx_bytes += stat->thr_io_stat[i].raw_tx_bytes;
stat->io_stat.drop_pkts += stat->thr_io_stat[i].drop_pkts;
stat->io_stat.drop_bytes += stat->thr_io_stat[i].drop_bytes;
stat->io_stat.inject_pkts += stat->thr_io_stat[i].inject_pkts;
stat->io_stat.inject_bytes += stat->thr_io_stat[i].inject_bytes;
stat->io_stat.ctrl_rx_pkts += stat->thr_io_stat[i].ctrl_rx_pkts;
stat->io_stat.ctrl_rx_bytes += stat->thr_io_stat[i].ctrl_rx_bytes;
stat->io_stat.ctrl_tx_pkts += stat->thr_io_stat[i].ctrl_tx_pkts;
stat->io_stat.ctrl_tx_bytes += stat->thr_io_stat[i].ctrl_tx_bytes;
// ip reassembly stat
stat->ip_stat.ip4_flow_find += stat->thr_ip_stat[i].ip4_flow_find;
stat->ip_stat.ip4_flow_add += stat->thr_ip_stat[i].ip4_flow_add;
stat->ip_stat.ip4_flow_del += stat->thr_ip_stat[i].ip4_flow_del;
stat->ip_stat.ip4_flow_timeout += stat->thr_ip_stat[i].ip4_flow_timeout;
stat->ip_stat.ip4_flow_fail_no_space += stat->thr_ip_stat[i].ip4_flow_fail_no_space;
stat->ip_stat.ip4_flow_fail_overlap += stat->thr_ip_stat[i].ip4_flow_fail_overlap;
stat->ip_stat.ip4_flow_fail_many_frag += stat->thr_ip_stat[i].ip4_flow_fail_many_frag;
stat->ip_stat.ip4_flow_fail_invalid_length += stat->thr_ip_stat[i].ip4_flow_fail_invalid_length;
stat->ip_stat.ip4_flow_bypass_dup_fist_frag += stat->thr_ip_stat[i].ip4_flow_bypass_dup_fist_frag;
stat->ip_stat.ip4_flow_bypass_dup_last_frag += stat->thr_ip_stat[i].ip4_flow_bypass_dup_last_frag;
stat->ip_stat.ip6_flow_find += stat->thr_ip_stat[i].ip6_flow_find;
stat->ip_stat.ip6_flow_add += stat->thr_ip_stat[i].ip6_flow_add;
stat->ip_stat.ip6_flow_del += stat->thr_ip_stat[i].ip6_flow_del;
stat->ip_stat.ip6_flow_timeout += stat->thr_ip_stat[i].ip6_flow_timeout;
stat->ip_stat.ip6_flow_fail_no_space += stat->thr_ip_stat[i].ip6_flow_fail_no_space;
stat->ip_stat.ip6_flow_fail_overlap += stat->thr_ip_stat[i].ip6_flow_fail_overlap;
stat->ip_stat.ip6_flow_fail_many_frag += stat->thr_ip_stat[i].ip6_flow_fail_many_frag;
stat->ip_stat.ip6_flow_fail_invalid_length += stat->thr_ip_stat[i].ip6_flow_fail_invalid_length;
stat->ip_stat.ip6_flow_bypass_dup_fist_frag += stat->thr_ip_stat[i].ip6_flow_bypass_dup_fist_frag;
stat->ip_stat.ip6_flow_bypass_dup_last_frag += stat->thr_ip_stat[i].ip6_flow_bypass_dup_last_frag;
memset(&stat->thr_ip_stat[i], 0, sizeof(struct ip_reassembly_stat));
// session manager stat
stat->sess_stat.total_nr_tcp_sess_used += stat->thr_sess_stat[i].total_nr_tcp_sess_used;
stat->sess_stat.curr_nr_tcp_sess_used += stat->thr_sess_stat[i].curr_nr_tcp_sess_used;
stat->sess_stat.curr_nr_tcp_sess_opening += stat->thr_sess_stat[i].curr_nr_tcp_sess_opening;
stat->sess_stat.curr_nr_tcp_sess_active += stat->thr_sess_stat[i].curr_nr_tcp_sess_active;
stat->sess_stat.curr_nr_tcp_sess_closing += stat->thr_sess_stat[i].curr_nr_tcp_sess_closing;
stat->sess_stat.curr_nr_tcp_sess_discard += stat->thr_sess_stat[i].curr_nr_tcp_sess_discard;
stat->sess_stat.curr_nr_tcp_sess_closed += stat->thr_sess_stat[i].curr_nr_tcp_sess_closed;
stat->sess_stat.total_nr_udp_sess_used += stat->thr_sess_stat[i].total_nr_udp_sess_used;
stat->sess_stat.curr_nr_udp_sess_used += stat->thr_sess_stat[i].curr_nr_udp_sess_used;
stat->sess_stat.curr_nr_udp_sess_opening += stat->thr_sess_stat[i].curr_nr_udp_sess_opening;
stat->sess_stat.curr_nr_udp_sess_active += stat->thr_sess_stat[i].curr_nr_udp_sess_active;
stat->sess_stat.curr_nr_udp_sess_closing += stat->thr_sess_stat[i].curr_nr_udp_sess_closing;
stat->sess_stat.curr_nr_udp_sess_discard += stat->thr_sess_stat[i].curr_nr_udp_sess_discard;
stat->sess_stat.curr_nr_udp_sess_closed += stat->thr_sess_stat[i].curr_nr_udp_sess_closed;
stat->sess_stat.nr_tcp_sess_evicted += stat->thr_sess_stat[i].nr_tcp_sess_evicted;
stat->sess_stat.nr_udp_sess_evicted += stat->thr_sess_stat[i].nr_udp_sess_evicted;
stat->sess_stat.nr_udp_pkts_nospace_bypass += stat->thr_sess_stat[i].nr_udp_pkts_nospace_bypass;
stat->sess_stat.nr_tcp_pkts_nospace_bypass += stat->thr_sess_stat[i].nr_tcp_pkts_nospace_bypass;
stat->sess_stat.nr_tcp_pkts_nosess_bypass += stat->thr_sess_stat[i].nr_tcp_pkts_nosess_bypass;
stat->sess_stat.nr_tcp_pkts_duped_bypass += stat->thr_sess_stat[i].nr_tcp_pkts_duped_bypass;
stat->sess_stat.nr_udp_pkts_duped_bypass += stat->thr_sess_stat[i].nr_udp_pkts_duped_bypass;
stat->sess_stat.nr_udp_pkts_evctd_bypass += stat->thr_sess_stat[i].nr_udp_pkts_evctd_bypass;
stat->sess_stat.nr_tcp_seg_received += stat->thr_sess_stat[i].nr_tcp_seg_received;
stat->sess_stat.nr_tcp_seg_expired += stat->thr_sess_stat[i].nr_tcp_seg_expired;
stat->sess_stat.nr_tcp_seg_retransmit += stat->thr_sess_stat[i].nr_tcp_seg_retransmit;
stat->sess_stat.nr_tcp_seg_overlap += stat->thr_sess_stat[i].nr_tcp_seg_overlap;
stat->sess_stat.nr_tcp_seg_no_space += stat->thr_sess_stat[i].nr_tcp_seg_no_space;
stat->sess_stat.nr_tcp_seg_inorder += stat->thr_sess_stat[i].nr_tcp_seg_inorder;
stat->sess_stat.nr_tcp_seg_reorded += stat->thr_sess_stat[i].nr_tcp_seg_reorded;
stat->sess_stat.nr_tcp_seg_buffered += stat->thr_sess_stat[i].nr_tcp_seg_buffered;
stat->sess_stat.nr_tcp_seg_released += stat->thr_sess_stat[i].nr_tcp_seg_released;
memset(&stat->thr_sess_stat[i], 0, sizeof(struct session_manager_stat));
ATOMIC_SET(&(stat->flag[i]), IS_FREE);
}
}
// device packet
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.dev_rx_pkts, NULL, 0, stat->io_stat.dev_rx_pkts);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.dev_rx_bytes, NULL, 0, stat->io_stat.dev_rx_bytes);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.dev_tx_pkts, NULL, 0, stat->io_stat.dev_tx_pkts);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.dev_tx_bytes, NULL, 0, stat->io_stat.dev_tx_bytes);
// keep-alive packet
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.keep_alive_pkts, NULL, 0, stat->io_stat.keep_alive_pkts);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.keep_alive_bytes, NULL, 0, stat->io_stat.keep_alive_bytes);
// raw packet
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.raw_rx_pkts, NULL, 0, stat->io_stat.raw_rx_pkts);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.raw_rx_bytes, NULL, 0, stat->io_stat.raw_rx_bytes);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.raw_tx_pkts, NULL, 0, stat->io_stat.raw_tx_pkts);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.raw_tx_bytes, NULL, 0, stat->io_stat.raw_tx_bytes);
// drop packet
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.drop_pkts, NULL, 0, stat->io_stat.drop_pkts);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.drop_bytes, NULL, 0, stat->io_stat.drop_bytes);
// inject packet
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.inject_pkts, NULL, 0, stat->io_stat.inject_pkts);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.inject_bytes, NULL, 0, stat->io_stat.inject_bytes);
// ctrl packet
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ctrl_rx_pkts, NULL, 0, stat->io_stat.ctrl_rx_pkts);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ctrl_rx_bytes, NULL, 0, stat->io_stat.ctrl_rx_bytes);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ctrl_tx_pkts, NULL, 0, stat->io_stat.ctrl_tx_pkts);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ctrl_tx_bytes, NULL, 0, stat->io_stat.ctrl_tx_bytes);
// ip reassembly
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip4_flow_find, NULL, 0, stat->ip_stat.ip4_flow_find);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip4_flow_add, NULL, 0, stat->ip_stat.ip4_flow_add);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip4_flow_del, NULL, 0, stat->ip_stat.ip4_flow_del);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip4_flow_timeout, NULL, 0, stat->ip_stat.ip4_flow_timeout);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip4_flow_fail_no_space, NULL, 0, stat->ip_stat.ip4_flow_fail_no_space);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip4_flow_fail_overlap, NULL, 0, stat->ip_stat.ip4_flow_fail_overlap);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip4_flow_fail_many_frag, NULL, 0, stat->ip_stat.ip4_flow_fail_many_frag);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip4_flow_fail_invalid_length, NULL, 0, stat->ip_stat.ip4_flow_fail_invalid_length);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip4_flow_bypass_dup_fist_frag, NULL, 0, stat->ip_stat.ip4_flow_bypass_dup_fist_frag);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip4_flow_bypass_dup_last_frag, NULL, 0, stat->ip_stat.ip4_flow_bypass_dup_last_frag);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip6_flow_find, NULL, 0, stat->ip_stat.ip6_flow_find);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip6_flow_add, NULL, 0, stat->ip_stat.ip6_flow_add);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip6_flow_del, NULL, 0, stat->ip_stat.ip6_flow_del);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip6_flow_timeout, NULL, 0, stat->ip_stat.ip6_flow_timeout);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip6_flow_fail_no_space, NULL, 0, stat->ip_stat.ip6_flow_fail_no_space);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip6_flow_fail_overlap, NULL, 0, stat->ip_stat.ip6_flow_fail_overlap);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip6_flow_fail_many_frag, NULL, 0, stat->ip_stat.ip6_flow_fail_many_frag);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip6_flow_fail_invalid_length, NULL, 0, stat->ip_stat.ip6_flow_fail_invalid_length);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip6_flow_bypass_dup_fist_frag, NULL, 0, stat->ip_stat.ip6_flow_bypass_dup_fist_frag);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip6_flow_bypass_dup_last_frag, NULL, 0, stat->ip_stat.ip6_flow_bypass_dup_last_frag);
// TCP session
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.total_nr_tcp_sess_used, NULL, 0, stat->sess_stat.total_nr_tcp_sess_used);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.curr_nr_tcp_sess_used, NULL, 0, stat->sess_stat.curr_nr_tcp_sess_used);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.curr_nr_tcp_sess_opening, NULL, 0, stat->sess_stat.curr_nr_tcp_sess_opening);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.curr_nr_tcp_sess_active, NULL, 0, stat->sess_stat.curr_nr_tcp_sess_active);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.curr_nr_tcp_sess_closing, NULL, 0, stat->sess_stat.curr_nr_tcp_sess_closing);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.curr_nr_tcp_sess_discard, NULL, 0, stat->sess_stat.curr_nr_tcp_sess_discard);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.curr_nr_tcp_sess_closed, NULL, 0, stat->sess_stat.curr_nr_tcp_sess_closed);
// UDP session
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.total_nr_udp_sess_used, NULL, 0, stat->sess_stat.total_nr_udp_sess_used);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.curr_nr_udp_sess_used, NULL, 0, stat->sess_stat.curr_nr_udp_sess_used);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.curr_nr_udp_sess_opening, NULL, 0, stat->sess_stat.curr_nr_udp_sess_opening);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.curr_nr_udp_sess_active, NULL, 0, stat->sess_stat.curr_nr_udp_sess_active);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.curr_nr_udp_sess_closing, NULL, 0, stat->sess_stat.curr_nr_udp_sess_closing);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.curr_nr_udp_sess_discard, NULL, 0, stat->sess_stat.curr_nr_udp_sess_discard);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.curr_nr_udp_sess_closed, NULL, 0, stat->sess_stat.curr_nr_udp_sess_closed);
// Evicted session
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_tcp_sess_evicted, NULL, 0, stat->sess_stat.nr_tcp_sess_evicted);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_udp_sess_evicted, NULL, 0, stat->sess_stat.nr_udp_sess_evicted);
// Packet
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_udp_pkts_nospace_bypass, NULL, 0, stat->sess_stat.nr_udp_pkts_nospace_bypass);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_tcp_pkts_nospace_bypass, NULL, 0, stat->sess_stat.nr_tcp_pkts_nospace_bypass);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_tcp_pkts_nosess_bypass, NULL, 0, stat->sess_stat.nr_tcp_pkts_nosess_bypass);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_tcp_pkts_duped_bypass, NULL, 0, stat->sess_stat.nr_tcp_pkts_duped_bypass);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_udp_pkts_duped_bypass, NULL, 0, stat->sess_stat.nr_udp_pkts_duped_bypass);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_udp_pkts_evctd_bypass, NULL, 0, stat->sess_stat.nr_udp_pkts_evctd_bypass);
// TCP segments
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_tcp_seg_received, NULL, 0, stat->sess_stat.nr_tcp_seg_received);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_tcp_seg_expired, NULL, 0, stat->sess_stat.nr_tcp_seg_expired);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_tcp_seg_retransmit, NULL, 0, stat->sess_stat.nr_tcp_seg_retransmit);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_tcp_seg_overlap, NULL, 0, stat->sess_stat.nr_tcp_seg_overlap);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_tcp_seg_no_space, NULL, 0, stat->sess_stat.nr_tcp_seg_no_space);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_tcp_seg_inorder, NULL, 0, stat->sess_stat.nr_tcp_seg_inorder);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_tcp_seg_reorded, NULL, 0, stat->sess_stat.nr_tcp_seg_reorded);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_tcp_seg_buffered, NULL, 0, stat->sess_stat.nr_tcp_seg_buffered);
fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_tcp_seg_released, NULL, 0, stat->sess_stat.nr_tcp_seg_released);
char *buff;
size_t len;
fieldstat_easy_output(stat->fs, &buff, &len);
if (buff)
{
FILE *fp = fopen(stat->output_file, "w+");
if (fp == NULL)
{
STAT_LOG_ERROR("failed to open file: %s, %s", stat->output_file, strerror(errno));
}
else
{
fwrite(buff, len, 1, fp);
fflush(fp);
fclose(fp);
}
free(buff);
}
memset(&stat->io_stat, 0, sizeof(struct io_stat));
memset(&stat->ip_stat, 0, sizeof(struct ip_reassembly_stat));
memset(&stat->sess_stat, 0, sizeof(struct session_manager_stat));
}
void stellar_stat_merge(struct stellar_stat *stat, const struct thread_stat *thr_stat, uint16_t thr_idx)
{
if (ATOMIC_READ(&(stat->flag[thr_idx])) == IS_FREE)
{
memcpy(&stat->thr_io_stat[thr_idx], thr_stat->io, sizeof(struct io_stat));
memcpy(&stat->thr_ip_stat[thr_idx], thr_stat->ip_rea, sizeof(struct ip_reassembly_stat));
memcpy(&stat->thr_sess_stat[thr_idx], thr_stat->sess_mgr, sizeof(struct session_manager_stat));
ATOMIC_SET(&(stat->flag[thr_idx]), IS_BUSY);
}
}

View File

@@ -8,7 +8,6 @@
#include <sys/prctl.h> #include <sys/prctl.h>
#include "log.h" #include "log.h"
#include "stat.h"
#include "logo.h" #include "logo.h"
#include "times.h" #include "times.h"
#include "config.h" #include "config.h"
@@ -16,6 +15,7 @@
#include "packet_utils.h" #include "packet_utils.h"
#include "session_utils.h" #include "session_utils.h"
#include "id_generator.h" #include "id_generator.h"
#include "stellar_stat.h"
#include "stellar_utils.h" #include "stellar_utils.h"
#include "plugin_manager.h" #include "plugin_manager.h"
@@ -132,9 +132,9 @@ static inline void merge_thread_stat(struct stellar_thread *thread, uint64_t now
{ {
struct stellar_runtime *runtime = thread->runtime; struct stellar_runtime *runtime = thread->runtime;
struct thread_stat thr_stat = { struct thread_stat thr_stat = {
packet_io_stat(runtime->packet_io, thread->idx), .packet_io = packet_io_stat(runtime->packet_io, thread->idx),
ip_reassembly_stat(thread->ip_mgr), .ip_reassembly = ip_reassembly_stat(thread->ip_mgr),
session_manager_stat(thread->sess_mgr), .session_mgr = session_manager_stat(thread->sess_mgr),
}; };
stellar_stat_merge(runtime->stat, &thr_stat, thread->idx); stellar_stat_merge(runtime->stat, &thr_stat, thread->idx);
} }

View File

@@ -0,0 +1,306 @@
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "log.h"
#include "stellar_stat.h"
#include "fieldstat/fieldstat_easy.h"
#include "fieldstat/fieldstat_exporter.h"
#define STAT_LOG_ERROR(format, ...) LOG_ERROR("stat", format, ##__VA_ARGS__)
#define IS_FREE 0
#define IS_BUSY 0xf
typedef uint64_t get_val_func(struct thread_stat *thr_stat);
static inline uint64_t get_dev_rx_pkts(struct thread_stat *thr_stat) { return thr_stat->packet_io->dev_rx_pkts; }
static inline uint64_t get_dev_rx_bytes(struct thread_stat *thr_stat) { return thr_stat->packet_io->dev_rx_bytes; }
static inline uint64_t get_dev_tx_pkts(struct thread_stat *thr_stat) { return thr_stat->packet_io->dev_tx_pkts; }
static inline uint64_t get_dev_tx_bytes(struct thread_stat *thr_stat) { return thr_stat->packet_io->dev_tx_bytes; }
static inline uint64_t get_keep_alive_pkts(struct thread_stat *thr_stat) { return thr_stat->packet_io->keep_alive_pkts; }
static inline uint64_t get_keep_alive_bytes(struct thread_stat *thr_stat) { return thr_stat->packet_io->keep_alive_bytes; }
static inline uint64_t get_raw_rx_pkts(struct thread_stat *thr_stat) { return thr_stat->packet_io->raw_rx_pkts; }
static inline uint64_t get_raw_rx_bytes(struct thread_stat *thr_stat) { return thr_stat->packet_io->raw_rx_bytes; }
static inline uint64_t get_raw_tx_pkts(struct thread_stat *thr_stat) { return thr_stat->packet_io->raw_tx_pkts; }
static inline uint64_t get_raw_tx_bytes(struct thread_stat *thr_stat) { return thr_stat->packet_io->raw_tx_bytes; }
static inline uint64_t get_drop_pkts(struct thread_stat *thr_stat) { return thr_stat->packet_io->drop_pkts; }
static inline uint64_t get_drop_bytes(struct thread_stat *thr_stat) { return thr_stat->packet_io->drop_bytes; }
static inline uint64_t get_inject_pkts(struct thread_stat *thr_stat) { return thr_stat->packet_io->inject_pkts; }
static inline uint64_t get_inject_bytes(struct thread_stat *thr_stat) { return thr_stat->packet_io->inject_bytes; }
static inline uint64_t get_ctrl_rx_pkts(struct thread_stat *thr_stat) { return thr_stat->packet_io->ctrl_rx_pkts; }
static inline uint64_t get_ctrl_rx_bytes(struct thread_stat *thr_stat) { return thr_stat->packet_io->ctrl_rx_bytes; }
static inline uint64_t get_ctrl_tx_pkts(struct thread_stat *thr_stat) { return thr_stat->packet_io->ctrl_tx_pkts; }
static inline uint64_t get_ctrl_tx_bytes(struct thread_stat *thr_stat) { return thr_stat->packet_io->ctrl_tx_bytes; }
static inline uint64_t get_ip4_flow_find(struct thread_stat *thr_stat) { return thr_stat->ip_reassembly->ip4_flow_find; }
static inline uint64_t get_ip4_flow_add(struct thread_stat *thr_stat) { return thr_stat->ip_reassembly->ip4_flow_add; }
static inline uint64_t get_ip4_flow_del(struct thread_stat *thr_stat) { return thr_stat->ip_reassembly->ip4_flow_del; }
static inline uint64_t get_ip4_flow_timeout(struct thread_stat *thr_stat) { return thr_stat->ip_reassembly->ip4_flow_timeout; }
static inline uint64_t get_ip4_flow_fail_no_space(struct thread_stat *thr_stat) { return thr_stat->ip_reassembly->ip4_flow_fail_no_space; }
static inline uint64_t get_ip4_flow_fail_overlap(struct thread_stat *thr_stat) { return thr_stat->ip_reassembly->ip4_flow_fail_overlap; }
static inline uint64_t get_ip4_flow_fail_many_frag(struct thread_stat *thr_stat) { return thr_stat->ip_reassembly->ip4_flow_fail_many_frag; }
static inline uint64_t get_ip4_flow_fail_invalid_length(struct thread_stat *thr_stat) { return thr_stat->ip_reassembly->ip4_flow_fail_invalid_length; }
static inline uint64_t get_ip4_flow_bypass_dup_fist_frag(struct thread_stat *thr_stat) { return thr_stat->ip_reassembly->ip4_flow_bypass_dup_fist_frag; }
static inline uint64_t get_ip4_flow_bypass_dup_last_frag(struct thread_stat *thr_stat) { return thr_stat->ip_reassembly->ip4_flow_bypass_dup_last_frag; }
static inline uint64_t get_ip6_flow_find(struct thread_stat *thr_stat) { return thr_stat->ip_reassembly->ip6_flow_find; }
static inline uint64_t get_ip6_flow_add(struct thread_stat *thr_stat) { return thr_stat->ip_reassembly->ip6_flow_add; }
static inline uint64_t get_ip6_flow_del(struct thread_stat *thr_stat) { return thr_stat->ip_reassembly->ip6_flow_del; }
static inline uint64_t get_ip6_flow_timeout(struct thread_stat *thr_stat) { return thr_stat->ip_reassembly->ip6_flow_timeout; }
static inline uint64_t get_ip6_flow_fail_no_space(struct thread_stat *thr_stat) { return thr_stat->ip_reassembly->ip6_flow_fail_no_space; }
static inline uint64_t get_ip6_flow_fail_overlap(struct thread_stat *thr_stat) { return thr_stat->ip_reassembly->ip6_flow_fail_overlap; }
static inline uint64_t get_ip6_flow_fail_many_frag(struct thread_stat *thr_stat) { return thr_stat->ip_reassembly->ip6_flow_fail_many_frag; }
static inline uint64_t get_ip6_flow_fail_invalid_length(struct thread_stat *thr_stat) { return thr_stat->ip_reassembly->ip6_flow_fail_invalid_length; }
static inline uint64_t get_ip6_flow_bypass_dup_fist_frag(struct thread_stat *thr_stat) { return thr_stat->ip_reassembly->ip6_flow_bypass_dup_fist_frag; }
static inline uint64_t get_ip6_flow_bypass_dup_last_frag(struct thread_stat *thr_stat) { return thr_stat->ip_reassembly->ip6_flow_bypass_dup_last_frag; }
static inline uint64_t get_total_nr_tcp_sess_used(struct thread_stat *thr_stat) { return thr_stat->session_mgr->total_nr_tcp_sess_used; }
static inline uint64_t get_curr_nr_tcp_sess_used(struct thread_stat *thr_stat) { return thr_stat->session_mgr->curr_nr_tcp_sess_used; }
static inline uint64_t get_curr_nr_tcp_sess_opening(struct thread_stat *thr_stat) { return thr_stat->session_mgr->curr_nr_tcp_sess_opening; }
static inline uint64_t get_curr_nr_tcp_sess_active(struct thread_stat *thr_stat) { return thr_stat->session_mgr->curr_nr_tcp_sess_active; }
static inline uint64_t get_curr_nr_tcp_sess_closing(struct thread_stat *thr_stat) { return thr_stat->session_mgr->curr_nr_tcp_sess_closing; }
static inline uint64_t get_curr_nr_tcp_sess_discard(struct thread_stat *thr_stat) { return thr_stat->session_mgr->curr_nr_tcp_sess_discard; }
static inline uint64_t get_curr_nr_tcp_sess_closed(struct thread_stat *thr_stat) { return thr_stat->session_mgr->curr_nr_tcp_sess_closed; }
static inline uint64_t get_total_nr_udp_sess_used(struct thread_stat *thr_stat) { return thr_stat->session_mgr->total_nr_udp_sess_used; }
static inline uint64_t get_curr_nr_udp_sess_used(struct thread_stat *thr_stat) { return thr_stat->session_mgr->curr_nr_udp_sess_used; }
static inline uint64_t get_curr_nr_udp_sess_opening(struct thread_stat *thr_stat) { return thr_stat->session_mgr->curr_nr_udp_sess_opening; }
static inline uint64_t get_curr_nr_udp_sess_active(struct thread_stat *thr_stat) { return thr_stat->session_mgr->curr_nr_udp_sess_active; }
static inline uint64_t get_curr_nr_udp_sess_closing(struct thread_stat *thr_stat) { return thr_stat->session_mgr->curr_nr_udp_sess_closing; }
static inline uint64_t get_curr_nr_udp_sess_discard(struct thread_stat *thr_stat) { return thr_stat->session_mgr->curr_nr_udp_sess_discard; }
static inline uint64_t get_curr_nr_udp_sess_closed(struct thread_stat *thr_stat) { return thr_stat->session_mgr->curr_nr_udp_sess_closed; }
static inline uint64_t get_nr_tcp_sess_evicted(struct thread_stat *thr_stat) { return thr_stat->session_mgr->nr_tcp_sess_evicted; }
static inline uint64_t get_nr_udp_sess_evicted(struct thread_stat *thr_stat) { return thr_stat->session_mgr->nr_udp_sess_evicted; }
static inline uint64_t get_nr_udp_pkts_nospace_bypass(struct thread_stat *thr_stat) { return thr_stat->session_mgr->nr_udp_pkts_nospace_bypass; }
static inline uint64_t get_nr_tcp_pkts_nospace_bypass(struct thread_stat *thr_stat) { return thr_stat->session_mgr->nr_tcp_pkts_nospace_bypass; }
static inline uint64_t get_nr_tcp_pkts_nosess_bypass(struct thread_stat *thr_stat) { return thr_stat->session_mgr->nr_tcp_pkts_nosess_bypass; }
static inline uint64_t get_nr_tcp_pkts_duped_bypass(struct thread_stat *thr_stat) { return thr_stat->session_mgr->nr_tcp_pkts_duped_bypass; }
static inline uint64_t get_nr_udp_pkts_duped_bypass(struct thread_stat *thr_stat) { return thr_stat->session_mgr->nr_udp_pkts_duped_bypass; }
static inline uint64_t get_nr_udp_pkts_evctd_bypass(struct thread_stat *thr_stat) { return thr_stat->session_mgr->nr_udp_pkts_evctd_bypass; }
static inline uint64_t get_nr_tcp_seg_received(struct thread_stat *thr_stat) { return thr_stat->session_mgr->nr_tcp_seg_received; }
static inline uint64_t get_nr_tcp_seg_expired(struct thread_stat *thr_stat) { return thr_stat->session_mgr->nr_tcp_seg_expired; }
static inline uint64_t get_nr_tcp_seg_retransmit(struct thread_stat *thr_stat) { return thr_stat->session_mgr->nr_tcp_seg_retransmit; }
static inline uint64_t get_nr_tcp_seg_overlap(struct thread_stat *thr_stat) { return thr_stat->session_mgr->nr_tcp_seg_overlap; }
static inline uint64_t get_nr_tcp_seg_no_space(struct thread_stat *thr_stat) { return thr_stat->session_mgr->nr_tcp_seg_no_space; }
static inline uint64_t get_nr_tcp_seg_inorder(struct thread_stat *thr_stat) { return thr_stat->session_mgr->nr_tcp_seg_inorder; }
static inline uint64_t get_nr_tcp_seg_reorded(struct thread_stat *thr_stat) { return thr_stat->session_mgr->nr_tcp_seg_reorded; }
static inline uint64_t get_nr_tcp_seg_buffered(struct thread_stat *thr_stat) { return thr_stat->session_mgr->nr_tcp_seg_buffered; }
static inline uint64_t get_nr_tcp_seg_released(struct thread_stat *thr_stat) { return thr_stat->session_mgr->nr_tcp_seg_released; }
struct metric_schema
{
const char *name;
get_val_func *get_val;
} schemas[] =
{
// device packet
{"dev_rx_pkts", get_dev_rx_pkts},
{"dev_rx_bytes", get_dev_rx_bytes},
{"dev_tx_pkts", get_dev_tx_pkts},
{"dev_tx_bytes", get_dev_tx_bytes},
// keep-alive packet
{"keep_alive_pkts", get_keep_alive_pkts},
{"keep_alive_bytes", get_keep_alive_bytes},
// raw packet
{"raw_rx_pkts", get_raw_rx_pkts},
{"raw_rx_bytes", get_raw_rx_bytes},
{"raw_tx_pkts", get_raw_tx_pkts},
{"raw_tx_bytes", get_raw_tx_bytes},
// drop packet
{"drop_pkts", get_drop_pkts},
{"drop_bytes", get_drop_bytes},
// inject packet
{"inject_pkts", get_inject_pkts},
{"inject_bytes", get_inject_bytes},
// ctrl packet
{"ctrl_rx_pkts", get_ctrl_rx_pkts},
{"ctrl_rx_bytes", get_ctrl_rx_bytes},
{"ctrl_tx_pkts", get_ctrl_tx_pkts},
{"ctrl_tx_bytes", get_ctrl_tx_bytes},
// ipv4 reassembly
{"ip4_flow_find", get_ip4_flow_find},
{"ip4_flow_add", get_ip4_flow_add},
{"ip4_flow_del", get_ip4_flow_del},
{"ip4_flow_timeout", get_ip4_flow_timeout},
{"ip4_flow_fail_no_space", get_ip4_flow_fail_no_space},
{"ip4_flow_fail_overlap", get_ip4_flow_fail_overlap},
{"ip4_flow_fail_many_frag", get_ip4_flow_fail_many_frag},
{"ip4_flow_fail_invalid_length", get_ip4_flow_fail_invalid_length},
{"ip4_flow_bypass_dup_fist_frag", get_ip4_flow_bypass_dup_fist_frag},
{"ip4_flow_bypass_dup_last_frag", get_ip4_flow_bypass_dup_last_frag},
// ipv6 reassembly
{"ip6_flow_find", get_ip6_flow_find},
{"ip6_flow_add", get_ip6_flow_add},
{"ip6_flow_del", get_ip6_flow_del},
{"ip6_flow_timeout", get_ip6_flow_timeout},
{"ip6_flow_fail_no_space", get_ip6_flow_fail_no_space},
{"ip6_flow_fail_overlap", get_ip6_flow_fail_overlap},
{"ip6_flow_fail_many_frag", get_ip6_flow_fail_many_frag},
{"ip6_flow_fail_invalid_length", get_ip6_flow_fail_invalid_length},
{"ip6_flow_bypass_dup_fist_frag", get_ip6_flow_bypass_dup_fist_frag},
{"ip6_flow_bypass_dup_last_frag", get_ip6_flow_bypass_dup_last_frag},
// TCP session
{"total_nr_tcp_sess_used", get_total_nr_tcp_sess_used},
{"curr_nr_tcp_sess_used", get_curr_nr_tcp_sess_used},
{"curr_nr_tcp_sess_opening", get_curr_nr_tcp_sess_opening},
{"curr_nr_tcp_sess_active", get_curr_nr_tcp_sess_active},
{"curr_nr_tcp_sess_closing", get_curr_nr_tcp_sess_closing},
{"curr_nr_tcp_sess_discard", get_curr_nr_tcp_sess_discard},
{"curr_nr_tcp_sess_closed", get_curr_nr_tcp_sess_closed},
// UDP session
{"total_nr_udp_sess_used", get_total_nr_udp_sess_used},
{"curr_nr_udp_sess_used", get_curr_nr_udp_sess_used},
{"curr_nr_udp_sess_opening", get_curr_nr_udp_sess_opening},
{"curr_nr_udp_sess_active", get_curr_nr_udp_sess_active},
{"curr_nr_udp_sess_closing", get_curr_nr_udp_sess_closing},
{"curr_nr_udp_sess_discard", get_curr_nr_udp_sess_discard},
{"curr_nr_udp_sess_closed", get_curr_nr_udp_sess_closed},
// Evicted session
{"nr_tcp_sess_evicted", get_nr_tcp_sess_evicted},
{"nr_udp_sess_evicted", get_nr_udp_sess_evicted},
// Packet
{"nr_udp_pkts_nospace_bypass", get_nr_udp_pkts_nospace_bypass},
{"nr_tcp_pkts_nospace_bypass", get_nr_tcp_pkts_nospace_bypass},
{"nr_tcp_pkts_nosess_bypass", get_nr_tcp_pkts_nosess_bypass},
{"nr_tcp_pkts_duped_bypass", get_nr_tcp_pkts_duped_bypass},
{"nr_udp_pkts_duped_bypass", get_nr_udp_pkts_duped_bypass},
{"nr_udp_pkts_evctd_bypass", get_nr_udp_pkts_evctd_bypass},
// TCP segments
{"nr_tcp_seg_received", get_nr_tcp_seg_received},
{"nr_tcp_seg_expired", get_nr_tcp_seg_expired},
{"nr_tcp_seg_retransmit", get_nr_tcp_seg_retransmit},
{"nr_tcp_seg_overlap", get_nr_tcp_seg_overlap},
{"nr_tcp_seg_no_space", get_nr_tcp_seg_no_space},
{"nr_tcp_seg_inorder", get_nr_tcp_seg_inorder},
{"nr_tcp_seg_reorded", get_nr_tcp_seg_reorded},
{"nr_tcp_seg_buffered", get_nr_tcp_seg_buffered},
{"nr_tcp_seg_released", get_nr_tcp_seg_released},
};
struct stellar_stat
{
uint16_t nr_thread;
char output_file[2048];
struct fieldstat_easy *fs;
int flag[MAX_THREAD_NUM]; // IS_FREE or IS_BUSY
struct thread_stat thr_stat[MAX_THREAD_NUM];
struct metric_map
{
uint64_t key;
uint64_t val;
} map[sizeof(schemas) / sizeof(struct metric_schema)];
};
// python3 -m pip install prettytable
// python3 -m pip install jinja2
// /opt/MESA/bin/fieldstat_exporter.py local -j log/stellar_fs4.json -e -l --clear-screen
struct stellar_stat *stellar_stat_new(uint16_t nr_thread)
{
char cwd[1024] = {0};
struct stellar_stat *stat = (struct stellar_stat *)calloc(1, sizeof(struct stellar_stat));
if (stat == NULL)
{
return NULL;
}
if (getcwd(cwd, sizeof(cwd)) == NULL)
{
STAT_LOG_ERROR("failed to get current working directory: %s", strerror(errno));
goto error_out;
}
snprintf(stat->output_file, sizeof(stat->output_file), "%s/log/stellar_fs4.json", cwd);
stat->fs = fieldstat_easy_new(1, "stellar", NULL, 0);
if (stat->fs == NULL)
{
STAT_LOG_ERROR("failed to create fieldstat_easy");
goto error_out;
}
stat->nr_thread = nr_thread;
for (int i = 0; i < MAX_THREAD_NUM; i++)
{
stat->flag[i] = IS_FREE;
}
for (size_t i = 0; i < sizeof(schemas) / sizeof(struct metric_schema); i++)
{
stat->map[i].key = fieldstat_easy_register_counter(stat->fs, schemas[i].name);
stat->map[i].val = 0;
}
return stat;
error_out:
stellar_stat_free(stat);
return NULL;
}
void stellar_stat_free(struct stellar_stat *stat)
{
if (stat)
{
if (stat->fs)
{
fieldstat_easy_free(stat->fs);
stat->fs = NULL;
}
free(stat);
stat = NULL;
}
}
void stellar_stat_output(struct stellar_stat *stat)
{
for (uint16_t i = 0; i < stat->nr_thread; i++)
{
if (ATOMIC_READ(&(stat->flag[i])) == IS_BUSY)
{
struct thread_stat *thr_stat = &stat->thr_stat[i];
for (size_t j = 0; j < sizeof(schemas) / sizeof(struct metric_schema); j++)
{
stat->map[j].val += schemas[j].get_val(thr_stat);
}
memset(thr_stat, 0, sizeof(struct thread_stat));
ATOMIC_SET(&(stat->flag[i]), IS_FREE);
}
}
for (size_t j = 0; j < sizeof(schemas) / sizeof(struct metric_schema); j++)
{
fieldstat_easy_counter_set(stat->fs, 0, stat->map[j].key, NULL, 0, stat->map[j].val);
}
char *buff;
size_t len;
fieldstat_easy_output(stat->fs, &buff, &len);
if (buff)
{
FILE *fp = fopen(stat->output_file, "w+");
if (fp == NULL)
{
STAT_LOG_ERROR("failed to open file: %s, %s", stat->output_file, strerror(errno));
}
else
{
fwrite(buff, len, 1, fp);
fflush(fp);
fclose(fp);
}
free(buff);
}
for (size_t j = 0; j < sizeof(schemas) / sizeof(struct metric_schema); j++)
{
stat->map[j].val = 0;
}
}
void stellar_stat_merge(struct stellar_stat *stat, const struct thread_stat *thr_stat, uint16_t thr_idx)
{
if (ATOMIC_READ(&(stat->flag[thr_idx])) == IS_FREE)
{
memcpy(&stat->thr_stat[thr_idx], thr_stat, sizeof(struct thread_stat));
ATOMIC_SET(&(stat->flag[thr_idx]), IS_BUSY);
}
}

View File

@@ -11,9 +11,9 @@ extern "C"
struct thread_stat struct thread_stat
{ {
struct io_stat *io; struct packet_io_stat *packet_io;
struct ip_reassembly_stat *ip_rea; struct ip_reassembly_stat *ip_reassembly;
struct session_manager_stat *sess_mgr; struct session_manager_stat *session_mgr;
}; };
struct stellar_stat; struct stellar_stat;