This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
tango-tsg-service-chaining-…/platform/src/global_metrics.cpp

357 lines
16 KiB
C++

#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <MESA/MESA_prof_load.h>
#include "log.h"
#include "global_metrics.h"
enum SCE_STAT_FIELD
{
// device_metrics
STAT_DEVICE_NF_RX_PKT,
STAT_DEVICE_NF_RX_B,
STAT_DEVICE_NF_TX_PKT,
STAT_DEVICE_NF_TX_B,
STAT_DEVICE_ENDPOINT_RX_PKT,
STAT_DEVICE_ENDPOINT_RX_B,
STAT_DEVICE_ENDPOINT_TX_PKT,
STAT_DEVICE_ENDPOINT_TX_B,
// keepalived_pkt_metrics
STAT_KEE_PKT_DOWN_RX_PKT,
STAT_KEE_PKT_DOWN_RX_B,
STAT_KEE_PKT_DOWN_TX_PKT,
STAT_KEE_PKT_DOWN_TX_B,
STAT_KEE_PKT_UP_RX_PKT,
STAT_KEE_PKT_UP_RX_B,
STAT_KEE_PKT_UP_TX_DROP_PKT,
STAT_KEE_PKT_UP_TX_DROP_B,
// raw_pkt_metrics
STAT_RAW_PKT_MIRR_BYPASS_PKT,
STAT_RAW_PKT_MIRR_BYPASS_B,
STAT_RAW_PKT_MIRR_BLOCK_PKT,
STAT_RAW_PKT_MIRR_BLOCK_B,
STAT_RAW_PKT_MIRR_RX_DROP_PKT,
STAT_RAW_PKT_MIRR_RX_DROP_B,
STAT_RAW_PKT_MIRR_TX_PKT,
STAT_RAW_PKT_MIRR_TX_B,
STAT_RAW_PKT_STEE_BYPASS_PKT,
STAT_RAW_PKT_STEE_BYPASS_B,
STAT_RAW_PKT_STEE_BLOCK_PKT,
STAT_RAW_PKT_STEE_BLOCK_B,
STAT_RAW_PKT_STEE_RX_PKT,
STAT_RAW_PKT_STEE_RX_B,
STAT_RAW_PKT_STEE_TX_PKT,
STAT_RAW_PKT_STEE_TX_B,
STAT_RAW_PKT_MISS_SESS_PKT,
STAT_RAW_PKT_MISS_SESS_B,
STAT_RAW_PKT_ERROR_BYPASS_PKT,
STAT_RAW_PKT_ERROR_BYPASS_B,
STAT_RAW_PKT_ERROR_BLOCK_PKT,
STAT_RAW_PKT_ERROR_BLOCK_B,
STAT_DEVICE_ENDPOINT_DROP_PKT,
STAT_DEVICE_ENDPOINT_DROP_B,
// ctrl_pkt_metrics
STAT_CTRL_PKT_RX_PKT,
STAT_CTRL_PKT_RX_B,
STAT_CTRL_PKT_TX_PKT,
STAT_CTRL_PKT_TX_B,
STAT_CTRL_PKT_OPENING,
STAT_CTRL_PKT_ACTIVE,
STAT_CTRL_PKT_CLOSING,
STAT_CTRL_PKT_RESETALL,
STAT_CTRL_PKT_ERROR,
// sf_session_metrics
STAT_SF_SESSION_NUM,
STAT_SF_SESSION_LOG,
// sf_status_metrics
STAT_SF_STATUS_ACTIVE,
STAT_SF_STATUS_INACTIVE,
// max
STAT_MAX,
};
static const char *stat_map[] =
{
// device_metrics
[STAT_DEVICE_NF_RX_PKT] = "nf_rx_pkt",
[STAT_DEVICE_NF_RX_B] = "nf_rx_B",
[STAT_DEVICE_NF_TX_PKT] = "nf_tx_pkt",
[STAT_DEVICE_NF_TX_B] = "nf_tx_B",
[STAT_DEVICE_ENDPOINT_RX_PKT] = "endp_rx_pkt",
[STAT_DEVICE_ENDPOINT_RX_B] = "endp_rx_B",
[STAT_DEVICE_ENDPOINT_TX_PKT] = "endp_tx_pkt",
[STAT_DEVICE_ENDPOINT_TX_B] = "endp_tx_B",
// keepalived_pkt_metrics
[STAT_KEE_PKT_DOWN_RX_PKT] = "kee_d_rx_pkt",
[STAT_KEE_PKT_DOWN_RX_B] = "kee_d_rx_B",
[STAT_KEE_PKT_DOWN_TX_PKT] = "kee_d_tx_pkt",
[STAT_KEE_PKT_DOWN_TX_B] = "kee_d_tx_B",
[STAT_KEE_PKT_UP_RX_PKT] = "kee_u_rx_pkt",
[STAT_KEE_PKT_UP_RX_B] = "kee_u_rx_B",
[STAT_KEE_PKT_UP_TX_DROP_PKT] = "kee_u_rxdop_pkt",
[STAT_KEE_PKT_UP_TX_DROP_B] = "kee_u_rxdop_B",
// raw_pkt_metrics
[STAT_RAW_PKT_MIRR_BYPASS_PKT] = "mirr_bypass_pkt",
[STAT_RAW_PKT_MIRR_BYPASS_B] = "mirr_bypass_B",
[STAT_RAW_PKT_MIRR_BLOCK_PKT] = "mirr_block_pkt",
[STAT_RAW_PKT_MIRR_BLOCK_B] = "mirr_block_B",
[STAT_RAW_PKT_MIRR_RX_DROP_PKT] = "mirr_rxdop_pkt",
[STAT_RAW_PKT_MIRR_RX_DROP_B] = "mirr_rxdop_B",
[STAT_RAW_PKT_MIRR_TX_PKT] = "mirro_tx_pkt",
[STAT_RAW_PKT_MIRR_TX_B] = "mirro_tx_B",
[STAT_RAW_PKT_STEE_BYPASS_PKT] = "stee_bypass_pkt",
[STAT_RAW_PKT_STEE_BYPASS_B] = "stee_bypass_B",
[STAT_RAW_PKT_STEE_BLOCK_PKT] = "stee_block_pkt",
[STAT_RAW_PKT_STEE_BLOCK_B] = "stee_block_B",
[STAT_RAW_PKT_STEE_RX_PKT] = "stee_rx_pkt",
[STAT_RAW_PKT_STEE_RX_B] = "stee_rx_B",
[STAT_RAW_PKT_STEE_TX_PKT] = "stee_tx_pkt",
[STAT_RAW_PKT_STEE_TX_B] = "stee_tx_B",
[STAT_RAW_PKT_MISS_SESS_PKT] = "miss_sess_pkt",
[STAT_RAW_PKT_MISS_SESS_B] = "miss_sess_B",
[STAT_RAW_PKT_ERROR_BYPASS_PKT] = "err_bypass_pkt",
[STAT_RAW_PKT_ERROR_BYPASS_B] = "err_bypass_B",
[STAT_RAW_PKT_ERROR_BLOCK_PKT] = "err_block_pkt",
[STAT_RAW_PKT_ERROR_BLOCK_B] = "err_block_B",
[STAT_DEVICE_ENDPOINT_DROP_PKT] = "endp_drop_pkt",
[STAT_DEVICE_ENDPOINT_DROP_B] = "endp_drop_B",
// ctrl_pkt_metrics
[STAT_CTRL_PKT_RX_PKT] = "ctrl_rx_pkt",
[STAT_CTRL_PKT_RX_B] = "ctrl_rx_B",
[STAT_CTRL_PKT_TX_PKT] = "ctrl_tx_pkt",
[STAT_CTRL_PKT_TX_B] = "ctrl_tx_B",
[STAT_CTRL_PKT_OPENING] = "ctrl_opening",
[STAT_CTRL_PKT_ACTIVE] = "ctrl_active",
[STAT_CTRL_PKT_CLOSING] = "ctrl_closing",
[STAT_CTRL_PKT_RESETALL] = "ctrl_resetall",
[STAT_CTRL_PKT_ERROR] = "ctrl_error",
// sf_session_metrics
[STAT_SF_SESSION_NUM] = "session_num",
[STAT_SF_SESSION_LOG] = "session_logs",
// sf_status_metrics
[STAT_SF_STATUS_ACTIVE] = "sf_active",
[STAT_SF_STATUS_INACTIVE] = "sf_inactive",
[STAT_MAX] = NULL};
static void global_metrics_parse_config(const char *profile, struct metrics_config *config)
{
MESA_load_profile_string_def(profile, "STAT", "output_file", config->output_file, sizeof(config->output_file), "log/sce.fs2");
MESA_load_profile_string_def(profile, "STAT", "statsd_server", config->statsd_server, sizeof(config->statsd_server), "127.0.0.1");
MESA_load_profile_int_def(profile, "STAT", "statsd_port", &(config->statsd_port), 8100);
MESA_load_profile_int_def(profile, "STAT", "statsd_format", &(config->statsd_format), 1); // FS_OUTPUT_STATSD=1, FS_OUTPUT_INFLUX_LINE=2
MESA_load_profile_int_def(profile, "STAT", "statsd_cycle", &(config->statsd_cycle), 1);
MESA_load_profile_int_def(profile, "STAT", "prometheus_listen_port", &(config->prometheus_listen_port), 9001);
MESA_load_profile_string_def(profile, "STAT", "prometheus_listen_url", config->prometheus_listen_url, sizeof(config->prometheus_listen_url), "/sce_prometheus");
if (config->statsd_format != 1 && config->statsd_format != 2)
{
config->statsd_format = 1;
}
LOG_DEBUG("%s: STAT->output_file : %s", LOG_TAG_METRICS, config->output_file);
LOG_DEBUG("%s: STAT->statsd_server : %s", LOG_TAG_METRICS, config->statsd_server);
LOG_DEBUG("%s: STAT->statsd_port : %d", LOG_TAG_METRICS, config->statsd_port);
LOG_DEBUG("%s: STAT->statsd_format : %d", LOG_TAG_METRICS, config->statsd_format);
LOG_DEBUG("%s: STAT->statsd_cycle : %d", LOG_TAG_METRICS, config->statsd_cycle);
LOG_DEBUG("%s: STAT->prometheus_listen_port : %d", LOG_TAG_METRICS, config->prometheus_listen_port);
LOG_DEBUG("%s: STAT->prometheus_listen_url : %s", LOG_TAG_METRICS, config->prometheus_listen_url);
}
struct global_metrics *global_metrics_create(const char *profile)
{
struct global_metrics *metrics = (struct global_metrics *)calloc(1, sizeof(struct global_metrics));
assert(metrics != NULL);
global_metrics_parse_config(profile, &metrics->config);
FS_library_set_prometheus_port(metrics->config.prometheus_listen_port);
FS_library_set_prometheus_url_path(metrics->config.prometheus_listen_url);
FS_library_init();
int value = 0;
metrics->fs_handle = FS_create_handle(); // TODO memleak no free() API
FS_set_para(metrics->fs_handle, APP_NAME, "SCE", 3);
FS_set_para(metrics->fs_handle, OUTPUT_DEVICE, metrics->config.output_file, strlen(metrics->config.output_file));
value = 1;
FS_set_para(metrics->fs_handle, OUTPUT_PROMETHEUS, &value, sizeof(value));
value = 1;
FS_set_para(metrics->fs_handle, PRINT_MODE, &value, sizeof(value));
value = 0;
FS_set_para(metrics->fs_handle, CREATE_THREAD, &value, sizeof(value));
if (strlen(metrics->config.statsd_server) > 0 && metrics->config.statsd_port != 0)
{
FS_set_para(metrics->fs_handle, STATS_SERVER_IP, metrics->config.statsd_server, strlen(metrics->config.statsd_server));
FS_set_para(metrics->fs_handle, STATS_SERVER_PORT, &(metrics->config.statsd_port), sizeof(metrics->config.statsd_port));
FS_set_para(metrics->fs_handle, STATS_FORMAT, &metrics->config.statsd_format, sizeof(metrics->config.statsd_format));
}
if (STAT_MAX >= (sizeof(metrics->fs_id) / sizeof(metrics->fs_id[0])))
{
LOG_ERROR("%s: field stat has insufficient space to store fs_id, and supports a maximum of %lu fsids, but %d is needed ", LOG_TAG_METRICS, (sizeof(metrics->fs_id) / sizeof(metrics->fs_id[0])), STAT_MAX);
global_metrics_destory(metrics);
return NULL;
}
for (int i = 0; i < STAT_MAX; i++)
{
metrics->fs_id[i] = FS_register(metrics->fs_handle, FS_STYLE_FIELD, FS_CALC_CURRENT, stat_map[i]);
}
FS_start(metrics->fs_handle);
return metrics;
}
void global_metrics_destory(struct global_metrics *metrics)
{
if (metrics)
{
FS_library_destroy();
free(metrics);
metrics = NULL;
}
}
void global_metrics_dump(struct global_metrics *metrics)
{
// device_metrics
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_DEVICE_NF_RX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->device.nf_rx.n_pkts)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_DEVICE_NF_RX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->device.nf_rx.n_bytes)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_DEVICE_NF_TX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->device.nf_tx.n_pkts)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_DEVICE_NF_TX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->device.nf_tx.n_bytes)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_DEVICE_ENDPOINT_RX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->device.endpoint_rx.n_pkts)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_DEVICE_ENDPOINT_RX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->device.endpoint_rx.n_bytes)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_DEVICE_ENDPOINT_TX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->device.endpoint_tx.n_pkts)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_DEVICE_ENDPOINT_TX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->device.endpoint_tx.n_bytes)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_DEVICE_ENDPOINT_DROP_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->device.endpoint_drop.n_pkts)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_DEVICE_ENDPOINT_DROP_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->device.endpoint_drop.n_bytes)));
// raw_pkt_metrics
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_MIRR_BYPASS_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.mirr_bypass.n_pkts)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_MIRR_BYPASS_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.mirr_bypass.n_bytes)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_MIRR_BLOCK_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.mirr_block.n_pkts)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_MIRR_BLOCK_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.mirr_block.n_bytes)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_MIRR_RX_DROP_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.mirr_rx_drop.n_pkts)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_MIRR_RX_DROP_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.mirr_rx_drop.n_bytes)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_MIRR_TX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.mirr_tx.n_pkts)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_MIRR_TX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.mirr_tx.n_bytes)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_STEE_BYPASS_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.stee_bypass.n_pkts)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_STEE_BYPASS_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.stee_bypass.n_bytes)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_STEE_BLOCK_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.stee_block.n_pkts)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_STEE_BLOCK_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.stee_block.n_bytes)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_STEE_RX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.stee_rx.n_pkts)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_STEE_RX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.stee_rx.n_bytes)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_STEE_TX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.stee_tx.n_pkts)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_STEE_TX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.stee_tx.n_bytes)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_MISS_SESS_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.miss_sess.n_pkts)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_MISS_SESS_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.miss_sess.n_bytes)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_ERROR_BYPASS_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.error_bypass.n_pkts)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_ERROR_BYPASS_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.error_bypass.n_bytes)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_ERROR_BLOCK_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.error_block.n_pkts)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_RAW_PKT_ERROR_BLOCK_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->raw_pkt.error_block.n_bytes)));
// ctrl_pkt_metrics
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_RX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->ctrl_pkt.rx.n_pkts)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_RX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->ctrl_pkt.rx.n_bytes)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_TX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->ctrl_pkt.tx.n_pkts)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_TX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->ctrl_pkt.tx.n_bytes)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_OPENING], 0, FS_OP_SET, ATOMIC_READ(&(metrics->ctrl_pkt.opening)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_ACTIVE], 0, FS_OP_SET, ATOMIC_READ(&(metrics->ctrl_pkt.active)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_CLOSING], 0, FS_OP_SET, ATOMIC_READ(&(metrics->ctrl_pkt.closing)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_RESETALL], 0, FS_OP_SET, ATOMIC_READ(&(metrics->ctrl_pkt.resetall)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_CTRL_PKT_ERROR], 0, FS_OP_SET, ATOMIC_READ(&(metrics->ctrl_pkt.error)));
// keepalived_pkt_metrics
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_KEE_PKT_DOWN_RX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->kee_pkt.downlink_rx.n_pkts)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_KEE_PKT_DOWN_RX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->kee_pkt.downlink_rx.n_bytes)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_KEE_PKT_DOWN_TX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->kee_pkt.downlink_tx.n_pkts)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_KEE_PKT_DOWN_TX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->kee_pkt.downlink_tx.n_bytes)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_KEE_PKT_UP_RX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->kee_pkt.uplink_rx.n_pkts)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_KEE_PKT_UP_RX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->kee_pkt.uplink_rx.n_bytes)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_KEE_PKT_UP_TX_DROP_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->kee_pkt.uplink_tx_drop.n_pkts)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_KEE_PKT_UP_TX_DROP_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->kee_pkt.uplink_tx_drop.n_bytes)));
// sf_status_metrics
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_SF_STATUS_ACTIVE], 0, FS_OP_SET, ATOMIC_READ(&(metrics->sf_status.active)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_SF_STATUS_INACTIVE], 0, FS_OP_SET, ATOMIC_READ(&(metrics->sf_status.inactive)));
// sf_session_metrics
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_SF_SESSION_NUM], 0, FS_OP_SET, ATOMIC_READ(&(metrics->sf_session.num)));
FS_operate(metrics->fs_handle, metrics->fs_id[STAT_SF_SESSION_LOG], 0, FS_OP_SET, ATOMIC_READ(&(metrics->sf_session.log)));
FS_passive_output(metrics->fs_handle);
}