2023-02-21 09:58:31 +08:00
# include <stdlib.h>
# include <string.h>
# include <assert.h>
# include <MESA/MESA_prof_load.h>
# include "log.h"
# include "global_metrics.h"
2024-11-08 15:30:28 +08:00
// type, name, value
# define STAT_MAP(XX) \
/* device_nf */ \
XX ( STAT_DEVICE_NF_RX_PKT , dev_nf_rx_P , nf_rx . n_pkts ) \
XX ( STAT_DEVICE_NF_RX_B , dev_nf_rx_B , nf_rx . n_bytes ) \
XX ( STAT_DEVICE_NF_TX_PKT , dev_nf_tx_P , nf_tx . n_pkts ) \
XX ( STAT_DEVICE_NF_TX_B , dev_nf_tx_B , nf_tx . n_bytes ) \
XX ( STAT_KEE_PKT_DOWN_RX_PKT , kee_d_rx_P , downlink_rx . n_pkts ) \
XX ( STAT_KEE_PKT_DOWN_RX_B , kee_d_rx_B , downlink_rx . n_bytes ) \
XX ( STAT_KEE_PKT_DOWN_TX_PKT , kee_d_tx_P , downlink_tx . n_pkts ) \
XX ( STAT_KEE_PKT_DOWN_TX_B , kee_d_tx_B , downlink_tx . n_bytes ) \
/* raw traffic */ \
XX ( STAT_RAW_TRAFFIC_RX_PKT , raw_rx_P , raw_rx . n_pkts ) \
XX ( STAT_RAW_TRAFFIC_RX_B , raw_rx_B , raw_rx . n_bytes ) \
XX ( STAT_RAW_TRAFFIC_TX_PKT , raw_tx_P , raw_tx . n_pkts ) \
XX ( STAT_RAW_TRAFFIC_TX_B , raw_tx_B , raw_tx . n_bytes ) \
/* decrypted traffic */ \
XX ( STAT_DECRYPTED_TRAFFIC_RX_PKT , dec_rx_P , dec_rx . n_pkts ) \
XX ( STAT_DECRYPTED_TRAFFIC_RX_B , dec_rx_B , dec_rx . n_bytes ) \
XX ( STAT_DECRYPTED_TRAFFIC_TX_PKT , dec_tx_P , dec_tx . n_pkts ) \
XX ( STAT_DECRYPTED_TRAFFIC_TX_B , dec_tx_B , dec_tx . n_bytes ) \
/* device_endpoint_vxlan */ \
XX ( STAT_DEVICE_ENDPOINT_VXLAN_RX_PKT , dev_l3_rx_P , endpoint_vxlan_rx . n_pkts ) \
XX ( STAT_DEVICE_ENDPOINT_VXLAN_RX_B , dev_l3_rx_B , endpoint_vxlan_rx . n_bytes ) \
XX ( STAT_DEVICE_ENDPOINT_VXLAN_TX_PKT , dev_l3_tx_P , endpoint_vxlan_tx . n_pkts ) \
XX ( STAT_DEVICE_ENDPOINT_VXLAN_TX_B , dev_l3_tx_B , endpoint_vxlan_tx . n_bytes ) \
XX ( STAT_DEVICE_ENDPOINT_VXLAN_DROP_PKT , dev_l3_dop_P , endpoint_vxlan_drop . n_pkts ) \
XX ( STAT_DEVICE_ENDPOINT_VXLAN_DROP_B , dev_l3_dop_B , endpoint_vxlan_drop . n_bytes ) \
XX ( STAT_KEE_PKT_UP_RX_PKT , kee_u_rx_P , uplink_rx . n_pkts ) \
XX ( STAT_KEE_PKT_UP_RX_B , kee_u_rx_B , uplink_rx . n_bytes ) \
XX ( STAT_KEE_PKT_UP_TX_DROP_PKT , kee_u_rxdop_P , uplink_tx_drop . n_pkts ) \
XX ( STAT_KEE_PKT_UP_TX_DROP_B , kee_u_rxdop_B , uplink_tx_drop . n_bytes ) \
/* device_endpoint_vlan */ \
XX ( STAT_DEVICE_ENDPOINT_VLAN_RX_PKT , dev_l2_rx_P , endpoint_vlan_rx . n_pkts ) \
XX ( STAT_DEVICE_ENDPOINT_VLAN_RX_B , dev_l2_rx_B , endpoint_vlan_rx . n_bytes ) \
XX ( STAT_DEVICE_ENDPOINT_VLAN_TX_PKT , dev_l2_tx_P , endpoint_vlan_tx . n_pkts ) \
XX ( STAT_DEVICE_ENDPOINT_VLAN_TX_B , dev_l2_tx_B , endpoint_vlan_tx . n_bytes ) \
XX ( STAT_DEVICE_ENDPOINT_VLAN_DROP_PKT , dev_l2_dop_P , endpoint_vlan_drop . n_pkts ) \
XX ( STAT_DEVICE_ENDPOINT_VLAN_DROP_B , dev_l2_dop_B , endpoint_vlan_drop . n_bytes ) \
/* data_pkt_metrics */ \
XX ( STAT_DATA_PKT_MIRR_BYPASS_PKT , mirr_bypass_P , mirr_bypass . n_pkts ) \
XX ( STAT_DATA_PKT_MIRR_BYPASS_B , mirr_bypass_B , mirr_bypass . n_bytes ) \
XX ( STAT_DATA_PKT_MIRR_BLOCK_PKT , mirr_block_P , mirr_block . n_pkts ) \
XX ( STAT_DATA_PKT_MIRR_BLOCK_B , mirr_block_B , mirr_block . n_bytes ) \
XX ( STAT_DATA_PKT_MIRR_RX_DROP_PKT , mirr_rxdop_P , mirr_rx_drop . n_pkts ) \
XX ( STAT_DATA_PKT_MIRR_RX_DROP_B , mirr_rxdop_B , mirr_rx_drop . n_bytes ) \
XX ( STAT_DATA_PKT_MIRR_TX_PKT , mirr_tx_P , mirr_tx . n_pkts ) \
XX ( STAT_DATA_PKT_MIRR_TX_B , mirr_tx_B , mirr_tx . n_bytes ) \
XX ( STAT_DATA_PKT_STEE_BYPASS_PKT , stee_bypass_P , stee_bypass . n_pkts ) \
XX ( STAT_DATA_PKT_STEE_BYPASS_B , stee_bypass_B , stee_bypass . n_bytes ) \
XX ( STAT_DATA_PKT_STEE_BLOCK_PKT , stee_block_P , stee_block . n_pkts ) \
XX ( STAT_DATA_PKT_STEE_BLOCK_B , stee_block_B , stee_block . n_bytes ) \
XX ( STAT_DATA_PKT_STEE_RX_PKT , stee_rx_P , stee_rx . n_pkts ) \
XX ( STAT_DATA_PKT_STEE_RX_B , stee_rx_B , stee_rx . n_bytes ) \
XX ( STAT_DATA_PKT_STEE_TX_PKT , stee_tx_P , stee_tx . n_pkts ) \
XX ( STAT_DATA_PKT_STEE_TX_B , stee_tx_B , stee_tx . n_bytes ) \
XX ( STAT_DATA_PKT_MISS_SESS_PKT , miss_sess_P , miss_sess . n_pkts ) \
XX ( STAT_DATA_PKT_MISS_SESS_B , miss_sess_B , miss_sess . n_bytes ) \
XX ( STAT_DATA_PKT_ERROR_BYPASS_PKT , err_bypass_P , error_bypass . n_pkts ) \
XX ( STAT_DATA_PKT_ERROR_BYPASS_B , err_bypass_B , error_bypass . n_bytes ) \
XX ( STAT_DATA_PKT_ERROR_BLOCK_PKT , err_block_P , error_block . n_pkts ) \
XX ( STAT_DATA_PKT_ERROR_BLOCK_B , err_block_B , error_block . n_bytes ) \
/* sf_status_metrics */ \
XX ( STAT_SF_STATUS_ACTIVE , sf_active , sf_active ) \
XX ( STAT_SF_STATUS_INACTIVE , sf_inactive , sf_inactive ) \
/* ctrl_pkt_metrics */ \
XX ( STAT_CTRL_PKT_RX_PKT , ctrl_rx_P , ctrl_rx . n_pkts ) \
XX ( STAT_CTRL_PKT_RX_B , ctrl_rx_B , ctrl_rx . n_bytes ) \
XX ( STAT_CTRL_PKT_TX_PKT , ctrl_tx_P , ctrl_tx . n_pkts ) \
XX ( STAT_CTRL_PKT_TX_B , ctrl_tx_B , ctrl_tx . n_bytes ) \
XX ( STAT_CTRL_PKT_OPENING , ctrl_opening , ctrl_opening ) \
XX ( STAT_CTRL_PKT_ACTIVE , ctrl_active , ctrl_active ) \
XX ( STAT_CTRL_PKT_CLOSING , ctrl_closing , ctrl_closing ) \
XX ( STAT_CTRL_PKT_RESETALL , ctrl_resetall , ctrl_resetall ) \
XX ( STAT_CTRL_PKT_ERROR , ctrl_error , ctrl_error ) \
/* sf_session_metrics */ \
XX ( STAT_SF_SESSION_NUM , curr_sessions , session_num ) \
XX ( STAT_SF_SESSION_LOG , session_logs , session_log ) \
XX ( STAT_SESSION_NEW , session_new , session_new ) \
XX ( STAT_SESSION_FREE , session_free , session_free ) \
/* stateless inject */ \
XX ( STAT_STATELESS_INJECT_PKT , stateless_inject_P , stateless_inject . n_pkts ) \
XX ( STAT_STATELESS_INJECT_B , stateless_inject_B , stateless_inject . n_bytes )
enum stat_type
2023-02-21 09:58:31 +08:00
{
2024-11-08 15:30:28 +08:00
# define XX(_type, _name, _value) _type,
STAT_MAP ( XX )
# undef XX
STAT_MAX
2023-02-21 09:58:31 +08:00
} ;
2024-11-08 15:30:28 +08:00
static const char * stat_str [ ] =
2023-02-21 09:58:31 +08:00
{
2024-11-08 15:30:28 +08:00
# define XX(_type, _name, _value) #_name,
STAT_MAP ( XX )
# undef XX
} ;
2024-03-07 10:38:05 +08:00
2024-11-08 15:30:28 +08:00
static uint64_t thread_metrics_get_value ( struct thread_metrics * metrics , enum stat_type type )
{
switch ( type )
{
# define XX(_type, _name, _value) \
case _type : \
return metrics - > _value ;
STAT_MAP ( XX )
# undef XX
default :
return 0 ;
}
}
2024-04-20 11:40:00 +08:00
2024-11-08 15:30:28 +08:00
static void thread_metrics_add_value ( struct thread_metrics * metrics , enum stat_type type , uint64_t value )
{
switch ( type )
{
# define XX(_type, _name, _value) \
case _type : \
metrics - > _value + = value ; \
break ;
STAT_MAP ( XX )
# undef XX
default :
break ;
}
}
2023-02-21 09:58:31 +08:00
2023-03-14 16:10:44 +08:00
static void global_metrics_parse_config ( const char * profile , struct metrics_config * config )
2023-02-21 09:58:31 +08:00
{
2024-11-08 15:30:28 +08:00
MESA_load_profile_string_def ( profile , " STAT " , " output_file " , config - > output_file , sizeof ( config - > output_file ) , " log/sce.fs4 " ) ;
2023-02-21 09:58:31 +08:00
MESA_load_profile_int_def ( profile , " STAT " , " statsd_cycle " , & ( config - > statsd_cycle ) , 1 ) ;
2023-11-23 16:52:06 +08:00
LOG_DEBUG ( " STAT->output_file : %s " , config - > output_file ) ;
LOG_DEBUG ( " STAT->statsd_cycle : %d " , config - > statsd_cycle ) ;
2023-02-21 09:58:31 +08:00
}
2023-10-12 16:31:53 +08:00
struct global_metrics * global_metrics_create ( const char * profile , int thread_num )
2023-02-21 09:58:31 +08:00
{
2023-10-12 16:31:53 +08:00
struct global_metrics * global_metrics = ( struct global_metrics * ) calloc ( 1 , sizeof ( struct global_metrics ) ) ;
assert ( global_metrics ! = NULL ) ;
2023-02-21 09:58:31 +08:00
2023-10-12 16:31:53 +08:00
global_metrics - > thread_num = thread_num ;
global_metrics - > thread_metrics_flag = ( int * ) calloc ( global_metrics - > thread_num , sizeof ( int ) ) ;
global_metrics - > thread_metrics_cache = ( struct thread_metrics * ) calloc ( global_metrics - > thread_num , sizeof ( struct thread_metrics ) ) ;
2023-02-21 09:58:31 +08:00
2023-10-12 16:31:53 +08:00
global_metrics_parse_config ( profile , & global_metrics - > config ) ;
2024-11-08 15:30:28 +08:00
global_metrics - > fs_handle = fieldstat_easy_new ( 1 , " SCE " , NULL , 0 ) ;
if ( global_metrics - > fs_handle = = NULL )
{
LOG_ERROR ( " failed to create fieldstat_easy " ) ;
global_metrics_destory ( global_metrics ) ;
return NULL ;
}
2023-02-21 09:58:31 +08:00
2024-11-08 15:30:28 +08:00
if ( fieldstat_easy_enable_auto_output ( global_metrics - > fs_handle , global_metrics - > config . output_file , global_metrics - > config . statsd_cycle ) ! = 0 )
2023-02-21 09:58:31 +08:00
{
2024-11-08 15:30:28 +08:00
LOG_ERROR ( " failed to enable auto output for fieldstat_easy " ) ;
global_metrics_destory ( global_metrics ) ;
return NULL ;
2023-02-21 09:58:31 +08:00
}
2023-10-12 16:31:53 +08:00
if ( STAT_MAX > = ( sizeof ( global_metrics - > fs_id ) / sizeof ( global_metrics - > fs_id [ 0 ] ) ) )
2023-02-27 14:37:31 +08:00
{
2023-11-23 16:52:06 +08:00
LOG_ERROR ( " field stat has insufficient space to store fs_id, and supports a maximum of %lu fsids, but %d is needed " , ( sizeof ( global_metrics - > fs_id ) / sizeof ( global_metrics - > fs_id [ 0 ] ) ) , STAT_MAX ) ;
2023-10-12 16:31:53 +08:00
global_metrics_destory ( global_metrics ) ;
2023-02-27 14:37:31 +08:00
return NULL ;
}
2023-02-21 09:58:31 +08:00
for ( int i = 0 ; i < STAT_MAX ; i + + )
{
2024-11-08 15:30:28 +08:00
global_metrics - > fs_id [ i ] = fieldstat_easy_register_counter ( global_metrics - > fs_handle , stat_str [ i ] ) ;
2023-02-21 09:58:31 +08:00
}
2023-10-12 16:31:53 +08:00
return global_metrics ;
2023-02-21 09:58:31 +08:00
}
2023-10-12 16:31:53 +08:00
void global_metrics_destory ( struct global_metrics * global_metrics )
2023-02-21 09:58:31 +08:00
{
2023-10-12 16:31:53 +08:00
if ( global_metrics )
2023-02-21 09:58:31 +08:00
{
2023-11-23 16:52:06 +08:00
if ( global_metrics - > thread_metrics_flag )
{
free ( global_metrics - > thread_metrics_flag ) ;
global_metrics - > thread_metrics_flag = NULL ;
}
if ( global_metrics - > thread_metrics_cache )
{
free ( global_metrics - > thread_metrics_cache ) ;
global_metrics - > thread_metrics_cache = NULL ;
}
2024-11-08 15:30:28 +08:00
if ( global_metrics - > fs_handle )
{
fieldstat_easy_free ( global_metrics - > fs_handle ) ;
global_metrics - > fs_handle = NULL ;
}
2023-10-12 16:31:53 +08:00
free ( global_metrics ) ;
global_metrics = NULL ;
2023-02-21 09:58:31 +08:00
}
}
2023-10-12 16:31:53 +08:00
# define THREAD_METRICS_CACHE_IS_FREE 0
# define THREAD_METRICS_CACHE_IS_BUSY 0xf
2024-11-08 15:30:28 +08:00
void global_metrics_sync ( struct global_metrics * global_metrics , struct thread_metrics * thread_metrics , int thread_id )
2023-02-21 09:58:31 +08:00
{
2023-10-12 16:31:53 +08:00
if ( ATOMIC_READ ( & ( global_metrics - > thread_metrics_flag [ thread_id ] ) ) = = THREAD_METRICS_CACHE_IS_FREE )
{
struct thread_metrics * ptr_metrics = & global_metrics - > thread_metrics_cache [ thread_id ] ;
memcpy ( ptr_metrics , thread_metrics , sizeof ( struct thread_metrics ) ) ;
memset ( thread_metrics , 0 , sizeof ( struct thread_metrics ) ) ;
ATOMIC_SET ( & ( global_metrics - > thread_metrics_flag [ thread_id ] ) , THREAD_METRICS_CACHE_IS_BUSY ) ;
}
}
2024-11-08 15:30:28 +08:00
void global_metrics_flush ( struct global_metrics * global_metrics )
2023-10-12 16:31:53 +08:00
{
2023-11-24 15:17:18 +08:00
struct thread_metrics * sum = & global_metrics - > sum ;
2024-11-08 15:30:28 +08:00
struct thread_metrics last = * sum ;
2023-10-12 16:31:53 +08:00
for ( int i = 0 ; i < global_metrics - > thread_num ; i + + )
{
if ( ATOMIC_READ ( & ( global_metrics - > thread_metrics_flag [ i ] ) ) = = THREAD_METRICS_CACHE_IS_BUSY )
{
2023-11-24 15:17:18 +08:00
struct thread_metrics * thread = & global_metrics - > thread_metrics_cache [ i ] ;
2024-11-08 15:30:28 +08:00
for ( int j = 0 ; j < STAT_MAX ; j + + )
{
uint64_t val = thread_metrics_get_value ( thread , ( enum stat_type ) j ) ;
thread_metrics_add_value ( sum , ( enum stat_type ) j , val ) ;
}
2023-11-24 15:17:18 +08:00
memset ( thread , 0 , sizeof ( struct thread_metrics ) ) ;
2023-10-12 16:31:53 +08:00
ATOMIC_SET ( & ( global_metrics - > thread_metrics_flag [ i ] ) , THREAD_METRICS_CACHE_IS_FREE ) ;
}
}
2023-02-21 09:58:31 +08:00
2024-11-08 15:30:28 +08:00
for ( int i = 0 ; i < STAT_MAX ; i + + )
{
uint64_t delta = thread_metrics_get_value ( sum , ( enum stat_type ) i ) - thread_metrics_get_value ( & last , ( enum stat_type ) i ) ;
fieldstat_easy_counter_incrby ( global_metrics - > fs_handle , 0 , global_metrics - > fs_id [ i ] , NULL , 0 , delta ) ;
}
2023-02-21 09:58:31 +08:00
}