diff options
| author | luwenpeng <[email protected]> | 2024-04-16 14:12:41 +0800 |
|---|---|---|
| committer | luwenpeng <[email protected]> | 2024-04-16 14:13:42 +0800 |
| commit | d878849c3a86906d379c4cfc7f283b4011dc31ed (patch) | |
| tree | 6077eb465f2365140d567821141c865292c16914 | |
| parent | 17f5d338de2aa48255c1c2b2996b1cacb0d10a71 (diff) | |
Stellar output statistics
| -rw-r--r-- | CMakeLists.txt | 5 | ||||
| -rw-r--r-- | ci/travis.sh | 1 | ||||
| -rw-r--r-- | conf/log.toml | 2 | ||||
| -rw-r--r-- | script/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | script/stellar_stat.sh | 3 | ||||
| -rw-r--r-- | src/log/log.cpp | 5 | ||||
| -rw-r--r-- | src/packet_io/dumpfile_io.cpp | 4 | ||||
| -rw-r--r-- | src/packet_io/dumpfile_io.h | 2 | ||||
| -rw-r--r-- | src/packet_io/marsio_io.cpp | 4 | ||||
| -rw-r--r-- | src/packet_io/marsio_io.h | 2 | ||||
| -rw-r--r-- | src/packet_io/packet_io.cpp | 6 | ||||
| -rw-r--r-- | src/packet_io/packet_io.h | 4 | ||||
| -rw-r--r-- | src/plugin/plugin_manager.cpp | 3 | ||||
| -rw-r--r-- | src/stellar/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | src/stellar/stat.cpp | 375 | ||||
| -rw-r--r-- | src/stellar/stat.h | 33 | ||||
| -rw-r--r-- | src/stellar/stellar.cpp | 54 | ||||
| -rw-r--r-- | vendor/CMakeLists.txt | 7 |
18 files changed, 485 insertions, 30 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ab4eaa..160c1bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,4 +58,7 @@ enable_testing() add_subdirectory(conf) add_subdirectory(vendor) add_subdirectory(deps) -add_subdirectory(src)
\ No newline at end of file +add_subdirectory(src) +add_subdirectory(script) + +install(DIRECTORY DESTINATION log)
\ No newline at end of file diff --git a/ci/travis.sh b/ci/travis.sh index 50455b4..ae9e8cc 100644 --- a/ci/travis.sh +++ b/ci/travis.sh @@ -36,6 +36,7 @@ env | sort yum install -y mrzcpd-corei7 yum install -y numactl-libs # required by mrzcpd yum install -y libibverbs # required by mrzcpd +yum install -y libfieldstat4-devel if [ $ASAN_OPTION ] && [ -f "/opt/rh/devtoolset-7/enable" ]; then source /opt/rh/devtoolset-7/enable diff --git a/conf/log.toml b/conf/log.toml index c49b2ce..0246ed1 100644 --- a/conf/log.toml +++ b/conf/log.toml @@ -1,4 +1,4 @@ [log] output = file # stderr, file -file = stellar.log +file = "log/stellar.log" level = DEBUG # TRACE, DEBUG, INFO, WARN, ERROR, FATAL diff --git a/script/CMakeLists.txt b/script/CMakeLists.txt new file mode 100644 index 0000000..16f3cfd --- /dev/null +++ b/script/CMakeLists.txt @@ -0,0 +1 @@ +install(FILES stellar_stat.sh DESTINATION ./ COMPONENT Program)
\ No newline at end of file diff --git a/script/stellar_stat.sh b/script/stellar_stat.sh new file mode 100644 index 0000000..e4c5134 --- /dev/null +++ b/script/stellar_stat.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +/opt/MESA/bin/fieldstat_exporter.py local -j /opt/tsg/stellar/log/stellar.fs4 -l --clear-screen -e diff --git a/src/log/log.cpp b/src/log/log.cpp index 69d4331..f66fd9d 100644 --- a/src/log/log.cpp +++ b/src/log/log.cpp @@ -153,7 +153,8 @@ static int parse_config(struct log_config *config, const char *cfg_file) fprintf(stderr, "config file %s missing log.file\n", cfg_file); goto error_out; } - strncpy(config->log_file, ptr, sizeof(config->log_file) - 1); + // skip "" + strncpy(config->log_file, ptr + 1, strlen(ptr) - 2); } // level @@ -200,7 +201,7 @@ static int log_reopen() new_fd = open(buff, O_WRONLY | O_APPEND | O_CREAT, 0644); if (new_fd == -1) { - fprintf(stderr, "open() \"%s\" failed, %s", buff, strerror(errno)); + fprintf(stderr, "open() \"%s\" failed, %s\n", buff, strerror(errno)); return -1; } diff --git a/src/packet_io/dumpfile_io.cpp b/src/packet_io/dumpfile_io.cpp index 3d3f50e..a72a9bb 100644 --- a/src/packet_io/dumpfile_io.cpp +++ b/src/packet_io/dumpfile_io.cpp @@ -20,7 +20,7 @@ struct dumpfile_io pcap_t *pcap; struct lock_free_queue *queue[MAX_THREAD_NUM]; - struct packet_stat stat; + struct io_stat stat; uint64_t io_thread_need_exit; uint64_t io_thread_is_runing; }; @@ -193,7 +193,7 @@ void dumpfile_io_free(struct dumpfile_io *handle) } } -struct packet_stat *dumpfile_io_stat(struct dumpfile_io *handle) +struct io_stat *dumpfile_io_get_stat(struct dumpfile_io *handle) { return &handle->stat; } diff --git a/src/packet_io/dumpfile_io.h b/src/packet_io/dumpfile_io.h index 2f73790..e672a42 100644 --- a/src/packet_io/dumpfile_io.h +++ b/src/packet_io/dumpfile_io.h @@ -11,7 +11,7 @@ extern "C" struct dumpfile_io; struct dumpfile_io *dumpfile_io_new(const char *directory, uint8_t nr_threads); void dumpfile_io_free(struct dumpfile_io *handle); -struct packet_stat *dumpfile_io_stat(struct dumpfile_io *handle); +struct io_stat *dumpfile_io_get_stat(struct dumpfile_io *handle); 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); diff --git a/src/packet_io/marsio_io.cpp b/src/packet_io/marsio_io.cpp index 9ce0a5a..ff3e56c 100644 --- a/src/packet_io/marsio_io.cpp +++ b/src/packet_io/marsio_io.cpp @@ -15,7 +15,7 @@ struct marsio_io struct mr_vdev *mr_dev; struct mr_sendpath *mr_path; - struct packet_stat stat; + struct io_stat stat; }; /****************************************************************************** @@ -118,7 +118,7 @@ void marsio_io_free(struct marsio_io *handle) } } -struct packet_stat *marsio_io_stat(struct marsio_io *handle) +struct io_stat *marsio_io_get_stat(struct marsio_io *handle) { return &handle->stat; } diff --git a/src/packet_io/marsio_io.h b/src/packet_io/marsio_io.h index 1c377e1..1de58c8 100644 --- a/src/packet_io/marsio_io.h +++ b/src/packet_io/marsio_io.h @@ -11,7 +11,7 @@ extern "C" struct marsio_io; struct marsio_io *marsio_io_new(const char *app_symbol, const char *dev_symbol, uint16_t *cpu_mask, uint8_t nr_threads); void marsio_io_free(struct marsio_io *handle); -struct packet_stat *marsio_io_stat(struct marsio_io *handle); +struct io_stat *marsio_io_get_stat(struct marsio_io *handle); int marsio_io_init(struct marsio_io *handle, uint16_t thr_idx); int marsio_io_ingress(struct marsio_io *handle, uint16_t thr_idx, struct packet *pkts, int nr_pkts); diff --git a/src/packet_io/packet_io.cpp b/src/packet_io/packet_io.cpp index 162961f..c58d05c 100644 --- a/src/packet_io/packet_io.cpp +++ b/src/packet_io/packet_io.cpp @@ -58,15 +58,15 @@ void packet_io_free(struct packet_io *packet_io) } } -struct packet_stat *packet_io_stat(struct packet_io *packet_io) +struct io_stat *packet_io_get_stat(struct packet_io *packet_io) { if (packet_io->mode == PACKET_IO_MARSIO) { - return marsio_io_stat(packet_io->marsio); + return marsio_io_get_stat(packet_io->marsio); } else { - return dumpfile_io_stat(packet_io->dumpfile); + return dumpfile_io_get_stat(packet_io->dumpfile); } } diff --git a/src/packet_io/packet_io.h b/src/packet_io/packet_io.h index a98d6fe..da312e1 100644 --- a/src/packet_io/packet_io.h +++ b/src/packet_io/packet_io.h @@ -14,7 +14,7 @@ extern "C" #define PACKET_IO_LOG_ERROR(format, ...) LOG_ERROR("packet_io", format, ##__VA_ARGS__) #define PACKET_IO_LOG_DEBUG(format, ...) LOG_DEBUG("packet_io", format, ##__VA_ARGS__) -struct packet_stat +struct io_stat { // device packet uint64_t dev_rx_pkts; @@ -66,7 +66,7 @@ struct packet_io_options struct packet_io; struct packet_io *packet_io_new(struct packet_io_options *opts); void packet_io_free(struct packet_io *packet_io); -struct packet_stat *packet_io_stat(struct packet_io *packet_io); +struct io_stat *packet_io_get_stat(struct packet_io *packet_io); int packet_io_init(struct packet_io *packet_io, uint16_t thr_idx); int packet_io_ingress(struct packet_io *packet_io, uint16_t thr_idx, struct packet *pkts, int nr_pkts); diff --git a/src/plugin/plugin_manager.cpp b/src/plugin/plugin_manager.cpp index 43ee127..3ec3105 100644 --- a/src/plugin/plugin_manager.cpp +++ b/src/plugin/plugin_manager.cpp @@ -42,8 +42,7 @@ void plugin_manager_dispatch_session(struct plugin_manager *mgr, struct session struct tcp_segment *seg; enum session_state state = session_get_state(sess); enum session_type type = session_get_type(sess); - PLUGIN_MANAGER_LOG_DEBUG("=> plugin dispatch session: %u %s %s %s", session_get_id(sess), session_get_tuple_str(sess), session_type_to_str(type), session_state_to_str(state)); - + // PLUGIN_MANAGER_LOG_DEBUG("=> plugin dispatch session: %u %s %s %s", session_get_id(sess), session_get_tuple_str(sess), session_type_to_str(type), session_state_to_str(state)); // session_print(sess); if (packet_is_ctrl(pkt)) diff --git a/src/stellar/CMakeLists.txt b/src/stellar/CMakeLists.txt index ac7e19c..a5b9169 100644 --- a/src/stellar/CMakeLists.txt +++ b/src/stellar/CMakeLists.txt @@ -1,4 +1,4 @@ -add_executable(stellar stellar.cpp) -target_link_libraries(stellar timestamp session_manager plugin_manager pthread config packet_io) +add_executable(stellar stellar.cpp stat.cpp) +target_link_libraries(stellar timestamp session_manager plugin_manager pthread config packet_io fieldstat4) install(TARGETS stellar RUNTIME DESTINATION bin COMPONENT Program)
\ No newline at end of file diff --git a/src/stellar/stat.cpp b/src/stellar/stat.cpp new file mode 100644 index 0000000..df77946 --- /dev/null +++ b/src/stellar/stat.cpp @@ -0,0 +1,375 @@ +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> + +#include "stat.h" +#include "fieldstat/fieldstat_easy.h" +#include "fieldstat/fieldstat_exporter.h" + +#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; + + // ctrl packet + int ctrl_rx_pkts; + int ctrl_rx_bytes; + + int ctrl_tx_pkts; + int ctrl_tx_bytes; + + // TCP session + int nr_tcp_sess_used; + int nr_tcp_sess_opening; + int nr_tcp_sess_active; + int nr_tcp_sess_closing; + int nr_tcp_sess_discard; + int nr_tcp_sess_closed; + + // UDP session + int nr_udp_sess_used; + int nr_udp_sess_opening; + int nr_udp_sess_active; + int nr_udp_sess_closing; + int nr_udp_sess_discard; + int 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_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 +{ + // thread stat + uint16_t nr_thread; + int flag[MAX_THREAD_NUM]; // IS_FREE or IS_BUSY + 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 -e -l --clear-screen +struct stellar_stat *stellar_stat_new(uint16_t nr_thread) +{ + struct stellar_stat *stat = (struct stellar_stat *)calloc(1, sizeof(struct stellar_stat)); + if (stat == NULL) + { + return NULL; + } + + 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"); + // 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"); + // TCP session + stat->ids.nr_tcp_sess_used = fieldstat_easy_register_counter(stat->fs, "tcp_sess_used"); + stat->ids.nr_tcp_sess_opening = fieldstat_easy_register_counter(stat->fs, "tcp_sess_opening"); + stat->ids.nr_tcp_sess_active = fieldstat_easy_register_counter(stat->fs, "tcp_sess_active"); + stat->ids.nr_tcp_sess_closing = fieldstat_easy_register_counter(stat->fs, "tcp_sess_closing"); + stat->ids.nr_tcp_sess_discard = fieldstat_easy_register_counter(stat->fs, "tcp_sess_discard"); + stat->ids.nr_tcp_sess_closed = fieldstat_easy_register_counter(stat->fs, "tcp_sess_closed"); + // UDP session + stat->ids.nr_udp_sess_used = fieldstat_easy_register_counter(stat->fs, "udp_sess_used"); + stat->ids.nr_udp_sess_opening = fieldstat_easy_register_counter(stat->fs, "udp_sess_opening"); + stat->ids.nr_udp_sess_active = fieldstat_easy_register_counter(stat->fs, "udp_sess_active"); + stat->ids.nr_udp_sess_closing = fieldstat_easy_register_counter(stat->fs, "udp_sess_closing"); + stat->ids.nr_udp_sess_discard = fieldstat_easy_register_counter(stat->fs, "udp_sess_discard"); + stat->ids.nr_udp_sess_closed = fieldstat_easy_register_counter(stat->fs, "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_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) + { + // 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.nr_tcp_sess_used += stat->thr_sess_stat[i].nr_tcp_sess_used; + stat->sess_stat.nr_tcp_sess_opening += stat->thr_sess_stat[i].nr_tcp_sess_opening; + stat->sess_stat.nr_tcp_sess_active += stat->thr_sess_stat[i].nr_tcp_sess_active; + stat->sess_stat.nr_tcp_sess_closing += stat->thr_sess_stat[i].nr_tcp_sess_closing; + stat->sess_stat.nr_tcp_sess_discard += stat->thr_sess_stat[i].nr_tcp_sess_discard; + stat->sess_stat.nr_tcp_sess_closed += stat->thr_sess_stat[i].nr_tcp_sess_closed; + + stat->sess_stat.nr_udp_sess_used += stat->thr_sess_stat[i].nr_udp_sess_used; + stat->sess_stat.nr_udp_sess_opening += stat->thr_sess_stat[i].nr_udp_sess_opening; + stat->sess_stat.nr_udp_sess_active += stat->thr_sess_stat[i].nr_udp_sess_active; + stat->sess_stat.nr_udp_sess_closing += stat->thr_sess_stat[i].nr_udp_sess_closing; + stat->sess_stat.nr_udp_sess_discard += stat->thr_sess_stat[i].nr_udp_sess_discard; + stat->sess_stat.nr_udp_sess_closed += stat->thr_sess_stat[i].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_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); + // 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); + // TCP session + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_tcp_sess_used, NULL, 0, stat->sess_stat.nr_tcp_sess_used); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_tcp_sess_opening, NULL, 0, stat->sess_stat.nr_tcp_sess_opening); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_tcp_sess_active, NULL, 0, stat->sess_stat.nr_tcp_sess_active); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_tcp_sess_closing, NULL, 0, stat->sess_stat.nr_tcp_sess_closing); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_tcp_sess_discard, NULL, 0, stat->sess_stat.nr_tcp_sess_discard); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_tcp_sess_closed, NULL, 0, stat->sess_stat.nr_tcp_sess_closed); + // UDP session + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_udp_sess_used, NULL, 0, stat->sess_stat.nr_udp_sess_used); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_udp_sess_opening, NULL, 0, stat->sess_stat.nr_udp_sess_opening); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_udp_sess_active, NULL, 0, stat->sess_stat.nr_udp_sess_active); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_udp_sess_closing, NULL, 0, stat->sess_stat.nr_udp_sess_closing); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_udp_sess_discard, NULL, 0, stat->sess_stat.nr_udp_sess_discard); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_udp_sess_closed, NULL, 0, stat->sess_stat.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_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("/opt/tsg/stellar/log/stellar.fs4", "w+"); + if (fp == NULL) + { + STAT_LOG_ERROR("failed to open file: %s, %s", "/opt/tsg/stellar/log/stellar.fs4", 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_peek_io_stat(struct stellar_stat *stat, const struct io_stat *pkt_io) +{ + stat->io_stat.dev_rx_pkts += pkt_io->dev_rx_pkts; + stat->io_stat.dev_rx_bytes += pkt_io->dev_rx_bytes; + + stat->io_stat.dev_tx_pkts += pkt_io->dev_tx_pkts; + stat->io_stat.dev_tx_bytes += pkt_io->dev_tx_bytes; + + stat->io_stat.keep_alive_pkts += pkt_io->keep_alive_pkts; + stat->io_stat.keep_alive_bytes += pkt_io->keep_alive_bytes; + + stat->io_stat.raw_rx_pkts += pkt_io->raw_rx_pkts; + stat->io_stat.raw_rx_bytes += pkt_io->raw_rx_bytes; + + stat->io_stat.raw_tx_pkts += pkt_io->raw_tx_pkts; + stat->io_stat.raw_tx_bytes += pkt_io->raw_tx_bytes; + + stat->io_stat.ctrl_rx_pkts += pkt_io->ctrl_rx_pkts; + stat->io_stat.ctrl_rx_bytes += pkt_io->ctrl_rx_bytes; + + stat->io_stat.ctrl_tx_pkts += pkt_io->ctrl_tx_pkts; + stat->io_stat.ctrl_tx_bytes += pkt_io->ctrl_tx_bytes; +} + +void stellar_peek_thr_stat(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_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); + } +} diff --git a/src/stellar/stat.h b/src/stellar/stat.h new file mode 100644 index 0000000..07695b1 --- /dev/null +++ b/src/stellar/stat.h @@ -0,0 +1,33 @@ +#ifndef _STAT_H +#define _STAT_H + +#ifdef __cpluscplus +extern "C" +{ +#endif + +#include "packet_io.h" +#include "ip_reassembly.h" +#include "session_manager.h" + +#define STAT_LOG_ERROR(format, ...) LOG_ERROR("stat", format, ##__VA_ARGS__) + +struct thread_stat +{ + struct ip_reassembly_stat *ip_rea; + struct session_manager_stat *sess_mgr; +}; + +struct stellar_stat; +struct stellar_stat *stellar_stat_new(uint16_t nr_thread); +void stellar_stat_free(struct stellar_stat *stat); +void stellar_stat_output(struct stellar_stat *stat); + +void stellar_peek_io_stat(struct stellar_stat *stat, const struct io_stat *io_stat); +void stellar_peek_thr_stat(struct stellar_stat *stat, const struct thread_stat *thr_stat, uint16_t thr_idx); + +#ifdef __cpluscplus +} +#endif + +#endif diff --git a/src/stellar/stellar.cpp b/src/stellar/stellar.cpp index bbc0259..273704e 100644 --- a/src/stellar/stellar.cpp +++ b/src/stellar/stellar.cpp @@ -9,6 +9,7 @@ #include <sys/prctl.h> #include "logo.h" +#include "stat.h" #include "stellar.h" #include "config.h" #include "packet_private.h" @@ -23,9 +24,6 @@ #define STELLAR_LOG_ERROR(format, ...) LOG_ERROR("stellar", format, ##__VA_ARGS__) #define STELLAR_LOG_DEBUG(format, ...) LOG_DEBUG("stellar", format, ##__VA_ARGS__) -#define ATOMIC_SET(x, y) __atomic_store_n(x, y, __ATOMIC_RELAXED) -#define ATOMIC_READ(x) __atomic_load_n(x, __ATOMIC_RELAXED) - struct thread_ctx { pthread_t tid; @@ -38,6 +36,7 @@ struct thread_ctx struct stellar_runtime { uint64_t need_exit; + struct stellar_stat *stat; struct packet_io *packet_io; struct plugin_manager *plug_mgr; struct thread_ctx threads[MAX_THREAD_NUM]; @@ -129,23 +128,37 @@ static inline void thread_set_name(const char *thd_symbol, uint16_t thd_idx) prctl(PR_SET_NAME, (unsigned long long)thd_name, NULL, NULL, NULL); } +static inline void stellar_thread_cron(struct thread_ctx *thr_ctx) +{ + thread_local uint64_t last = 0; + if (timestamp_get_msec() - last > 2000) + { + struct thread_stat thr_stat = { + ip_reassembly_get_stat(thr_ctx->ip_mgr), + session_manager_get_stat(thr_ctx->sess_mgr), + }; + stellar_peek_thr_stat(runtime->stat, &thr_stat, thr_ctx->idx); + last = timestamp_get_msec(); + } +} + static void *work_thread(void *arg) { + int nr_recv; + uint64_t now = 0; + uint16_t thr_idx = 0; void *plugin_ctx; struct packet *pkt; struct packet packets[RX_BURST_MAX]; struct session *sess; struct session *evicted_sess; struct session *expired_sess; + struct packet_io *packet_io = runtime->packet_io; + struct plugin_manager *plug_mgr = runtime->plug_mgr; struct thread_ctx *thr_ctx = (struct thread_ctx *)arg; struct ip_reassembly *ip_reass = thr_ctx->ip_mgr; struct session_manager *sess_mgr = thr_ctx->sess_mgr; - struct packet_io *packet_io = runtime->packet_io; - struct plugin_manager *plug_mgr = runtime->plug_mgr; - - int nr_recv; - uint64_t now = 0; - uint16_t thr_idx = thr_ctx->idx; + thr_idx = thr_ctx->idx; if (packet_io_init(packet_io, thr_idx) != 0) { @@ -231,6 +244,8 @@ static void *work_thread(void *arg) } ip_reassembly_expire(ip_reass, now); + stellar_thread_cron(thr_ctx); + // TODO // plugin_manager_cron(); // poll_non_packet_events(); @@ -317,6 +332,8 @@ static void stellar_thread_join(struct stellar_runtime *ctx, uint8_t nr_threads) int main(int argc, char **argv) { uint8_t nr_threads; + uint64_t last_stat = 0; + struct io_stat *io_stat; memset(runtime, 0, sizeof(struct stellar_runtime)); memset(config, 0, sizeof(struct stellar_config)); timestamp_update(); @@ -339,6 +356,7 @@ int main(int argc, char **argv) goto error_out; } stellar_config_print(config); + nr_threads = config->io_opts.nr_threads; if (id_generator_init(config->dev_opts.base, config->dev_opts.offset) != 0) { @@ -346,6 +364,13 @@ int main(int argc, char **argv) goto error_out; } + runtime->stat = stellar_stat_new(nr_threads); + if (runtime->stat == NULL) + { + STELLAR_LOG_ERROR("unable to create stellar stat"); + goto error_out; + } + runtime->plug_mgr = plugin_manager_new(); if (runtime->plug_mgr == NULL) { @@ -353,7 +378,6 @@ int main(int argc, char **argv) goto error_out; } - nr_threads = config->io_opts.nr_threads; runtime->packet_io = packet_io_new(&config->io_opts); if (runtime->packet_io == NULL) { @@ -373,9 +397,18 @@ int main(int argc, char **argv) goto error_out; } + io_stat = packet_io_get_stat(runtime->packet_io); + last_stat = timestamp_get_msec(); while (!ATOMIC_READ(&runtime->need_exit)) { timestamp_update(); + if (timestamp_get_msec() - last_stat > 2000) + { + stellar_peek_io_stat(runtime->stat, io_stat); + stellar_stat_output(runtime->stat); + last_stat = timestamp_get_msec(); + } + usleep(5 * 1000); } @@ -384,6 +417,7 @@ error_out: stellar_thread_clean(runtime, nr_threads); packet_io_free(runtime->packet_io); plugin_manager_free(runtime->plug_mgr); + stellar_stat_free(runtime->stat); STELLAR_LOG_STATE("stellar exit !!!\n"); log_free(); diff --git a/vendor/CMakeLists.txt b/vendor/CMakeLists.txt index c3559e2..e0751a7 100644 --- a/vendor/CMakeLists.txt +++ b/vendor/CMakeLists.txt @@ -30,4 +30,9 @@ set(MRZCPD_INCLUDE_DIR /opt/tsg/mrzcpd/corei7/include) add_library(mrzcpd SHARED IMPORTED GLOBAL) set_property(TARGET mrzcpd PROPERTY IMPORTED_LOCATION ${MRZCPD_LIB_DIR}/libmarsio.so) -set_property(TARGET mrzcpd PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MRZCPD_INCLUDE_DIR})
\ No newline at end of file +set_property(TARGET mrzcpd PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${MRZCPD_INCLUDE_DIR}) + +# FIELDSTAT +add_library(fieldstat4 SHARED IMPORTED GLOBAL) +set_property(TARGET fieldstat4 PROPERTY IMPORTED_LOCATION /opt/MESA/lib/libfieldstat4.so) +set_property(TARGET fieldstat4 PROPERTY INTERFACE_INCLUDE_DIRECTORIES /opt/MESA/include)
\ No newline at end of file |
