TSG-13626 tsg-service-chaining-engine发送Metrics
This commit is contained in:
@@ -60,4 +60,4 @@ add_subdirectory(conf)
|
|||||||
add_subdirectory(vendor)
|
add_subdirectory(vendor)
|
||||||
add_subdirectory(common)
|
add_subdirectory(common)
|
||||||
add_subdirectory(platform)
|
add_subdirectory(platform)
|
||||||
#add_subdirectory(script)
|
add_subdirectory(script)
|
||||||
@@ -14,7 +14,9 @@ extern "C"
|
|||||||
#define LOG_TAG_CTRLPKT "CTRL_PACKET"
|
#define LOG_TAG_CTRLPKT "CTRL_PACKET"
|
||||||
#define LOG_TAG_STABLE "SESSION_TABLE"
|
#define LOG_TAG_STABLE "SESSION_TABLE"
|
||||||
#define LOG_TAG_PKTIO "PACKET_IO"
|
#define LOG_TAG_PKTIO "PACKET_IO"
|
||||||
#define LOG_TAG_METRICS "METRICS"
|
#define LOG_TAG_METRICS "G_METRICS"
|
||||||
|
#define LOG_TAG_SF_METRICS "SF_METRICS"
|
||||||
|
#define LOG_TAG_SF_STATUS "SF_STATUS"
|
||||||
#define LOG_TAG_SCE "SCE"
|
#define LOG_TAG_SCE "SCE"
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
[system]
|
[system]
|
||||||
nr_worker_threads=8
|
nr_worker_threads=8
|
||||||
|
enable_cpu_affinity=0
|
||||||
|
cpu_affinity_mask=2-10
|
||||||
firewall_sids=1001
|
firewall_sids=1001
|
||||||
|
|
||||||
[maat]
|
[maat]
|
||||||
@@ -19,7 +21,7 @@ json_cfg_file=resource/sce.json
|
|||||||
foreign_cont_dir=resource/foreign_files
|
foreign_cont_dir=resource/foreign_files
|
||||||
redis_db_idx=0
|
redis_db_idx=0
|
||||||
redis_server=127.0.0.1
|
redis_server=127.0.0.1
|
||||||
redis_port_range=6379
|
redis_port_range=6379
|
||||||
|
|
||||||
[packet_io]
|
[packet_io]
|
||||||
# bypass_all_traffic:1 NF2NF and SF2SF
|
# bypass_all_traffic:1 NF2NF and SF2SF
|
||||||
@@ -50,8 +52,15 @@ statsd_cycle=2
|
|||||||
prometheus_listen_port=9001
|
prometheus_listen_port=9001
|
||||||
prometheus_listen_url=/sce_prometheus
|
prometheus_listen_url=/sce_prometheus
|
||||||
|
|
||||||
|
[metrics]
|
||||||
|
# Kafka Topic: SERVICE-CHAINING-METRICS
|
||||||
|
enable=1
|
||||||
|
interval_s=1
|
||||||
|
telegraf_bind_address=127.0.0.1
|
||||||
|
telegraf_listen_port=8300
|
||||||
|
|
||||||
[bfdd]
|
[bfdd]
|
||||||
path=/var/run/frr/bfdd.vty
|
path=/var/run/frr/bfdd.vty
|
||||||
device=eth0
|
device=eth0
|
||||||
local_address=127.0.0.1
|
local_address=127.0.0.1
|
||||||
gateway=127.0.0.1
|
gateway=127.0.0.1
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
add_library(platform src/policy.cpp src/health_check.cpp src/sce.cpp src/packet_io.cpp src/global_metrics.cpp)
|
add_library(platform src/policy.cpp src/health_check.cpp src/sce.cpp src/packet_io.cpp src/global_metrics.cpp src/sf_metrics.cpp src/sf_status.cpp)
|
||||||
target_link_libraries(platform PUBLIC common)
|
target_link_libraries(platform PUBLIC common)
|
||||||
target_link_libraries(platform PUBLIC pthread)
|
target_link_libraries(platform PUBLIC pthread)
|
||||||
target_link_libraries(platform PUBLIC MESA_prof_load)
|
target_link_libraries(platform PUBLIC MESA_prof_load)
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ struct thread_ctx
|
|||||||
pthread_t tid;
|
pthread_t tid;
|
||||||
int thread_index;
|
int thread_index;
|
||||||
struct session_table *session_table;
|
struct session_table *session_table;
|
||||||
|
struct sf_metrics *sf_metrics;
|
||||||
|
|
||||||
struct packet_io *ref_io;
|
struct packet_io *ref_io;
|
||||||
struct global_metrics *ref_metrics;
|
struct global_metrics *ref_metrics;
|
||||||
@@ -26,6 +27,7 @@ struct thread_ctx
|
|||||||
struct sce_ctx *ref_sce_ctx;
|
struct sce_ctx *ref_sce_ctx;
|
||||||
|
|
||||||
int session_table_need_reset;
|
int session_table_need_reset;
|
||||||
|
int sf_metrics_need_send;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
|||||||
24
platform/include/sf_metrics.h
Normal file
24
platform/include/sf_metrics.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef _SF_METRICS_H
|
||||||
|
#define _SF_METRICS_H
|
||||||
|
|
||||||
|
#ifdef __cpluscplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "uthash.h"
|
||||||
|
|
||||||
|
struct sf_metrics *sf_metrics_create(const char *profile);
|
||||||
|
void sf_metrics_destory(struct sf_metrics *handle);
|
||||||
|
void sf_metrics_reset(struct sf_metrics *handle);
|
||||||
|
|
||||||
|
void sf_metrics_inc(struct sf_metrics *handle, int rule_id, int sff_profile_id, int sf_profile_id, uint64_t rx_pkts, uint64_t rx_bytes, uint64_t tx_pkts, uint64_t tx_bytes);
|
||||||
|
void sf_metrics_send(struct sf_metrics *handle);
|
||||||
|
int sf_metrics_get_interval(struct sf_metrics *handle);
|
||||||
|
|
||||||
|
#ifdef __cpluscplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
24
platform/include/sf_status.h
Normal file
24
platform/include/sf_status.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef _SF_STATUS_H
|
||||||
|
#define _SF_STATUS_H
|
||||||
|
|
||||||
|
#ifdef __cpluscplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "uthash.h"
|
||||||
|
|
||||||
|
struct sf_status *sf_status_create(const char *profile);
|
||||||
|
void sf_status_destory(struct sf_status *handle);
|
||||||
|
void sf_status_reset(struct sf_status *handle);
|
||||||
|
|
||||||
|
void sf_status_update(struct sf_status *handle, int sf_profile_id, int sf_status, int sf_latency);
|
||||||
|
void sf_status_send(struct sf_status *handle);
|
||||||
|
int sf_status_get_interval(struct sf_status *handle);
|
||||||
|
|
||||||
|
#ifdef __cpluscplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "uthash.h"
|
#include "uthash.h"
|
||||||
#include "bfd.h"
|
#include "bfd.h"
|
||||||
|
#include "sf_status.h"
|
||||||
#include "health_check.h"
|
#include "health_check.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -32,6 +33,7 @@ struct session_table
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct session_table g_handle;
|
static struct session_table g_handle;
|
||||||
|
static struct sf_status *g_sf_status = NULL;
|
||||||
|
|
||||||
struct session_iterm
|
struct session_iterm
|
||||||
{
|
{
|
||||||
@@ -72,6 +74,7 @@ void health_check_session_init(const char *profile)
|
|||||||
MESA_load_profile_string_def(profile, "bfdd", "local_address", local_address, sizeof(local_address), "127.0.0.1");
|
MESA_load_profile_string_def(profile, "bfdd", "local_address", local_address, sizeof(local_address), "127.0.0.1");
|
||||||
MESA_load_profile_string_def(profile, "bfdd", "gateway", gateway_address, sizeof(gateway_address), "127.0.0.1");
|
MESA_load_profile_string_def(profile, "bfdd", "gateway", gateway_address, sizeof(gateway_address), "127.0.0.1");
|
||||||
|
|
||||||
|
g_sf_status = sf_status_create(profile);
|
||||||
// TODO: 循环获取?
|
// TODO: 循环获取?
|
||||||
get_mac_by_addr(gateway_address, default_gw_mac);
|
get_mac_by_addr(gateway_address, default_gw_mac);
|
||||||
health_check_session_foreach();
|
health_check_session_foreach();
|
||||||
@@ -239,10 +242,17 @@ static int get_mac_by_addr(char *addr, uint8_t *buf)
|
|||||||
static void *_health_check_session_foreach(void *arg)
|
static void *_health_check_session_foreach(void *arg)
|
||||||
{
|
{
|
||||||
int is_active = 0;
|
int is_active = 0;
|
||||||
|
int interval_s = sf_status_get_interval(g_sf_status);
|
||||||
struct bfd_vtysh_client client;
|
struct bfd_vtysh_client client;
|
||||||
struct session_iterm *tmp = NULL;
|
struct session_iterm *tmp = NULL;
|
||||||
struct session_iterm *node = NULL;
|
struct session_iterm *node = NULL;
|
||||||
|
|
||||||
|
struct timespec current_time;
|
||||||
|
struct timespec g_status_last_send_time;
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, ¤t_time);
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &g_status_last_send_time);
|
||||||
|
|
||||||
health_check_session_init_bfd_client(&client);
|
health_check_session_init_bfd_client(&client);
|
||||||
bfd_vtysh_connect(&client);
|
bfd_vtysh_connect(&client);
|
||||||
|
|
||||||
@@ -260,16 +270,45 @@ static void *_health_check_session_foreach(void *arg)
|
|||||||
node->is_active = is_active;
|
node->is_active = is_active;
|
||||||
if (node->is_active == 1) {
|
if (node->is_active == 1) {
|
||||||
get_mac_by_addr(node->policy.address, node->mac);
|
get_mac_by_addr(node->policy.address, node->mac);
|
||||||
|
sf_status_update(g_sf_status, node->session_id, 1, 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
memset(node->mac, 0, sizeof(node->mac));
|
memset(node->mac, 0, sizeof(node->mac));
|
||||||
|
sf_status_update(g_sf_status, node->session_id, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sleep_ms > node->policy.interval_ms)
|
if (sleep_ms > node->policy.interval_ms)
|
||||||
sleep_ms = node->policy.interval_ms;
|
sleep_ms = node->policy.interval_ms;
|
||||||
}
|
}
|
||||||
pthread_rwlock_unlock(&g_handle.rwlock);
|
pthread_rwlock_unlock(&g_handle.rwlock);
|
||||||
usleep(sleep_ms*1000);
|
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, ¤t_time);
|
||||||
|
if (current_time.tv_sec - g_status_last_send_time.tv_sec >= interval_s)
|
||||||
|
{
|
||||||
|
sf_status_send(g_sf_status);
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &g_status_last_send_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
// interval_s : 1000 ms
|
||||||
|
// sleep_ms : 900 ms
|
||||||
|
if (interval_s * 1000 > sleep_ms)
|
||||||
|
{
|
||||||
|
usleep(sleep_ms * 1000);
|
||||||
|
}
|
||||||
|
// interval_s : 900 ms
|
||||||
|
// sleep_ms : 1000 ms
|
||||||
|
else
|
||||||
|
{
|
||||||
|
usleep(interval_s * 1000 * 1000);
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, ¤t_time);
|
||||||
|
if (current_time.tv_sec - g_status_last_send_time.tv_sec >= interval_s)
|
||||||
|
{
|
||||||
|
sf_status_send(g_sf_status);
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &g_status_last_send_time);
|
||||||
|
}
|
||||||
|
usleep(sleep_ms * 1000 - interval_s * 1000 * 1000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bfd_vtysh_close(&client);
|
bfd_vtysh_close(&client);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "sce.h"
|
#include "sce.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "sf_metrics.h"
|
||||||
#include "health_check.h"
|
#include "health_check.h"
|
||||||
#include "global_metrics.h"
|
#include "global_metrics.h"
|
||||||
|
|
||||||
@@ -45,6 +46,13 @@ static void *worker_thread_cycle(void *arg)
|
|||||||
session_table_reset(thread_ctx->session_table);
|
session_table_reset(thread_ctx->session_table);
|
||||||
__atomic_fetch_and(&thread_ctx->session_table_need_reset, 0, __ATOMIC_RELAXED);
|
__atomic_fetch_and(&thread_ctx->session_table_need_reset, 0, __ATOMIC_RELAXED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (__atomic_fetch_add(&thread_ctx->sf_metrics_need_send, 0, __ATOMIC_RELAXED) > 0)
|
||||||
|
{
|
||||||
|
sf_metrics_send(thread_ctx->sf_metrics);
|
||||||
|
sf_metrics_reset(thread_ctx->sf_metrics);
|
||||||
|
__atomic_fetch_and(&thread_ctx->sf_metrics_need_send, 0, __ATOMIC_RELAXED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_ERROR("%s: worker thread %d exiting", LOG_TAG_SCE, thread_ctx->thread_index);
|
LOG_ERROR("%s: worker thread %d exiting", LOG_TAG_SCE, thread_ctx->thread_index);
|
||||||
@@ -81,11 +89,13 @@ int main(int argc, char **argv)
|
|||||||
ctx->work_threads[i].tid = 0;
|
ctx->work_threads[i].tid = 0;
|
||||||
ctx->work_threads[i].thread_index = i;
|
ctx->work_threads[i].thread_index = i;
|
||||||
ctx->work_threads[i].session_table = session_table_create();
|
ctx->work_threads[i].session_table = session_table_create();
|
||||||
|
ctx->work_threads[i].sf_metrics = sf_metrics_create(profile);
|
||||||
ctx->work_threads[i].ref_io = ctx->io;
|
ctx->work_threads[i].ref_io = ctx->io;
|
||||||
ctx->work_threads[i].ref_metrics = ctx->metrics;
|
ctx->work_threads[i].ref_metrics = ctx->metrics;
|
||||||
ctx->work_threads[i].ref_enforcer = ctx->enforcer;
|
ctx->work_threads[i].ref_enforcer = ctx->enforcer;
|
||||||
ctx->work_threads[i].ref_sce_ctx = ctx;
|
ctx->work_threads[i].ref_sce_ctx = ctx;
|
||||||
ctx->work_threads[i].session_table_need_reset = 0;
|
ctx->work_threads[i].session_table_need_reset = 0;
|
||||||
|
ctx->work_threads[i].sf_metrics_need_send = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < ctx->nr_worker_threads; i++)
|
for (int i = 0; i < ctx->nr_worker_threads; i++)
|
||||||
@@ -98,10 +108,34 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct timespec current_time;
|
||||||
|
struct timespec g_metrics_last_send_time;
|
||||||
|
struct timespec sf_metrics_last_send_time;
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, ¤t_time);
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &g_metrics_last_send_time);
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &sf_metrics_last_send_time);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
global_metrics_dump(ctx->metrics);
|
if (current_time.tv_sec - g_metrics_last_send_time.tv_sec >= ctx->metrics->config.statsd_cycle)
|
||||||
sleep(ctx->metrics->config.statsd_cycle);
|
{
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &g_metrics_last_send_time);
|
||||||
|
global_metrics_dump(ctx->metrics);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_time.tv_sec - sf_metrics_last_send_time.tv_sec >= sf_metrics_get_interval(ctx->work_threads[0].sf_metrics))
|
||||||
|
{
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &sf_metrics_last_send_time);
|
||||||
|
for (int i = 0; i < ctx->nr_worker_threads; i++)
|
||||||
|
{
|
||||||
|
struct thread_ctx *thread_ctx = &ctx->work_threads[i];
|
||||||
|
__atomic_fetch_add(&thread_ctx->sf_metrics_need_send, 1, __ATOMIC_RELAXED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(MIN(ctx->metrics->config.statsd_cycle, sf_metrics_get_interval(ctx->work_threads[0].sf_metrics)));
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, ¤t_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
error_out:
|
error_out:
|
||||||
@@ -109,6 +143,7 @@ error_out:
|
|||||||
{
|
{
|
||||||
struct thread_ctx *thread_ctx = &ctx->work_threads[i];
|
struct thread_ctx *thread_ctx = &ctx->work_threads[i];
|
||||||
session_table_destory(thread_ctx->session_table);
|
session_table_destory(thread_ctx->session_table);
|
||||||
|
sf_metrics_destory(thread_ctx->sf_metrics);
|
||||||
}
|
}
|
||||||
sce_ctx_destory(ctx);
|
sce_ctx_destory(ctx);
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "sce.h"
|
#include "sce.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "g_vxlan.h"
|
#include "g_vxlan.h"
|
||||||
|
#include "sf_metrics.h"
|
||||||
#include "ctrl_packet.h"
|
#include "ctrl_packet.h"
|
||||||
#include "global_metrics.h"
|
#include "global_metrics.h"
|
||||||
|
|
||||||
@@ -839,6 +840,7 @@ static enum raw_pkt_action handle_raw_packet(struct packet_io *handle, marsio_bu
|
|||||||
nsend = forward_packet_to_sf(handle, rx_buff, &meta, node, thread_seq, ctx);
|
nsend = forward_packet_to_sf(handle, rx_buff, &meta, node, thread_seq, ctx);
|
||||||
if (nsend > 0)
|
if (nsend > 0)
|
||||||
{
|
{
|
||||||
|
sf_metrics_inc(thread->sf_metrics, node->policy_id, node->sff_profile_id, node->sf_profile_id, 0, 0, 1, nsend);
|
||||||
throughput_metrics_inc(&node->tx, 1, nsend);
|
throughput_metrics_inc(&node->tx, 1, nsend);
|
||||||
*action_bytes = nsend;
|
*action_bytes = nsend;
|
||||||
return RAW_PKT_HIT_FORWARD;
|
return RAW_PKT_HIT_FORWARD;
|
||||||
@@ -859,6 +861,7 @@ static enum raw_pkt_action handle_raw_packet(struct packet_io *handle, marsio_bu
|
|||||||
nsend = mirror_packet_to_sf(handle, rx_buff, &meta, node, thread_seq, ctx);
|
nsend = mirror_packet_to_sf(handle, rx_buff, &meta, node, thread_seq, ctx);
|
||||||
if (nsend > 0)
|
if (nsend > 0)
|
||||||
{
|
{
|
||||||
|
sf_metrics_inc(thread->sf_metrics, node->policy_id, node->sff_profile_id, node->sf_profile_id, 0, 0, 1, nsend);
|
||||||
throughput_metrics_inc(&node->tx, 1, nsend);
|
throughput_metrics_inc(&node->tx, 1, nsend);
|
||||||
throughput_metrics_inc(&g_metrics->mirroring_tx, 1, nsend);
|
throughput_metrics_inc(&g_metrics->mirroring_tx, 1, nsend);
|
||||||
throughput_metrics_inc(&g_metrics->dev_endpoint_tx, 1, nsend);
|
throughput_metrics_inc(&g_metrics->dev_endpoint_tx, 1, nsend);
|
||||||
@@ -969,6 +972,7 @@ static enum inject_pkt_action handle_inject_packet(struct packet_io *handle, mar
|
|||||||
return INJT_PKT_MIRR_RX_DROP;
|
return INJT_PKT_MIRR_RX_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sf_metrics_inc(thread->sf_metrics, chaining->chaining[sf_index].policy_id, chaining->chaining[sf_index].sff_profile_id, chaining->chaining[sf_index].sf_profile_id, 1, raw_len, 0, 0);
|
||||||
throughput_metrics_inc(&chaining->chaining[sf_index].rx, 1, raw_len);
|
throughput_metrics_inc(&chaining->chaining[sf_index].rx, 1, raw_len);
|
||||||
|
|
||||||
int next_sf_index;
|
int next_sf_index;
|
||||||
@@ -1016,6 +1020,7 @@ static enum inject_pkt_action handle_inject_packet(struct packet_io *handle, mar
|
|||||||
nsend = forward_packet_to_sf(handle, rx_buff, &meta, node, thread_seq, ctx);
|
nsend = forward_packet_to_sf(handle, rx_buff, &meta, node, thread_seq, ctx);
|
||||||
if (nsend > 0)
|
if (nsend > 0)
|
||||||
{
|
{
|
||||||
|
sf_metrics_inc(thread->sf_metrics, node->policy_id, node->sff_profile_id, node->sf_profile_id, 0, 0, 1, nsend);
|
||||||
throughput_metrics_inc(&node->tx, 1, nsend);
|
throughput_metrics_inc(&node->tx, 1, nsend);
|
||||||
*action_bytes = nsend;
|
*action_bytes = nsend;
|
||||||
return INJT_PKT_HIT_FWD2SF;
|
return INJT_PKT_HIT_FWD2SF;
|
||||||
@@ -1036,6 +1041,7 @@ static enum inject_pkt_action handle_inject_packet(struct packet_io *handle, mar
|
|||||||
nsend = mirror_packet_to_sf(handle, rx_buff, &meta, node, thread_seq, ctx);
|
nsend = mirror_packet_to_sf(handle, rx_buff, &meta, node, thread_seq, ctx);
|
||||||
if (nsend > 0)
|
if (nsend > 0)
|
||||||
{
|
{
|
||||||
|
sf_metrics_inc(thread->sf_metrics, node->policy_id, node->sff_profile_id, node->sf_profile_id, 0, 0, 1, nsend);
|
||||||
throughput_metrics_inc(&node->tx, 1, nsend);
|
throughput_metrics_inc(&node->tx, 1, nsend);
|
||||||
throughput_metrics_inc(&g_metrics->mirroring_tx, 1, nsend);
|
throughput_metrics_inc(&g_metrics->mirroring_tx, 1, nsend);
|
||||||
throughput_metrics_inc(&g_metrics->dev_endpoint_tx, 1, nsend);
|
throughput_metrics_inc(&g_metrics->dev_endpoint_tx, 1, nsend);
|
||||||
|
|||||||
214
platform/src/sf_metrics.cpp
Normal file
214
platform/src/sf_metrics.cpp
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <MESA/MESA_prof_load.h>
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "sf_metrics.h"
|
||||||
|
|
||||||
|
#define SCE_SF_METRICS "SCE-SF-METRICS,rule_id=%d,sff_profile_id=%d,sf_profile_id=%d,type=service_chaining_metrics sent_pkts=%lu,sent_bytes=%lu,recv_pkts=%lu,recv_bytes=%lu"
|
||||||
|
|
||||||
|
struct key_tuple
|
||||||
|
{
|
||||||
|
int rule_id;
|
||||||
|
int sff_profile_id;
|
||||||
|
int sf_profile_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct node
|
||||||
|
{
|
||||||
|
struct key_tuple key;
|
||||||
|
uint64_t sent_pkts;
|
||||||
|
uint64_t sent_bytes;
|
||||||
|
uint64_t recv_pkts;
|
||||||
|
uint64_t recv_bytes;
|
||||||
|
|
||||||
|
UT_hash_handle hh;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sf_metrics_config
|
||||||
|
{
|
||||||
|
int enable;
|
||||||
|
int interval_s;
|
||||||
|
int telegraf_listen_port;
|
||||||
|
char telegraf_bind_address[2048];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sf_metrics
|
||||||
|
{
|
||||||
|
struct sf_metrics_config config;
|
||||||
|
struct sockaddr_in sock_addr;
|
||||||
|
int sockfd;
|
||||||
|
|
||||||
|
struct node *htable;
|
||||||
|
uint64_t htable_elem_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void sf_metrics_parse_config(const char *profile, struct sf_metrics_config *config)
|
||||||
|
{
|
||||||
|
MESA_load_profile_int_def(profile, "METRICS", "enable", &(config->enable), 1);
|
||||||
|
MESA_load_profile_int_def(profile, "METRICS", "interval_s", &(config->interval_s), 1);
|
||||||
|
MESA_load_profile_int_def(profile, "METRICS", "telegraf_listen_port", &(config->telegraf_listen_port), 8300);
|
||||||
|
MESA_load_profile_string_def(profile, "METRICS", "telegraf_bind_address", config->telegraf_bind_address, sizeof(config->telegraf_bind_address), "127.0.0.1");
|
||||||
|
|
||||||
|
LOG_DEBUG("%s: METRICS->enable : %d", LOG_TAG_SF_METRICS, config->enable);
|
||||||
|
LOG_DEBUG("%s: METRICS->interval_s : %d", LOG_TAG_SF_METRICS, config->interval_s);
|
||||||
|
LOG_DEBUG("%s: METRICS->telegraf_listen_port : %d", LOG_TAG_SF_METRICS, config->telegraf_listen_port);
|
||||||
|
LOG_DEBUG("%s: METRICS->telegraf_bind_address : %s", LOG_TAG_SF_METRICS, config->telegraf_bind_address);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sf_metrics *sf_metrics_create(const char *profile)
|
||||||
|
{
|
||||||
|
struct sf_metrics *handle = (struct sf_metrics *)calloc(1, sizeof(struct sf_metrics));
|
||||||
|
assert(handle);
|
||||||
|
sf_metrics_parse_config(profile, &(handle->config));
|
||||||
|
|
||||||
|
if (handle->config.enable == 0)
|
||||||
|
{
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle->sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
handle->sock_addr.sin_family = AF_INET;
|
||||||
|
handle->sock_addr.sin_port = htons(handle->config.telegraf_listen_port);
|
||||||
|
handle->sock_addr.sin_addr.s_addr = inet_addr(handle->config.telegraf_bind_address);
|
||||||
|
handle->htable_elem_count = 0;
|
||||||
|
if (handle->sockfd == -1)
|
||||||
|
{
|
||||||
|
LOG_ERROR("%s: failed to create udp sockfd %s:%d, errno: %d, %s", LOG_TAG_SF_METRICS, handle->config.telegraf_bind_address, handle->config.telegraf_listen_port, errno, strerror(errno));
|
||||||
|
sf_metrics_destory(handle);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sf_metrics_destory(struct sf_metrics *handle)
|
||||||
|
{
|
||||||
|
if (handle)
|
||||||
|
{
|
||||||
|
if (handle->sockfd)
|
||||||
|
{
|
||||||
|
close(handle->sockfd);
|
||||||
|
handle->sockfd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct node *temp = NULL;
|
||||||
|
struct node *node = NULL;
|
||||||
|
HASH_ITER(hh, handle->htable, node, temp)
|
||||||
|
{
|
||||||
|
HASH_DELETE(hh, handle->htable, node);
|
||||||
|
|
||||||
|
free(node);
|
||||||
|
node = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle->htable_elem_count = 0;
|
||||||
|
free(handle);
|
||||||
|
handle = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sf_metrics_reset(struct sf_metrics *handle)
|
||||||
|
{
|
||||||
|
if (handle == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handle->config.enable == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct node *temp = NULL;
|
||||||
|
struct node *node = NULL;
|
||||||
|
HASH_ITER(hh, handle->htable, node, temp)
|
||||||
|
{
|
||||||
|
HASH_DELETE(hh, handle->htable, node);
|
||||||
|
|
||||||
|
free(node);
|
||||||
|
node = NULL;
|
||||||
|
handle->htable_elem_count--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sf_metrics_inc(struct sf_metrics *handle, int rule_id, int sff_profile_id, int sf_profile_id, uint64_t rx_pkts, uint64_t rx_bytes, uint64_t tx_pkts, uint64_t tx_bytes)
|
||||||
|
{
|
||||||
|
if (handle->config.enable == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct key_tuple key;
|
||||||
|
memset(&key, 0, sizeof(struct key_tuple));
|
||||||
|
key.rule_id = rule_id;
|
||||||
|
key.sff_profile_id = sff_profile_id;
|
||||||
|
key.sf_profile_id = sf_profile_id;
|
||||||
|
|
||||||
|
struct node *temp = NULL;
|
||||||
|
HASH_FIND(hh, handle->htable, &key, sizeof(struct key_tuple), temp);
|
||||||
|
if (temp)
|
||||||
|
{
|
||||||
|
temp->recv_pkts += rx_pkts;
|
||||||
|
temp->recv_bytes += rx_bytes;
|
||||||
|
temp->sent_pkts += tx_pkts;
|
||||||
|
temp->sent_bytes += tx_bytes;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
temp = (struct node *)calloc(1, sizeof(struct node));
|
||||||
|
temp->key.rule_id = rule_id;
|
||||||
|
temp->key.sff_profile_id = sff_profile_id;
|
||||||
|
temp->key.sf_profile_id = sf_profile_id;
|
||||||
|
temp->recv_pkts = rx_pkts;
|
||||||
|
temp->recv_bytes = rx_bytes;
|
||||||
|
temp->sent_pkts = tx_pkts;
|
||||||
|
temp->sent_bytes = tx_bytes;
|
||||||
|
|
||||||
|
HASH_ADD(hh, handle->htable, key, sizeof(struct key_tuple), temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sf_metrics_send(struct sf_metrics *handle)
|
||||||
|
{
|
||||||
|
char buff[2048];
|
||||||
|
int nsend = 0;
|
||||||
|
int size = sizeof(buff);
|
||||||
|
|
||||||
|
struct node *temp = NULL;
|
||||||
|
struct node *node = NULL;
|
||||||
|
|
||||||
|
if (handle->config.enable == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
HASH_ITER(hh, handle->htable, node, temp)
|
||||||
|
{
|
||||||
|
if (node->sent_pkts == 0 && node->recv_pkts == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(buff, 0, size);
|
||||||
|
nsend = snprintf(buff, size, SCE_SF_METRICS,
|
||||||
|
node->key.rule_id,
|
||||||
|
node->key.sff_profile_id,
|
||||||
|
node->key.sf_profile_id,
|
||||||
|
node->sent_pkts,
|
||||||
|
node->sent_bytes,
|
||||||
|
node->recv_pkts,
|
||||||
|
node->recv_bytes);
|
||||||
|
sendto(handle->sockfd, buff, nsend, 0, (struct sockaddr *)&handle->sock_addr, sizeof(handle->sock_addr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int sf_metrics_get_interval(struct sf_metrics *handle)
|
||||||
|
{
|
||||||
|
return handle->config.interval_s;
|
||||||
|
}
|
||||||
183
platform/src/sf_status.cpp
Normal file
183
platform/src/sf_status.cpp
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
#include <errno.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <MESA/MESA_prof_load.h>
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "sf_status.h"
|
||||||
|
|
||||||
|
#define SCE_SF_STATUS "SCE-SF-STATUS,sf_profile_id=%d,type=service_function_status sf_status=%d,sf_latency=%d"
|
||||||
|
|
||||||
|
struct node
|
||||||
|
{
|
||||||
|
int sf_profile_id;
|
||||||
|
int sf_status;
|
||||||
|
int sf_latency;
|
||||||
|
|
||||||
|
UT_hash_handle hh;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sf_status_config
|
||||||
|
{
|
||||||
|
int enable;
|
||||||
|
int interval_s;
|
||||||
|
int telegraf_listen_port;
|
||||||
|
char telegraf_bind_address[2048];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sf_status
|
||||||
|
{
|
||||||
|
struct sf_status_config config;
|
||||||
|
struct sockaddr_in sock_addr;
|
||||||
|
int sockfd;
|
||||||
|
|
||||||
|
struct node *htable;
|
||||||
|
uint64_t htable_elem_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void sf_status_parse_config(const char *profile, struct sf_status_config *config)
|
||||||
|
{
|
||||||
|
MESA_load_profile_int_def(profile, "METRICS", "enable", &(config->enable), 1);
|
||||||
|
MESA_load_profile_int_def(profile, "METRICS", "interval_s", &(config->interval_s), 1);
|
||||||
|
MESA_load_profile_int_def(profile, "METRICS", "telegraf_listen_port", &(config->telegraf_listen_port), 8300);
|
||||||
|
MESA_load_profile_string_def(profile, "METRICS", "telegraf_bind_address", config->telegraf_bind_address, sizeof(config->telegraf_bind_address), "127.0.0.1");
|
||||||
|
|
||||||
|
LOG_DEBUG("%s: METRICS->enable : %d", LOG_TAG_SF_STATUS, config->enable);
|
||||||
|
LOG_DEBUG("%s: METRICS->interval_s : %d", LOG_TAG_SF_STATUS, config->interval_s);
|
||||||
|
LOG_DEBUG("%s: METRICS->telegraf_listen_port : %d", LOG_TAG_SF_STATUS, config->telegraf_listen_port);
|
||||||
|
LOG_DEBUG("%s: METRICS->telegraf_bind_address : %s", LOG_TAG_SF_STATUS, config->telegraf_bind_address);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sf_status_destory(struct sf_status *handle)
|
||||||
|
{
|
||||||
|
if (handle)
|
||||||
|
{
|
||||||
|
if (handle->sockfd)
|
||||||
|
{
|
||||||
|
close(handle->sockfd);
|
||||||
|
handle->sockfd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct node *temp = NULL;
|
||||||
|
struct node *node = NULL;
|
||||||
|
HASH_ITER(hh, handle->htable, node, temp)
|
||||||
|
{
|
||||||
|
HASH_DELETE(hh, handle->htable, node);
|
||||||
|
free(node);
|
||||||
|
node = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle->htable_elem_count = 0;
|
||||||
|
free(handle);
|
||||||
|
handle = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sf_status *sf_status_create(const char *profile)
|
||||||
|
{
|
||||||
|
struct sf_status *handle = (struct sf_status *)calloc(1, sizeof(struct sf_status));
|
||||||
|
assert(handle);
|
||||||
|
sf_status_parse_config(profile, &(handle->config));
|
||||||
|
|
||||||
|
if (handle->config.enable == 0)
|
||||||
|
{
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle->sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
handle->sock_addr.sin_family = AF_INET;
|
||||||
|
handle->sock_addr.sin_port = htons(handle->config.telegraf_listen_port);
|
||||||
|
handle->sock_addr.sin_addr.s_addr = inet_addr(handle->config.telegraf_bind_address);
|
||||||
|
handle->htable_elem_count = 0;
|
||||||
|
if (handle->sockfd == -1)
|
||||||
|
{
|
||||||
|
LOG_ERROR("%s: failed to create udp sockfd %s:%d, errno: %d, %s", LOG_TAG_SF_STATUS, handle->config.telegraf_bind_address, handle->config.telegraf_listen_port, errno, strerror(errno));
|
||||||
|
sf_status_destory(handle);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sf_status_reset(struct sf_status *handle)
|
||||||
|
{
|
||||||
|
if (handle == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handle->config.enable == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct node *temp = NULL;
|
||||||
|
struct node *node = NULL;
|
||||||
|
HASH_ITER(hh, handle->htable, node, temp)
|
||||||
|
{
|
||||||
|
HASH_DELETE(hh, handle->htable, node);
|
||||||
|
|
||||||
|
free(node);
|
||||||
|
node = NULL;
|
||||||
|
handle->htable_elem_count--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sf_status_update(struct sf_status *handle, int sf_profile_id, int sf_status, int sf_latency)
|
||||||
|
{
|
||||||
|
if (handle->config.enable == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct node *temp = NULL;
|
||||||
|
HASH_FIND(hh, handle->htable, &sf_profile_id, sizeof(sf_profile_id), temp);
|
||||||
|
if (temp)
|
||||||
|
{
|
||||||
|
temp->sf_profile_id = sf_profile_id;
|
||||||
|
temp->sf_status = sf_status;
|
||||||
|
temp->sf_latency = sf_latency;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
temp = (struct node *)calloc(1, sizeof(struct node));
|
||||||
|
temp->sf_profile_id = sf_profile_id;
|
||||||
|
temp->sf_status = sf_status;
|
||||||
|
temp->sf_latency = sf_latency;
|
||||||
|
|
||||||
|
HASH_ADD(hh, handle->htable, sf_profile_id, sizeof(sf_profile_id), temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sf_status_send(struct sf_status *handle)
|
||||||
|
{
|
||||||
|
char buff[2048];
|
||||||
|
int nsend = 0;
|
||||||
|
int size = sizeof(buff);
|
||||||
|
|
||||||
|
struct node *temp = NULL;
|
||||||
|
struct node *node = NULL;
|
||||||
|
|
||||||
|
if (handle->config.enable == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
HASH_ITER(hh, handle->htable, node, temp)
|
||||||
|
{
|
||||||
|
memset(buff, 0, size);
|
||||||
|
nsend = snprintf(buff, size, SCE_SF_STATUS,
|
||||||
|
node->sf_profile_id,
|
||||||
|
node->sf_status,
|
||||||
|
node->sf_latency);
|
||||||
|
sendto(handle->sockfd, buff, nsend, 0, (struct sockaddr *)&handle->sock_addr, sizeof(handle->sock_addr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int sf_status_get_interval(struct sf_status *handle)
|
||||||
|
{
|
||||||
|
return handle->config.interval_s;
|
||||||
|
}
|
||||||
@@ -1 +1,2 @@
|
|||||||
install(FILES service/sce.service DESTINATION /usr/lib/systemd/system/ COMPONENT Program)
|
install(FILES service/sce.service DESTINATION /usr/lib/systemd/system/ COMPONENT Program)
|
||||||
|
install(FILES tmpfiles/sce.conf DESTINATION /usr/lib/tmpfiles.d/ COMPONENT Profile)
|
||||||
6
script/tmpfiles/sce.conf
Normal file
6
script/tmpfiles/sce.conf
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#Type Path Mode User Group Age Argument
|
||||||
|
d /var/log/sce/ 0755 - - 2d -
|
||||||
|
d /run/sce/crashreport 0755 - - 30d -
|
||||||
|
d /run/sce/rulescan_tmp 0755 - - - -
|
||||||
|
L /opt/tsg/sce/log - - - - /var/log/sce
|
||||||
|
L /opt/tsg/sce/rulescan_tmp - - - - /run/sce/rulescan_tmp
|
||||||
Reference in New Issue
Block a user