diff --git a/CMakeLists.txt b/CMakeLists.txt index 80cc624..ed1e117 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,4 +60,4 @@ add_subdirectory(conf) add_subdirectory(vendor) add_subdirectory(common) add_subdirectory(platform) -#add_subdirectory(script) \ No newline at end of file +add_subdirectory(script) \ No newline at end of file diff --git a/common/include/utils.h b/common/include/utils.h index 740afd3..77a5951 100644 --- a/common/include/utils.h +++ b/common/include/utils.h @@ -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" /****************************************************************************** diff --git a/conf/sce.conf b/conf/sce.conf index 15f2429..63f0ba5 100644 --- a/conf/sce.conf +++ b/conf/sce.conf @@ -1,5 +1,7 @@ [system] nr_worker_threads=8 +enable_cpu_affinity=0 +cpu_affinity_mask=2-10 firewall_sids=1001 [maat] @@ -19,7 +21,7 @@ json_cfg_file=resource/sce.json foreign_cont_dir=resource/foreign_files redis_db_idx=0 redis_server=127.0.0.1 -redis_port_range=6379 +redis_port_range=6379 [packet_io] # bypass_all_traffic:1 NF2NF and SF2SF @@ -50,8 +52,15 @@ 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 local_address=127.0.0.1 -gateway=127.0.0.1 +gateway=127.0.0.1 \ No newline at end of file diff --git a/platform/CMakeLists.txt b/platform/CMakeLists.txt index 496ca38..cff1224 100644 --- a/platform/CMakeLists.txt +++ b/platform/CMakeLists.txt @@ -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) diff --git a/platform/include/sce.h b/platform/include/sce.h index aad8c73..60b1764 100644 --- a/platform/include/sce.h +++ b/platform/include/sce.h @@ -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; }; /****************************************************************************** diff --git a/platform/include/sf_metrics.h b/platform/include/sf_metrics.h new file mode 100644 index 0000000..1a3a814 --- /dev/null +++ b/platform/include/sf_metrics.h @@ -0,0 +1,24 @@ +#ifndef _SF_METRICS_H +#define _SF_METRICS_H + +#ifdef __cpluscplus +extern "C" +{ +#endif + +#include +#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 diff --git a/platform/include/sf_status.h b/platform/include/sf_status.h new file mode 100644 index 0000000..1f72b25 --- /dev/null +++ b/platform/include/sf_status.h @@ -0,0 +1,24 @@ +#ifndef _SF_STATUS_H +#define _SF_STATUS_H + +#ifdef __cpluscplus +extern "C" +{ +#endif + +#include +#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 diff --git a/platform/src/health_check.cpp b/platform/src/health_check.cpp index f45733a..3f3647f 100644 --- a/platform/src/health_check.cpp +++ b/platform/src/health_check.cpp @@ -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); } diff --git a/platform/src/main.cpp b/platform/src/main.cpp index 9e58fc0..2643bb7 100644 --- a/platform/src/main.cpp +++ b/platform/src/main.cpp @@ -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) { - global_metrics_dump(ctx->metrics); - sleep(ctx->metrics->config.statsd_cycle); + 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); + } + + 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); diff --git a/platform/src/packet_io.cpp b/platform/src/packet_io.cpp index 054397c..2b60aec 100644 --- a/platform/src/packet_io.cpp +++ b/platform/src/packet_io.cpp @@ -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); diff --git a/platform/src/sf_metrics.cpp b/platform/src/sf_metrics.cpp new file mode 100644 index 0000000..0a858d5 --- /dev/null +++ b/platform/src/sf_metrics.cpp @@ -0,0 +1,214 @@ +#include +#include +#include +#include +#include +#include +#include + +#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; +} \ No newline at end of file diff --git a/platform/src/sf_status.cpp b/platform/src/sf_status.cpp new file mode 100644 index 0000000..ee3b668 --- /dev/null +++ b/platform/src/sf_status.cpp @@ -0,0 +1,183 @@ +#include +#include +#include +#include +#include +#include + +#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; +} \ No newline at end of file diff --git a/script/CMakeLists.txt b/script/CMakeLists.txt index b46517c..24b8d49 100644 --- a/script/CMakeLists.txt +++ b/script/CMakeLists.txt @@ -1 +1,2 @@ -install(FILES service/sce.service DESTINATION /usr/lib/systemd/system/ COMPONENT Program) \ No newline at end of file +install(FILES service/sce.service DESTINATION /usr/lib/systemd/system/ COMPONENT Program) +install(FILES tmpfiles/sce.conf DESTINATION /usr/lib/tmpfiles.d/ COMPONENT Profile) \ No newline at end of file diff --git a/script/tmpfiles/sce.conf b/script/tmpfiles/sce.conf new file mode 100644 index 0000000..dadec6f --- /dev/null +++ b/script/tmpfiles/sce.conf @@ -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 \ No newline at end of file