diff --git a/src/core/stellar_core.cpp b/src/core/stellar_core.cpp index 9e4da76..c3a9acb 100644 --- a/src/core/stellar_core.cpp +++ b/src/core/stellar_core.cpp @@ -177,6 +177,18 @@ static inline void merge_thread_stat(struct stellar_thread *thread) stellar_stat_merge(runtime->stat, &thr_stat, thread->idx); } +static inline void print_thread_stat(struct stellar_thread *thread) +{ + struct stellar *st = thread->st; + struct stellar_runtime *runtime = &st->runtime; + struct thread_stat thr_stat = { + .packet_io = packet_io_stat(runtime->packet_io, thread->idx), + .ip_reassembly = ip_reassembly_stat(thread->ip_mgr), + .session_mgr = session_manager_stat(thread->sess_mgr), + }; + stellar_stat_print(runtime->stat, &thr_stat, thread->idx); +} + static void *work_thread(void *arg) { int nr_recv; @@ -333,21 +345,21 @@ static void *work_thread(void *arg) plugin_manager_on_polling(plug_mgr); // per free_expired_session_interval MAX free_expired_session_batch sessions are released - if (now_ms - sched_data->last_free_expired_session_timestamp > sched_data->free_expired_session_interval) + if (now_ms - sched_data->last_free_expired_session_timestamp >= sched_data->free_expired_session_interval) { free_expired_sessions(sess_mgr, sched_data->free_expired_session_batch, now_ms); sched_data->last_free_expired_session_timestamp = now_ms; } // per merge_stat_interval merge thread stat - if (now_ms - sched_data->last_merge_thread_stat_timestamp > sched_data->merge_stat_interval) + if (now_ms - sched_data->last_merge_thread_stat_timestamp >= sched_data->merge_stat_interval) { merge_thread_stat(thread); sched_data->last_merge_thread_stat_timestamp = now_ms; } // per free_expired_ip_frag_interval MAX free_expired_ip_frag_batch ip fragments are released - if (now_ms - sched_data->last_free_expired_ip_frag_timestamp > sched_data->free_expired_ip_frag_interval) + if (now_ms - sched_data->last_free_expired_ip_frag_timestamp >= sched_data->free_expired_ip_frag_interval) { ip_reassembly_expire(ip_reass, sched_data->free_expired_ip_frag_batch, now_ms); sched_data->last_free_expired_ip_frag_timestamp = now_ms; @@ -359,6 +371,9 @@ static void *work_thread(void *arg) } } + merge_thread_stat(thread); + print_thread_stat(thread); + ATOMIC_SET(&thread->is_runing, 0); CORE_LOG_FATAL("worker thread %d exit", thr_idx); @@ -601,7 +616,7 @@ void stellar_run(struct stellar *st) runtime->stat_last_output_ts = clock_get_real_time_ms(); while (!ATOMIC_READ(&runtime->need_exit)) { - if (clock_get_real_time_ms() - runtime->stat_last_output_ts > config->sched_opts.output_stat_interval) + if (clock_get_real_time_ms() - runtime->stat_last_output_ts >= config->sched_opts.output_stat_interval) { runtime->stat_last_output_ts = clock_get_real_time_ms(); stellar_stat_output(runtime->stat); @@ -616,6 +631,9 @@ void stellar_run(struct stellar *st) ATOMIC_SET(&runtime->need_exit, 1); } } + + // berfore exit, output last stat + stellar_stat_output(runtime->stat); } void stellar_free(struct stellar *st) diff --git a/src/core/stellar_stat.cpp b/src/core/stellar_stat.cpp index 47808ba..6171ecb 100644 --- a/src/core/stellar_stat.cpp +++ b/src/core/stellar_stat.cpp @@ -11,116 +11,117 @@ #include "fieldstat/fieldstat_exporter.h" #define STAT_LOG_ERROR(format, ...) STELLAR_LOG_ERROR(__thread_local_logger, "stat", format, ##__VA_ARGS__) +#define STAT_LOG_INFO(format, ...) STELLAR_LOG_INFO(__thread_local_logger, "stat", format, ##__VA_ARGS__) #define IS_FREE 0 #define IS_BUSY 0xf -enum METRIC_TYPE +enum stat_type { // device packet - METRIC_TYPE_PKTS_RX, - METRIC_TYPE_BYTES_RX, - METRIC_TYPE_PKTS_TX, - METRIC_TYPE_BYTES_TX, + STAT_TYPE_PKTS_RX, + STAT_TYPE_BYTES_RX, + STAT_TYPE_PKTS_TX, + STAT_TYPE_BYTES_TX, // keep-alive packet - METRIC_TYPE_KEEP_ALIVE_PKTS, - METRIC_TYPE_KEEP_ALIVE_BYTES, + STAT_TYPE_KEEP_ALIVE_PKTS, + STAT_TYPE_KEEP_ALIVE_BYTES, // raw packet - METRIC_TYPE_RAW_PKTS_RX, - METRIC_TYPE_RAW_BYTES_RX, - METRIC_TYPE_RAW_PKTS_TX, - METRIC_TYPE_RAW_BYTES_TX, + STAT_TYPE_RAW_PKTS_RX, + STAT_TYPE_RAW_BYTES_RX, + STAT_TYPE_RAW_PKTS_TX, + STAT_TYPE_RAW_BYTES_TX, // drop packet - METRIC_TYPE_PKTS_DROPPED, - METRIC_TYPE_BYTES_DROPPED, + STAT_TYPE_PKTS_DROPPED, + STAT_TYPE_BYTES_DROPPED, // inject packet - METRIC_TYPE_PKTS_INJECTED, - METRIC_TYPE_BYTES_INJECTED, + STAT_TYPE_PKTS_INJECTED, + STAT_TYPE_BYTES_INJECTED, // ctrl packet - METRIC_TYPE_CTRL_PKTS_RX, - METRIC_TYPE_CTRL_BYTES_RX, - METRIC_TYPE_CTRL_PKTS_TX, - METRIC_TYPE_CTRL_BYTES_TX, + STAT_TYPE_CTRL_PKTS_RX, + STAT_TYPE_CTRL_BYTES_RX, + STAT_TYPE_CTRL_PKTS_TX, + STAT_TYPE_CTRL_BYTES_TX, // ipv4 reassembly - METRIC_TYPE_IP4_DEFRAGS_EXPECTED, - METRIC_TYPE_IP4_DEFRAGS_SUCCEED, - METRIC_TYPE_IP4_DEFRAGS_FAILED_TIMEOUT, - METRIC_TYPE_IP4_DEFRAGS_FAILED_INVALID_LENGTH, - METRIC_TYPE_IP4_DEFRAGS_FAILED_OVERLAP, - METRIC_TYPE_IP4_DEFRAGS_FAILED_TOO_MANY_FRAG, + STAT_TYPE_IP4_DEFRAGS_EXPECTED, + STAT_TYPE_IP4_DEFRAGS_SUCCEED, + STAT_TYPE_IP4_DEFRAGS_FAILED_TIMEOUT, + STAT_TYPE_IP4_DEFRAGS_FAILED_INVALID_LENGTH, + STAT_TYPE_IP4_DEFRAGS_FAILED_OVERLAP, + STAT_TYPE_IP4_DEFRAGS_FAILED_TOO_MANY_FRAG, - METRIC_TYPE_IP4_FRAGS, - METRIC_TYPE_IP4_FRAGS_FREED, - METRIC_TYPE_IP4_FRAGS_BUFFERED, - METRIC_TYPE_IP4_FRAGS_BYPASS_NO_BUFFER, - METRIC_TYPE_IP4_FRAGS_BYPASS_DUP_FIST_FRAG, - METRIC_TYPE_IP4_FRAGS_BYPASS_DUP_LAST_FRAG, + STAT_TYPE_IP4_FRAGS, + STAT_TYPE_IP4_FRAGS_FREED, + STAT_TYPE_IP4_FRAGS_BUFFERED, + STAT_TYPE_IP4_FRAGS_BYPASS_NO_BUFFER, + STAT_TYPE_IP4_FRAGS_BYPASS_DUP_FIST_FRAG, + STAT_TYPE_IP4_FRAGS_BYPASS_DUP_LAST_FRAG, // ipv6 reassembly - METRIC_TYPE_IP6_DEFRAGS_EXPECTED, - METRIC_TYPE_IP6_DEFRAGS_SUCCEED, - METRIC_TYPE_IP6_DEFRAGS_FAILED_TIMEOUT, - METRIC_TYPE_IP6_DEFRAGS_FAILED_INVALID_LENGTH, - METRIC_TYPE_IP6_DEFRAGS_FAILED_OVERLAP, - METRIC_TYPE_IP6_DEFRAGS_FAILED_TOO_MANY_FRAG, + STAT_TYPE_IP6_DEFRAGS_EXPECTED, + STAT_TYPE_IP6_DEFRAGS_SUCCEED, + STAT_TYPE_IP6_DEFRAGS_FAILED_TIMEOUT, + STAT_TYPE_IP6_DEFRAGS_FAILED_INVALID_LENGTH, + STAT_TYPE_IP6_DEFRAGS_FAILED_OVERLAP, + STAT_TYPE_IP6_DEFRAGS_FAILED_TOO_MANY_FRAG, - METRIC_TYPE_IP6_FRAGS, - METRIC_TYPE_IP6_FRAGS_FREED, - METRIC_TYPE_IP6_FRAGS_BUFFERED, - METRIC_TYPE_IP6_FRAGS_BYPASS_NO_BUFFER, - METRIC_TYPE_IP6_FRAGS_BYPASS_DUP_FIST_FRAG, - METRIC_TYPE_IP6_FRAGS_BYPASS_DUP_LAST_FRAG, + STAT_TYPE_IP6_FRAGS, + STAT_TYPE_IP6_FRAGS_FREED, + STAT_TYPE_IP6_FRAGS_BUFFERED, + STAT_TYPE_IP6_FRAGS_BYPASS_NO_BUFFER, + STAT_TYPE_IP6_FRAGS_BYPASS_DUP_FIST_FRAG, + STAT_TYPE_IP6_FRAGS_BYPASS_DUP_LAST_FRAG, // TCP session - METRIC_TYPE_HISTORY_TCP_SESSIONS, - METRIC_TYPE_TCP_SESS_USED, - METRIC_TYPE_TCP_SESS_OPENING, - METRIC_TYPE_TCP_SESS_ACTIVE, - METRIC_TYPE_TCP_SESS_CLOSING, - METRIC_TYPE_TCP_SESS_DISCARD, - METRIC_TYPE_TCP_SESS_CLOSED, + STAT_TYPE_HISTORY_TCP_SESSIONS, + STAT_TYPE_TCP_SESS_USED, + STAT_TYPE_TCP_SESS_OPENING, + STAT_TYPE_TCP_SESS_ACTIVE, + STAT_TYPE_TCP_SESS_CLOSING, + STAT_TYPE_TCP_SESS_DISCARD, + STAT_TYPE_TCP_SESS_CLOSED, // UDP session - METRIC_TYPE_HISTORY_UDP_SESSIONS, - METRIC_TYPE_UDP_SESS_USED, - METRIC_TYPE_UDP_SESS_OPENING, - METRIC_TYPE_UDP_SESS_ACTIVE, - METRIC_TYPE_UDP_SESS_CLOSING, - METRIC_TYPE_UDP_SESS_DISCARD, - METRIC_TYPE_UDP_SESS_CLOSED, + STAT_TYPE_HISTORY_UDP_SESSIONS, + STAT_TYPE_UDP_SESS_USED, + STAT_TYPE_UDP_SESS_OPENING, + STAT_TYPE_UDP_SESS_ACTIVE, + STAT_TYPE_UDP_SESS_CLOSING, + STAT_TYPE_UDP_SESS_DISCARD, + STAT_TYPE_UDP_SESS_CLOSED, // Evicted session - METRIC_TYPE_TCP_SESS_EVICTED, - METRIC_TYPE_UDP_SESS_EVICTED, + STAT_TYPE_TCP_SESS_EVICTED, + STAT_TYPE_UDP_SESS_EVICTED, // Packet - METRIC_TYPE_UDP_PKTS_BYPASS_TABLE_FULL, - METRIC_TYPE_TCP_PKTS_BYPASS_TABLE_FULL, - METRIC_TYPE_TCP_PKTS_BYPASS_SESSION_NOT_FOUND, - METRIC_TYPE_TCP_PKTS_BYPASS_DUPLICATED, - METRIC_TYPE_UDP_PKTS_BYPASS_DUPLICATED, - METRIC_TYPE_UDP_PKTS_BYPASS_SESSION_EVICTED, + STAT_TYPE_UDP_PKTS_BYPASS_TABLE_FULL, + STAT_TYPE_TCP_PKTS_BYPASS_TABLE_FULL, + STAT_TYPE_TCP_PKTS_BYPASS_SESSION_NOT_FOUND, + STAT_TYPE_TCP_PKTS_BYPASS_DUPLICATED, + STAT_TYPE_UDP_PKTS_BYPASS_DUPLICATED, + STAT_TYPE_UDP_PKTS_BYPASS_SESSION_EVICTED, // TCP segments - METRIC_TYPE_TCP_SEGS_INPUT, - METRIC_TYPE_TCP_SEGS_CONSUMED, - METRIC_TYPE_TCP_SEGS_TIMEOUT, - METRIC_TYPE_TCP_SEGS_RETRANSMITED, - METRIC_TYPE_TCP_SEGS_OVERLAPPED, - METRIC_TYPE_TCP_SEGS_OMITTED_TOO_MANY, - METRIC_TYPE_TCP_SEGS_INORDER, - METRIC_TYPE_TCP_SEGS_REORDERED, - METRIC_TYPE_TCP_SEGS_BUFFERED, - METRIC_TYPE_TCP_SEGS_FREED, + STAT_TYPE_TCP_SEGS_INPUT, + STAT_TYPE_TCP_SEGS_CONSUMED, + STAT_TYPE_TCP_SEGS_TIMEOUT, + STAT_TYPE_TCP_SEGS_RETRANSMITED, + STAT_TYPE_TCP_SEGS_OVERLAPPED, + STAT_TYPE_TCP_SEGS_OMITTED_TOO_MANY, + STAT_TYPE_TCP_SEGS_INORDER, + STAT_TYPE_TCP_SEGS_REORDERED, + STAT_TYPE_TCP_SEGS_BUFFERED, + STAT_TYPE_TCP_SEGS_FREED, // end - METRIC_TYPE_MAX, + STAT_TYPE_MAX, }; const char *name[] = { @@ -243,10 +244,194 @@ struct stellar_stat int flag[MAX_THREAD_NUM]; // IS_FREE or IS_BUSY struct thread_stat thr_stat[MAX_THREAD_NUM]; - uint64_t metric_key[METRIC_TYPE_MAX]; - uint64_t metric_val[METRIC_TYPE_MAX]; + uint64_t stat_idx[STAT_TYPE_MAX]; + uint64_t stat_val[STAT_TYPE_MAX]; }; +uint64_t get_stat_value_by_idx(const struct thread_stat *thr_stat, size_t idx) +{ + switch (idx) + { + // device packet + case STAT_TYPE_PKTS_RX: + return thr_stat->packet_io->pkts_rx; + case STAT_TYPE_BYTES_RX: + return thr_stat->packet_io->bytes_rx; + case STAT_TYPE_PKTS_TX: + return thr_stat->packet_io->pkts_tx; + case STAT_TYPE_BYTES_TX: + return thr_stat->packet_io->bytes_tx; + + // keep-alive packet + case STAT_TYPE_KEEP_ALIVE_PKTS: + return thr_stat->packet_io->keep_alive_pkts; + case STAT_TYPE_KEEP_ALIVE_BYTES: + return thr_stat->packet_io->keep_alive_bytes; + + // raw packet + case STAT_TYPE_RAW_PKTS_RX: + return thr_stat->packet_io->raw_pkts_rx; + case STAT_TYPE_RAW_BYTES_RX: + return thr_stat->packet_io->raw_bytes_rx; + case STAT_TYPE_RAW_PKTS_TX: + return thr_stat->packet_io->raw_pkts_tx; + case STAT_TYPE_RAW_BYTES_TX: + return thr_stat->packet_io->raw_bytes_tx; + + // drop packet + case STAT_TYPE_PKTS_DROPPED: + return thr_stat->packet_io->pkts_dropped; + case STAT_TYPE_BYTES_DROPPED: + return thr_stat->packet_io->bytes_dropped; + + // inject packet + case STAT_TYPE_PKTS_INJECTED: + return thr_stat->packet_io->pkts_injected; + case STAT_TYPE_BYTES_INJECTED: + return thr_stat->packet_io->bytes_injected; + + // ctrl packet + case STAT_TYPE_CTRL_PKTS_RX: + return thr_stat->packet_io->ctrl_pkts_rx; + case STAT_TYPE_CTRL_BYTES_RX: + return thr_stat->packet_io->ctrl_bytes_rx; + case STAT_TYPE_CTRL_PKTS_TX: + return thr_stat->packet_io->ctrl_pkts_tx; + case STAT_TYPE_CTRL_BYTES_TX: + return thr_stat->packet_io->ctrl_bytes_tx; + + // ipv4 reassembly + case STAT_TYPE_IP4_DEFRAGS_EXPECTED: + return thr_stat->ip_reassembly->ip4_defrags_expected; + case STAT_TYPE_IP4_DEFRAGS_SUCCEED: + return thr_stat->ip_reassembly->ip4_defrags_succeed; + case STAT_TYPE_IP4_DEFRAGS_FAILED_TIMEOUT: + return thr_stat->ip_reassembly->ip4_defrags_failed_timeout; + case STAT_TYPE_IP4_DEFRAGS_FAILED_INVALID_LENGTH: + return thr_stat->ip_reassembly->ip4_defrags_failed_invalid_length; + case STAT_TYPE_IP4_DEFRAGS_FAILED_OVERLAP: + return thr_stat->ip_reassembly->ip4_defrags_failed_overlap; + case STAT_TYPE_IP4_DEFRAGS_FAILED_TOO_MANY_FRAG: + return thr_stat->ip_reassembly->ip4_defrags_failed_too_many_frag; + case STAT_TYPE_IP4_FRAGS: + return thr_stat->ip_reassembly->ip4_frags; + case STAT_TYPE_IP4_FRAGS_FREED: + return thr_stat->ip_reassembly->ip4_frags_freed; + case STAT_TYPE_IP4_FRAGS_BUFFERED: + return thr_stat->ip_reassembly->ip4_frags_buffered; + case STAT_TYPE_IP4_FRAGS_BYPASS_NO_BUFFER: + return thr_stat->ip_reassembly->ip4_frags_bypass_no_buffer; + case STAT_TYPE_IP4_FRAGS_BYPASS_DUP_FIST_FRAG: + return thr_stat->ip_reassembly->ip4_frags_bypass_dup_fist_frag; + case STAT_TYPE_IP4_FRAGS_BYPASS_DUP_LAST_FRAG: + return thr_stat->ip_reassembly->ip4_frags_bypass_dup_last_frag; + + // ipv6 reassembly + case STAT_TYPE_IP6_DEFRAGS_EXPECTED: + return thr_stat->ip_reassembly->ip6_defrags_expected; + case STAT_TYPE_IP6_DEFRAGS_SUCCEED: + return thr_stat->ip_reassembly->ip6_defrags_succeed; + case STAT_TYPE_IP6_DEFRAGS_FAILED_TIMEOUT: + return thr_stat->ip_reassembly->ip6_defrags_failed_timeout; + case STAT_TYPE_IP6_DEFRAGS_FAILED_INVALID_LENGTH: + return thr_stat->ip_reassembly->ip6_defrags_failed_invalid_length; + case STAT_TYPE_IP6_DEFRAGS_FAILED_OVERLAP: + return thr_stat->ip_reassembly->ip6_defrags_failed_overlap; + case STAT_TYPE_IP6_DEFRAGS_FAILED_TOO_MANY_FRAG: + return thr_stat->ip_reassembly->ip6_defrags_failed_too_many_frag; + case STAT_TYPE_IP6_FRAGS: + return thr_stat->ip_reassembly->ip6_frags; + case STAT_TYPE_IP6_FRAGS_FREED: + return thr_stat->ip_reassembly->ip6_frags_freed; + case STAT_TYPE_IP6_FRAGS_BUFFERED: + return thr_stat->ip_reassembly->ip6_frags_buffered; + case STAT_TYPE_IP6_FRAGS_BYPASS_NO_BUFFER: + return thr_stat->ip_reassembly->ip6_frags_bypass_no_buffer; + case STAT_TYPE_IP6_FRAGS_BYPASS_DUP_FIST_FRAG: + return thr_stat->ip_reassembly->ip6_frags_bypass_dup_fist_frag; + case STAT_TYPE_IP6_FRAGS_BYPASS_DUP_LAST_FRAG: + return thr_stat->ip_reassembly->ip6_frags_bypass_dup_last_frag; + + // TCP session + case STAT_TYPE_HISTORY_TCP_SESSIONS: + return thr_stat->session_mgr->history_tcp_sessions; + case STAT_TYPE_TCP_SESS_USED: + return thr_stat->session_mgr->tcp_sess_used; + case STAT_TYPE_TCP_SESS_OPENING: + return thr_stat->session_mgr->tcp_sess_opening; + case STAT_TYPE_TCP_SESS_ACTIVE: + return thr_stat->session_mgr->tcp_sess_active; + case STAT_TYPE_TCP_SESS_CLOSING: + return thr_stat->session_mgr->tcp_sess_closing; + case STAT_TYPE_TCP_SESS_DISCARD: + return thr_stat->session_mgr->tcp_sess_discard; + case STAT_TYPE_TCP_SESS_CLOSED: + return thr_stat->session_mgr->tcp_sess_closed; + + // UDP session + case STAT_TYPE_HISTORY_UDP_SESSIONS: + return thr_stat->session_mgr->history_udp_sessions; + case STAT_TYPE_UDP_SESS_USED: + return thr_stat->session_mgr->udp_sess_used; + case STAT_TYPE_UDP_SESS_OPENING: + return thr_stat->session_mgr->udp_sess_opening; + case STAT_TYPE_UDP_SESS_ACTIVE: + return thr_stat->session_mgr->udp_sess_active; + case STAT_TYPE_UDP_SESS_CLOSING: + return thr_stat->session_mgr->udp_sess_closing; + case STAT_TYPE_UDP_SESS_DISCARD: + return thr_stat->session_mgr->udp_sess_discard; + case STAT_TYPE_UDP_SESS_CLOSED: + return thr_stat->session_mgr->udp_sess_closed; + + // Evicted session + case STAT_TYPE_TCP_SESS_EVICTED: + return thr_stat->session_mgr->tcp_sess_evicted; + case STAT_TYPE_UDP_SESS_EVICTED: + return thr_stat->session_mgr->udp_sess_evicted; + + // Packet + case STAT_TYPE_UDP_PKTS_BYPASS_TABLE_FULL: + return thr_stat->session_mgr->udp_pkts_bypass_table_full; + case STAT_TYPE_TCP_PKTS_BYPASS_TABLE_FULL: + return thr_stat->session_mgr->tcp_pkts_bypass_table_full; + case STAT_TYPE_TCP_PKTS_BYPASS_SESSION_NOT_FOUND: + return thr_stat->session_mgr->tcp_pkts_bypass_session_not_found; + case STAT_TYPE_TCP_PKTS_BYPASS_DUPLICATED: + return thr_stat->session_mgr->tcp_pkts_bypass_duplicated; + case STAT_TYPE_UDP_PKTS_BYPASS_DUPLICATED: + return thr_stat->session_mgr->udp_pkts_bypass_duplicated; + case STAT_TYPE_UDP_PKTS_BYPASS_SESSION_EVICTED: + return thr_stat->session_mgr->udp_pkts_bypass_session_evicted; + + // TCP segments + case STAT_TYPE_TCP_SEGS_INPUT: + return thr_stat->session_mgr->tcp_segs_input; + case STAT_TYPE_TCP_SEGS_CONSUMED: + return thr_stat->session_mgr->tcp_segs_consumed; + case STAT_TYPE_TCP_SEGS_TIMEOUT: + return thr_stat->session_mgr->tcp_segs_timeout; + case STAT_TYPE_TCP_SEGS_RETRANSMITED: + return thr_stat->session_mgr->tcp_segs_retransmited; + case STAT_TYPE_TCP_SEGS_OVERLAPPED: + return thr_stat->session_mgr->tcp_segs_overlapped; + case STAT_TYPE_TCP_SEGS_OMITTED_TOO_MANY: + return thr_stat->session_mgr->tcp_segs_omitted_too_many; + case STAT_TYPE_TCP_SEGS_INORDER: + return thr_stat->session_mgr->tcp_segs_inorder; + case STAT_TYPE_TCP_SEGS_REORDERED: + return thr_stat->session_mgr->tcp_segs_reordered; + case STAT_TYPE_TCP_SEGS_BUFFERED: + return thr_stat->session_mgr->tcp_segs_buffered; + case STAT_TYPE_TCP_SEGS_FREED: + return thr_stat->session_mgr->tcp_segs_freed; + + default: + assert(0); + return 0; + } +} + // 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 @@ -273,9 +458,9 @@ struct stellar_stat *stellar_stat_new(uint16_t nr_thread) stat->flag[i] = IS_FREE; } - for (size_t i = 0; i < METRIC_TYPE_MAX; i++) + for (size_t i = 0; i < STAT_TYPE_MAX; i++) { - stat->metric_key[i] = fieldstat_easy_register_counter(stat->fs, name[i]); + stat->stat_idx[i] = fieldstat_easy_register_counter(stat->fs, name[i]); } return stat; @@ -306,258 +491,18 @@ void stellar_stat_output(struct stellar_stat *stat) if (ATOMIC_READ(&(stat->flag[i])) == IS_BUSY) { struct thread_stat *thr_stat = &stat->thr_stat[i]; - for (size_t j = 0; j < METRIC_TYPE_MAX; j++) + for (size_t j = 0; j < STAT_TYPE_MAX; j++) { - switch (j) - { - // device packet - case METRIC_TYPE_PKTS_RX: - stat->metric_val[j] += thr_stat->packet_io->pkts_rx; - break; - case METRIC_TYPE_BYTES_RX: - stat->metric_val[j] += thr_stat->packet_io->bytes_rx; - break; - case METRIC_TYPE_PKTS_TX: - stat->metric_val[j] += thr_stat->packet_io->pkts_tx; - break; - case METRIC_TYPE_BYTES_TX: - stat->metric_val[j] += thr_stat->packet_io->bytes_tx; - break; - // keep-alive packet - case METRIC_TYPE_KEEP_ALIVE_PKTS: - stat->metric_val[j] += thr_stat->packet_io->keep_alive_pkts; - break; - case METRIC_TYPE_KEEP_ALIVE_BYTES: - stat->metric_val[j] += thr_stat->packet_io->keep_alive_bytes; - break; - // raw packet - case METRIC_TYPE_RAW_PKTS_RX: - stat->metric_val[j] += thr_stat->packet_io->raw_pkts_rx; - break; - case METRIC_TYPE_RAW_BYTES_RX: - stat->metric_val[j] += thr_stat->packet_io->raw_bytes_rx; - break; - case METRIC_TYPE_RAW_PKTS_TX: - stat->metric_val[j] += thr_stat->packet_io->raw_pkts_tx; - break; - case METRIC_TYPE_RAW_BYTES_TX: - stat->metric_val[j] += thr_stat->packet_io->raw_bytes_tx; - break; - // drop packet - case METRIC_TYPE_PKTS_DROPPED: - stat->metric_val[j] += thr_stat->packet_io->pkts_dropped; - break; - case METRIC_TYPE_BYTES_DROPPED: - stat->metric_val[j] += thr_stat->packet_io->bytes_dropped; - break; - // inject packet - case METRIC_TYPE_PKTS_INJECTED: - stat->metric_val[j] += thr_stat->packet_io->pkts_injected; - break; - case METRIC_TYPE_BYTES_INJECTED: - stat->metric_val[j] += thr_stat->packet_io->bytes_injected; - break; - // ctrl packet - case METRIC_TYPE_CTRL_PKTS_RX: - stat->metric_val[j] += thr_stat->packet_io->ctrl_pkts_rx; - break; - case METRIC_TYPE_CTRL_BYTES_RX: - stat->metric_val[j] += thr_stat->packet_io->ctrl_bytes_rx; - break; - case METRIC_TYPE_CTRL_PKTS_TX: - stat->metric_val[j] += thr_stat->packet_io->ctrl_pkts_tx; - break; - case METRIC_TYPE_CTRL_BYTES_TX: - stat->metric_val[j] += thr_stat->packet_io->ctrl_bytes_tx; - break; - // ipv4 reassembly - case METRIC_TYPE_IP4_DEFRAGS_EXPECTED: - stat->metric_val[j] += thr_stat->ip_reassembly->ip4_defrags_expected; - break; - case METRIC_TYPE_IP4_DEFRAGS_SUCCEED: - stat->metric_val[j] += thr_stat->ip_reassembly->ip4_defrags_succeed; - break; - case METRIC_TYPE_IP4_DEFRAGS_FAILED_TIMEOUT: - stat->metric_val[j] += thr_stat->ip_reassembly->ip4_defrags_failed_timeout; - break; - case METRIC_TYPE_IP4_DEFRAGS_FAILED_INVALID_LENGTH: - stat->metric_val[j] += thr_stat->ip_reassembly->ip4_defrags_failed_invalid_length; - break; - case METRIC_TYPE_IP4_DEFRAGS_FAILED_OVERLAP: - stat->metric_val[j] += thr_stat->ip_reassembly->ip4_defrags_failed_overlap; - break; - case METRIC_TYPE_IP4_DEFRAGS_FAILED_TOO_MANY_FRAG: - stat->metric_val[j] += thr_stat->ip_reassembly->ip4_defrags_failed_too_many_frag; - break; - case METRIC_TYPE_IP4_FRAGS: - stat->metric_val[j] += thr_stat->ip_reassembly->ip4_frags; - break; - case METRIC_TYPE_IP4_FRAGS_FREED: - stat->metric_val[j] += thr_stat->ip_reassembly->ip4_frags_freed; - break; - case METRIC_TYPE_IP4_FRAGS_BUFFERED: - stat->metric_val[j] += thr_stat->ip_reassembly->ip4_frags_buffered; - break; - case METRIC_TYPE_IP4_FRAGS_BYPASS_NO_BUFFER: - stat->metric_val[j] += thr_stat->ip_reassembly->ip4_frags_bypass_no_buffer; - break; - case METRIC_TYPE_IP4_FRAGS_BYPASS_DUP_FIST_FRAG: - stat->metric_val[j] += thr_stat->ip_reassembly->ip4_frags_bypass_dup_fist_frag; - break; - case METRIC_TYPE_IP4_FRAGS_BYPASS_DUP_LAST_FRAG: - stat->metric_val[j] += thr_stat->ip_reassembly->ip4_frags_bypass_dup_last_frag; - break; - // ipv6 reassembly - case METRIC_TYPE_IP6_DEFRAGS_EXPECTED: - stat->metric_val[j] += thr_stat->ip_reassembly->ip6_defrags_expected; - break; - case METRIC_TYPE_IP6_DEFRAGS_SUCCEED: - stat->metric_val[j] += thr_stat->ip_reassembly->ip6_defrags_succeed; - break; - case METRIC_TYPE_IP6_DEFRAGS_FAILED_TIMEOUT: - stat->metric_val[j] += thr_stat->ip_reassembly->ip6_defrags_failed_timeout; - break; - case METRIC_TYPE_IP6_DEFRAGS_FAILED_INVALID_LENGTH: - stat->metric_val[j] += thr_stat->ip_reassembly->ip6_defrags_failed_invalid_length; - break; - case METRIC_TYPE_IP6_DEFRAGS_FAILED_OVERLAP: - stat->metric_val[j] += thr_stat->ip_reassembly->ip6_defrags_failed_overlap; - break; - case METRIC_TYPE_IP6_DEFRAGS_FAILED_TOO_MANY_FRAG: - stat->metric_val[j] += thr_stat->ip_reassembly->ip6_defrags_failed_too_many_frag; - break; - case METRIC_TYPE_IP6_FRAGS: - stat->metric_val[j] += thr_stat->ip_reassembly->ip6_frags; - break; - case METRIC_TYPE_IP6_FRAGS_FREED: - stat->metric_val[j] += thr_stat->ip_reassembly->ip6_frags_freed; - break; - case METRIC_TYPE_IP6_FRAGS_BUFFERED: - stat->metric_val[j] += thr_stat->ip_reassembly->ip6_frags_buffered; - break; - case METRIC_TYPE_IP6_FRAGS_BYPASS_NO_BUFFER: - stat->metric_val[j] += thr_stat->ip_reassembly->ip6_frags_bypass_no_buffer; - break; - case METRIC_TYPE_IP6_FRAGS_BYPASS_DUP_FIST_FRAG: - stat->metric_val[j] += thr_stat->ip_reassembly->ip6_frags_bypass_dup_fist_frag; - break; - case METRIC_TYPE_IP6_FRAGS_BYPASS_DUP_LAST_FRAG: - stat->metric_val[j] += thr_stat->ip_reassembly->ip6_frags_bypass_dup_last_frag; - break; - // TCP session - case METRIC_TYPE_HISTORY_TCP_SESSIONS: - stat->metric_val[j] += thr_stat->session_mgr->history_tcp_sessions; - break; - case METRIC_TYPE_TCP_SESS_USED: - stat->metric_val[j] += thr_stat->session_mgr->tcp_sess_used; - break; - case METRIC_TYPE_TCP_SESS_OPENING: - stat->metric_val[j] += thr_stat->session_mgr->tcp_sess_opening; - break; - case METRIC_TYPE_TCP_SESS_ACTIVE: - stat->metric_val[j] += thr_stat->session_mgr->tcp_sess_active; - break; - case METRIC_TYPE_TCP_SESS_CLOSING: - stat->metric_val[j] += thr_stat->session_mgr->tcp_sess_closing; - break; - case METRIC_TYPE_TCP_SESS_DISCARD: - stat->metric_val[j] += thr_stat->session_mgr->tcp_sess_discard; - break; - case METRIC_TYPE_TCP_SESS_CLOSED: - stat->metric_val[j] += thr_stat->session_mgr->tcp_sess_closed; - break; - // UDP session - case METRIC_TYPE_HISTORY_UDP_SESSIONS: - stat->metric_val[j] += thr_stat->session_mgr->history_udp_sessions; - break; - case METRIC_TYPE_UDP_SESS_USED: - stat->metric_val[j] += thr_stat->session_mgr->udp_sess_used; - break; - case METRIC_TYPE_UDP_SESS_OPENING: - stat->metric_val[j] += thr_stat->session_mgr->udp_sess_opening; - break; - case METRIC_TYPE_UDP_SESS_ACTIVE: - stat->metric_val[j] += thr_stat->session_mgr->udp_sess_active; - break; - case METRIC_TYPE_UDP_SESS_CLOSING: - stat->metric_val[j] += thr_stat->session_mgr->udp_sess_closing; - break; - case METRIC_TYPE_UDP_SESS_DISCARD: - stat->metric_val[j] += thr_stat->session_mgr->udp_sess_discard; - break; - case METRIC_TYPE_UDP_SESS_CLOSED: - stat->metric_val[j] += thr_stat->session_mgr->udp_sess_closed; - break; - // Evicted session - case METRIC_TYPE_TCP_SESS_EVICTED: - stat->metric_val[j] += thr_stat->session_mgr->tcp_sess_evicted; - break; - case METRIC_TYPE_UDP_SESS_EVICTED: - stat->metric_val[j] += thr_stat->session_mgr->udp_sess_evicted; - break; - // Packet - case METRIC_TYPE_UDP_PKTS_BYPASS_TABLE_FULL: - stat->metric_val[j] += thr_stat->session_mgr->udp_pkts_bypass_table_full; - break; - case METRIC_TYPE_TCP_PKTS_BYPASS_TABLE_FULL: - stat->metric_val[j] += thr_stat->session_mgr->tcp_pkts_bypass_table_full; - break; - case METRIC_TYPE_TCP_PKTS_BYPASS_SESSION_NOT_FOUND: - stat->metric_val[j] += thr_stat->session_mgr->tcp_pkts_bypass_session_not_found; - break; - case METRIC_TYPE_TCP_PKTS_BYPASS_DUPLICATED: - stat->metric_val[j] += thr_stat->session_mgr->tcp_pkts_bypass_duplicated; - break; - case METRIC_TYPE_UDP_PKTS_BYPASS_DUPLICATED: - stat->metric_val[j] += thr_stat->session_mgr->udp_pkts_bypass_duplicated; - break; - case METRIC_TYPE_UDP_PKTS_BYPASS_SESSION_EVICTED: - stat->metric_val[j] += thr_stat->session_mgr->udp_pkts_bypass_session_evicted; - break; - // TCP segments - case METRIC_TYPE_TCP_SEGS_INPUT: - stat->metric_val[j] += thr_stat->session_mgr->tcp_segs_input; - break; - case METRIC_TYPE_TCP_SEGS_CONSUMED: - stat->metric_val[j] += thr_stat->session_mgr->tcp_segs_consumed; - break; - case METRIC_TYPE_TCP_SEGS_TIMEOUT: - stat->metric_val[j] += thr_stat->session_mgr->tcp_segs_timeout; - break; - case METRIC_TYPE_TCP_SEGS_RETRANSMITED: - stat->metric_val[j] += thr_stat->session_mgr->tcp_segs_retransmited; - break; - case METRIC_TYPE_TCP_SEGS_OVERLAPPED: - stat->metric_val[j] += thr_stat->session_mgr->tcp_segs_overlapped; - break; - case METRIC_TYPE_TCP_SEGS_OMITTED_TOO_MANY: - stat->metric_val[j] += thr_stat->session_mgr->tcp_segs_omitted_too_many; - break; - case METRIC_TYPE_TCP_SEGS_INORDER: - stat->metric_val[j] += thr_stat->session_mgr->tcp_segs_inorder; - break; - case METRIC_TYPE_TCP_SEGS_REORDERED: - stat->metric_val[j] += thr_stat->session_mgr->tcp_segs_reordered; - break; - case METRIC_TYPE_TCP_SEGS_BUFFERED: - stat->metric_val[j] += thr_stat->session_mgr->tcp_segs_buffered; - break; - case METRIC_TYPE_TCP_SEGS_FREED: - stat->metric_val[j] += thr_stat->session_mgr->tcp_segs_freed; - break; - default: - assert(0); - break; - } + stat->stat_val[j] += get_stat_value_by_idx(thr_stat, j); } memset(thr_stat, 0, sizeof(struct thread_stat)); ATOMIC_SET(&(stat->flag[i]), IS_FREE); } } - for (size_t j = 0; j < METRIC_TYPE_MAX; j++) + for (size_t j = 0; j < STAT_TYPE_MAX; j++) { - fieldstat_easy_counter_set(stat->fs, 0, stat->metric_key[j], NULL, 0, stat->metric_val[j]); + fieldstat_easy_counter_set(stat->fs, 0, stat->stat_idx[j], NULL, 0, stat->stat_val[j]); } char *buff; @@ -579,9 +524,9 @@ void stellar_stat_output(struct stellar_stat *stat) free(buff); } - for (size_t j = 0; j < METRIC_TYPE_MAX; j++) + for (size_t j = 0; j < STAT_TYPE_MAX; j++) { - stat->metric_val[j] = 0; + stat->stat_val[j] = 0; } } @@ -593,3 +538,11 @@ void stellar_stat_merge(struct stellar_stat *stat, const struct thread_stat *thr ATOMIC_SET(&(stat->flag[thr_idx]), IS_BUSY); } } + +void stellar_stat_print(struct stellar_stat *stat __attribute__((unused)), const struct thread_stat *thr_stat, uint16_t thr_idx) +{ + for (size_t i = 0; i < STAT_TYPE_MAX; i++) + { + STAT_LOG_INFO("worker thread %lu => %-34s: %lu", thr_idx, name[i], get_stat_value_by_idx(thr_stat, i)); + } +} diff --git a/src/core/stellar_stat.h b/src/core/stellar_stat.h index b309373..fbef78d 100644 --- a/src/core/stellar_stat.h +++ b/src/core/stellar_stat.h @@ -21,6 +21,7 @@ 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_stat_merge(struct stellar_stat *stat, const struct thread_stat *thr_stat, uint16_t thr_idx); +void stellar_stat_print(struct stellar_stat *stat, const struct thread_stat *thr_stat, uint16_t thr_idx); #ifdef __cplusplus }