summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorluwenpeng <[email protected]>2024-04-16 14:12:41 +0800
committerluwenpeng <[email protected]>2024-04-16 14:13:42 +0800
commitd878849c3a86906d379c4cfc7f283b4011dc31ed (patch)
tree6077eb465f2365140d567821141c865292c16914
parent17f5d338de2aa48255c1c2b2996b1cacb0d10a71 (diff)
Stellar output statistics
-rw-r--r--CMakeLists.txt5
-rw-r--r--ci/travis.sh1
-rw-r--r--conf/log.toml2
-rw-r--r--script/CMakeLists.txt1
-rw-r--r--script/stellar_stat.sh3
-rw-r--r--src/log/log.cpp5
-rw-r--r--src/packet_io/dumpfile_io.cpp4
-rw-r--r--src/packet_io/dumpfile_io.h2
-rw-r--r--src/packet_io/marsio_io.cpp4
-rw-r--r--src/packet_io/marsio_io.h2
-rw-r--r--src/packet_io/packet_io.cpp6
-rw-r--r--src/packet_io/packet_io.h4
-rw-r--r--src/plugin/plugin_manager.cpp3
-rw-r--r--src/stellar/CMakeLists.txt4
-rw-r--r--src/stellar/stat.cpp375
-rw-r--r--src/stellar/stat.h33
-rw-r--r--src/stellar/stellar.cpp54
-rw-r--r--vendor/CMakeLists.txt7
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