TSG-13626 tsg-service-chaining-engine发送Metrics
This commit is contained in:
@@ -60,4 +60,4 @@ add_subdirectory(conf)
|
||||
add_subdirectory(vendor)
|
||||
add_subdirectory(common)
|
||||
add_subdirectory(platform)
|
||||
#add_subdirectory(script)
|
||||
add_subdirectory(script)
|
||||
@@ -14,7 +14,9 @@ extern "C"
|
||||
#define LOG_TAG_CTRLPKT "CTRL_PACKET"
|
||||
#define LOG_TAG_STABLE "SESSION_TABLE"
|
||||
#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"
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
[system]
|
||||
nr_worker_threads=8
|
||||
enable_cpu_affinity=0
|
||||
cpu_affinity_mask=2-10
|
||||
firewall_sids=1001
|
||||
|
||||
[maat]
|
||||
@@ -50,6 +52,13 @@ statsd_cycle=2
|
||||
prometheus_listen_port=9001
|
||||
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]
|
||||
path=/var/run/frr/bfdd.vty
|
||||
device=eth0
|
||||
|
||||
@@ -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 pthread)
|
||||
target_link_libraries(platform PUBLIC MESA_prof_load)
|
||||
|
||||
@@ -19,6 +19,7 @@ struct thread_ctx
|
||||
pthread_t tid;
|
||||
int thread_index;
|
||||
struct session_table *session_table;
|
||||
struct sf_metrics *sf_metrics;
|
||||
|
||||
struct packet_io *ref_io;
|
||||
struct global_metrics *ref_metrics;
|
||||
@@ -26,6 +27,7 @@ struct thread_ctx
|
||||
struct sce_ctx *ref_sce_ctx;
|
||||
|
||||
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 "uthash.h"
|
||||
#include "bfd.h"
|
||||
#include "sf_status.h"
|
||||
#include "health_check.h"
|
||||
|
||||
|
||||
@@ -32,6 +33,7 @@ struct session_table
|
||||
};
|
||||
|
||||
static struct session_table g_handle;
|
||||
static struct sf_status *g_sf_status = NULL;
|
||||
|
||||
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", "gateway", gateway_address, sizeof(gateway_address), "127.0.0.1");
|
||||
|
||||
g_sf_status = sf_status_create(profile);
|
||||
// TODO: 循环获取?
|
||||
get_mac_by_addr(gateway_address, default_gw_mac);
|
||||
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)
|
||||
{
|
||||
int is_active = 0;
|
||||
int interval_s = sf_status_get_interval(g_sf_status);
|
||||
struct bfd_vtysh_client client;
|
||||
struct session_iterm *tmp = 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);
|
||||
bfd_vtysh_connect(&client);
|
||||
|
||||
@@ -260,16 +270,45 @@ static void *_health_check_session_foreach(void *arg)
|
||||
node->is_active = is_active;
|
||||
if (node->is_active == 1) {
|
||||
get_mac_by_addr(node->policy.address, node->mac);
|
||||
sf_status_update(g_sf_status, node->session_id, 1, 0);
|
||||
}
|
||||
else {
|
||||
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)
|
||||
sleep_ms = node->policy.interval_ms;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "sce.h"
|
||||
#include "log.h"
|
||||
#include "utils.h"
|
||||
#include "sf_metrics.h"
|
||||
#include "health_check.h"
|
||||
#include "global_metrics.h"
|
||||
|
||||
@@ -45,6 +46,13 @@ static void *worker_thread_cycle(void *arg)
|
||||
session_table_reset(thread_ctx->session_table);
|
||||
__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);
|
||||
@@ -81,11 +89,13 @@ int main(int argc, char **argv)
|
||||
ctx->work_threads[i].tid = 0;
|
||||
ctx->work_threads[i].thread_index = i;
|
||||
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_metrics = ctx->metrics;
|
||||
ctx->work_threads[i].ref_enforcer = ctx->enforcer;
|
||||
ctx->work_threads[i].ref_sce_ctx = ctx;
|
||||
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++)
|
||||
@@ -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)
|
||||
{
|
||||
if (current_time.tv_sec - g_metrics_last_send_time.tv_sec >= ctx->metrics->config.statsd_cycle)
|
||||
{
|
||||
clock_gettime(CLOCK_MONOTONIC, &g_metrics_last_send_time);
|
||||
global_metrics_dump(ctx->metrics);
|
||||
sleep(ctx->metrics->config.statsd_cycle);
|
||||
}
|
||||
|
||||
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:
|
||||
@@ -109,6 +143,7 @@ error_out:
|
||||
{
|
||||
struct thread_ctx *thread_ctx = &ctx->work_threads[i];
|
||||
session_table_destory(thread_ctx->session_table);
|
||||
sf_metrics_destory(thread_ctx->sf_metrics);
|
||||
}
|
||||
sce_ctx_destory(ctx);
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "sce.h"
|
||||
#include "utils.h"
|
||||
#include "g_vxlan.h"
|
||||
#include "sf_metrics.h"
|
||||
#include "ctrl_packet.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);
|
||||
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);
|
||||
*action_bytes = nsend;
|
||||
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);
|
||||
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(&g_metrics->mirroring_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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
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);
|
||||
*action_bytes = nsend;
|
||||
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);
|
||||
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(&g_metrics->mirroring_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 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