diff options
| author | fumingwei <[email protected]> | 2023-03-09 21:58:23 +0800 |
|---|---|---|
| committer | fumingwei <[email protected]> | 2023-03-09 23:06:49 +0800 |
| commit | b2daf45366e59ac3f7b44b3e465224b4c3c5a82e (patch) | |
| tree | 0b9f95fc0d685d155080da51989f7146e4e5d8e1 | |
| parent | cd0ecc40a989ac8e123039b433469ffc1f1c6fd4 (diff) | |
feature:代码review后修改
| -rw-r--r-- | inc/fieldstat.h | 83 | ||||
| -rw-r--r-- | src/field_stat_internal.h | 108 | ||||
| -rw-r--r-- | src/fieldstat.cpp | 550 | ||||
| -rw-r--r-- | src/fieldstat_internal.h | 94 | ||||
| -rw-r--r-- | src/fs2prometheus.cpp | 429 | ||||
| -rw-r--r-- | test/fieldstat_test.cpp (renamed from test/fs2_test.cpp) | 3 |
6 files changed, 417 insertions, 850 deletions
diff --git a/inc/fieldstat.h b/inc/fieldstat.h index cfce68f..c58e798 100644 --- a/inc/fieldstat.h +++ b/inc/fieldstat.h @@ -20,32 +20,81 @@ struct metric_id_list }; /** + * Create fieldstat instance. * @param name The instance name. - * @return Instance id. NULL is failed, Not NULL is successd. - * the output. + * @return Instance id. NULL is failed, Not NULL is successd. */ struct fieldstat_instance * fieldstat_instance_create(const char *name); +/** + * Create prometheus endpoint. + * @param listen_port The endpoint listen port. + * @param url The endpoint url. url is "/metrics" when url is NULL. + * @return -1 is failed. 0 is success. + */ int fieldstat_global_enable_prometheus_endpoint(unsigned short listen_port, const char *url); +/** + * Enable fieldstat instance output prometheus + * @param instance The Fieldstat instance. + * @return -1 is failed. 0 is success. + */ int fieldstat_set_prometheus_output(struct fieldstat_instance *instance); +/** + * Enable output metric to statsd server. + * @param instance The Fieldstat instance. + * @param ip Statsd server ip. + * @param port Statsd server port. + * @return -1 is failed. 0 is success. + */ int fieldstat_set_statsd_server(struct fieldstat_instance *instance, const char *ip, unsigned short port); +/** + * Enable output metric to line protocol server. + * @param instance The Fieldstat instance. + * @param ip Line protocol server ip. + * @param port Line protocol server port. + * @return -1 is failed. 0 is success. + */ int fieldstat_set_line_protocol_server(struct fieldstat_instance *instance, const char *ip, unsigned short port); -int fieldstat_set_local_output(struct fieldstat_instance *instance, const char *filename, const char *format);//format could be "json" or "default" -int fieldstat_backgroud_thead_disable(struct fieldstat_instance *instance); -int fieldstat_set_output_interval(struct fieldstat_instance *instance, int seconds);//default is 2 seconds - - -/* +/** + * Enable output metric to file. + * @param instance The Fieldstat instance. + * @param filename The output target filename. + * @param format The output format. value in {"json","default"} + * @return -1 is failed. 0 is success. + */ +int fieldstat_set_local_output(struct fieldstat_instance *instance, const char *filename, const char *format); +/** + * Disable the background thread. + * @param instance The Fieldstat instance. + * @return -1 is failed. 0 is success. + */ +int fieldstat_background_thead_disable(struct fieldstat_instance *instance); +/** + * Set the output interval in seconds + * @param seconds In seconds. + * @return -1 is failed. 0 is success. + */ +int fieldstat_set_output_interval(struct fieldstat_instance *instance, int seconds); +/** + * Register counter and gauge type metrics * @param field_name the name of the field - * @type counter, gauge summary and histogram - * @n_tag size of tag_key[] and tag_value[] - * - * return field_id to be used in fieldstat_value_xxx(), - * -1 if an error occured. - * example field_name=packets, tag=[{"policy_id", "101"},{"profile_id", "a"}] - * ouput: accumulate value or delta value - * counter or histogram - * */ + * @param type Counter, gauge. + * @param field_name Metric field name. + * @param tag_key Tag key array + * @param tag_value Tag key array + * @param n_tag size of tag_key[] and tag_value[] + * @return -1 is failed. 0 is success. + */ int fieldstat_register(struct fieldstat_instance *instance, enum field_type type, const char *field_name, const char *tag_key[], const char *tag_value[], size_t n_tag); +/** + * Register counter and gauge type metrics + * @param field_name the name of the field + * @param type Counter, gauge. + * @param field_name Metric field name. + * @param tag_key Tag key array + * @param tag_value Tag key array + * @param n_tag size of tag_key[] and tag_value[] + * @return -1 is failed. 0 is success. + */ int fieldstat_register_table(struct fieldstat_instance *instance, enum field_type table_type[], const char *field_list[], size_t n_field); //int fieldstat_register_table_metrics(struct fieldstat_instance * instance, const char *field_name, const char *tag_key[], const char *tag_value[]); struct metric_id_list fieldstat_register_table_metrics(struct fieldstat_instance * instance, int table_id, const char *field_name, const char *tag_key[], const char *tag_value[],size_t n_tag); diff --git a/src/field_stat_internal.h b/src/field_stat_internal.h deleted file mode 100644 index 5dbeb2e..0000000 --- a/src/field_stat_internal.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef __FIELD_STAT2_INTERNAL_H__ -#define __FIELD_STAT2_INTERNAL_H__ - -#include <pthread.h> -#include "hdr_histogram.h" -#include "threadsafe_counter.h" - -#define INIT_STAT_FIELD_NUM 1024 -#define MAX_STAT_COLUMN_NUM 64 -#define MAX_PATH_LEN 256 -#define UDP_PAYLOAD_SIZE 1460 - -#define STATUS_PER_LINE 6 -#define FIELD_PER_LINE 8 - - - -#define HISOTGRAM_EXTRA_INF 0 -#define HISTOGRAM_EXTRA_SUM 1 -#define HISTOGRAM_EXTRA_MAXVAL 2 -#define HISTOGRAM_EXTRA_SIZE 3 - - -struct stat_unit_t -{ - struct threadsafe_counter changing; - long long accumulated; - long long previous_changed; -}; -struct histogram_t -{ - struct hdr_histogram* changing; - struct hdr_histogram* accumulated; - struct hdr_histogram* previous_changed; - int64_t lowest_trackable_value; - int64_t highest_trackable_value; - int significant_figures; - -}; -struct display_manifest_t -{ - char* name; - int is_invisible; - int is_ratio; - int not_send_to_server; - int numerator_id; - int denominator_id; - int output_scaling; //negative value: zoom in; positive value: zoom out; - enum field_dsp_style_t style; - enum field_calc_algo calc_type; - union - { - struct stat_unit_t single;//for status and field - struct stat_unit_t* line; //for line - struct histogram_t histogram; - int column_seq; //for column - }; -}; - - -struct FS_space_t -{ - int stat_cycle; - int screen_print_trigger; - int print_mode; //1:Rewrite ,2: Append - int create_thread; - int running; - int output_prometheus; - - int line_cnt; - int display_cnt; - int single_cnt;//including line_cnt; - int metris_format; - int column_cnt; - int histogram_cnt; - - int histogram_bin_num; - double* histogram_bins; - - int cloumn_id[MAX_STAT_COLUMN_NUM]; - int display_size; - int current_date; - int flush_by_date; - char str_ip[32]; - char app_name[32]; - - int statsd_switch; - unsigned int server_ip; - unsigned short server_port; - int statsd_socket; - - size_t snd_buf_off; - char send_buff[UDP_PAYLOAD_SIZE]; - - pthread_mutex_t reg_lock; - struct display_manifest_t **display; - - char appoint_output_file[MAX_PATH_LEN]; - char current_output_file[MAX_PATH_LEN]; - FILE* fp; - pthread_t cfg_mon_t; - struct timespec last_display_time; - const char* write_mode; -}; - -int FS_library_promethues_register(screen_stat_handle_t handle); -long long get_stat_unit_val(display_manifest_t* p, int column_seq,enum field_calc_algo calc_type,int is_refer); -#endif diff --git a/src/fieldstat.cpp b/src/fieldstat.cpp index 61aa774..0cddc24 100644 --- a/src/fieldstat.cpp +++ b/src/fieldstat.cpp @@ -50,101 +50,6 @@ static __attribute__((__used__)) const char * GIT_VERSION_UNKNOWN = NULL; #endif //endof Automatically generate the version number -#define URL_MAX_LEN 2048 -#define LEN_IP_MAX 32 //?????? 32 from document -#define LEN_APP_NAME 32 -#define LEN_FORMAT_MAX 32 -#define LEN_PATH_MAX 256 -#define NUM_MAX_TABLE 64 -#define TABLE_COLUMN_SIZE 32 -#define UDP_PAYLOAD_SIZE 1460 -#define LEFT_MIN_BUFF_LEN 1024 -#define REALLOC_SCALE_SIZE 2048 -#define STR_LEN_32 32 -#define STR_LEN_64 64 -#define STR_LEN_256 256 -#define STR_LEN_1024 1024 -#define NUM_MAX_METRIC_IN_TABLE 1024 -#define HISTOGRAM_WIDTH 10 -#define INSTANCE_NAME_LEN 32 - - -enum field_op -{ - FS_OP_ADD=1, - FS_OP_SET, - FS_OP_SUB -}; - - -struct fieldstat_instance -{ - char name[LEN_APP_NAME]; - //char *statsd_server_ip; - char statsd_server_str_ip[LEN_IP_MAX]; - unsigned int statsd_server_ip; - unsigned short statsd_server_port; - int statsd_output_enable; - - char line_protocol_server_str_ip[LEN_IP_MAX]; - unsigned int line_protocol_server_ip; - unsigned short line_protocol_server_port; - int line_protocol_output_enable; - - char local_output_filename[LEN_PATH_MAX]; - char local_output_format[LEN_FORMAT_MAX]; - int local_output_enable; - - int background_thread_disable; //default:1 - int output_interval_s; //default:2 - int running; - - struct metric_t **metric_block_list[BLOCK_LIST_SIZE]; - - int metric_cnt; - int metric_size; - //struct metric_t **metric; - struct{ - struct metric_t **column; - size_t column_size; - } table_metrics[NUM_MAX_TABLE]; - int *index_table[NUM_MAX_TABLE][TABLE_COLUMN_SIZE]; - int per_table_line_number[NUM_MAX_TABLE]; - - int table_num; - int line_seq; - - int prometheus_output_enable; - - int counter_cnt; - int gauge_cnt; - int histogram_cnt; - int summary_cnt; - - struct timespec last_output_time; - - pthread_t cfg_mon_t; - char line_protocol_send_buff[UDP_PAYLOAD_SIZE]; - size_t line_protocol_send_buff_offset; - int line_protocol_socket; - pthread_mutex_t output_lock; - - - FILE* fp; -}; - -struct prometheus_endpoint_instance -{ - unsigned short port; - char *url_path; - pthread_t tid; - int running; - struct http_server_s *server_handle; - int fs_instance_cnt; - struct fieldstat_instance **fs_instance; //TO refactor - int fs_instance_size; // number -}; - struct prometheus_endpoint_instance g_prometheus_endpoint_instance = { 9273, @@ -256,33 +161,6 @@ struct metric_t* metric_new(enum field_type type, const char *field_name, const return metric; } -struct metric_t * create_metric(struct fieldstat_instance *instance, int metric_id,enum field_type type, const char *field_name, const char *tag_key[], const char *tag_value[], size_t n_tag) -{ - int block_index = 0; - int block_in_index = 0; - struct metric_t ** metrics_array = NULL; - struct metric_t * metric = NULL; - - if(instance == NULL) - { - return NULL; - } - block_index = metric_id / NUM_INIT_METRICS; - block_in_index = metric_id % NUM_INIT_METRICS; - if(block_in_index == 0 && instance->metric_block_list[block_index] == NULL) - { - instance->metric_block_list[block_index] = (struct metric_t **)calloc(sizeof(struct metric *), NUM_INIT_METRICS); - } - else - { - while (instance->metric_block_list[block_index] == NULL); - } - metrics_array = (struct metric_t **)instance->metric_block_list[block_index]; - //assert(instance->metric_cnt < instance->metric_size); - metric = metrics_array[block_in_index] = metric_new(type,field_name,tag_key,tag_value,n_tag); - return metric; -} - void metric_free(struct metric_t* metric) { int i = 0; @@ -305,10 +183,37 @@ void metric_free(struct metric_t* metric) return; } +static struct metric_t ** read_metric_slot(struct fieldstat_instance *instance, int metric_id) +{ + int block_index = 0; + int in_block_index = 0; + struct metric_t ** metrics_block = NULL; + + if(instance == NULL) + { + return NULL; + } + block_index = metric_id / NUM_INIT_METRICS; + in_block_index = metric_id % NUM_INIT_METRICS; + if(in_block_index == 0) + { + assert(instance->metric_block_list[block_index] != NULL); + instance->metric_block_list[block_index] = (struct metric_t **)calloc(sizeof(struct metric *), NUM_INIT_METRICS); + } + else + { + while (instance->metric_block_list[block_index] == NULL); + } + metrics_block = (struct metric_t **)instance->metric_block_list[block_index]; + + return (struct metric_t **)&(metrics_block[in_block_index]); +} + static int startup_udp() { int sd_udp=-1; int flags; + int opt=1; if(-1==(sd_udp = socket(AF_INET, SOCK_DGRAM, 0))) { printf("FS2: socket error: %d %s, restart socket.", errno, strerror(errno)); @@ -321,8 +226,8 @@ static int startup_udp() printf("FS2: socket error: %d %s, restart socket.", errno, strerror(errno)); sd_udp=-1; } - int opt=1; - if (setsockopt (sd_udp, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt) ) < 0) { + if (setsockopt (sd_udp, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt) ) < 0) + { printf("FS2:setsockopt error: %d %s, restart socket.", errno, strerror(errno)); close (sd_udp); sd_udp=-1; @@ -376,7 +281,7 @@ int fieldstat_set_output_interval(struct fieldstat_instance *instance, int secon return 0; } -int fieldstat_backgroud_thead_disable(struct fieldstat_instance *instance) +int fieldstat_background_thead_disable(struct fieldstat_instance *instance) { if(instance->running == 1) { @@ -408,7 +313,6 @@ int fieldstat_set_local_output(struct fieldstat_instance *instance, const char * { return -1; } - instance->line_protocol_socket = startup_udp(); strncpy(instance->local_output_filename, (char *)filename, len_filename); strncpy(instance->local_output_format, (char *)format, len_format); instance->local_output_enable = 1; @@ -418,22 +322,16 @@ int fieldstat_set_local_output(struct fieldstat_instance *instance, const char * int fieldstat_set_line_protocol_server(struct fieldstat_instance *instance, const char *ip, unsigned short port) { - int len_ip = strlen(ip); - if(instance->running == 1) { return -1; } - if(len_ip <= 0 || len_ip >= LEN_IP_MAX) - { - return -1; - } + if(1 != inet_pton(AF_INET, ip, (void *)&(instance->line_protocol_server_ip))) { return -1; } - - strncpy(instance->line_protocol_server_str_ip,(char *)ip,len_ip); + instance->line_protocol_socket = startup_udp(); instance->line_protocol_server_port = port; instance->line_protocol_output_enable = 1; @@ -442,22 +340,16 @@ int fieldstat_set_line_protocol_server(struct fieldstat_instance *instance, cons int fieldstat_set_statsd_server(struct fieldstat_instance *instance, const char *ip, unsigned short port) { - int len_ip = strlen(ip); if(instance->running == 1) { return -1; } - if(len_ip <= 0 || len_ip >= LEN_IP_MAX) - { - return -1; - } if(1 != inet_pton(AF_INET, ip, (void *)&(instance->statsd_server_ip))) { return -1; } - strncpy(instance->statsd_server_str_ip,(char *)ip,len_ip); instance->statsd_server_port = port; instance->statsd_output_enable = 1; return 0; @@ -466,7 +358,8 @@ int fieldstat_set_statsd_server(struct fieldstat_instance *instance, const char int fieldstat_register(struct fieldstat_instance *instance, enum field_type type, const char *field_name, const char *tag_key[], const char *tag_value[], size_t n_tag) { int metric_id = 0; - struct metric_t * metric_choosen = NULL; + struct metric_t * metric = NULL; + struct metric_t **metric_slot = NULL; if(!is_valid_field_name(field_name)) { return -1; @@ -475,29 +368,19 @@ int fieldstat_register(struct fieldstat_instance *instance, enum field_type type { return -1; } - //TODO not block - metric_id = atomic_inc(&instance->metric_cnt) - 1; - metric_choosen = create_metric(instance, metric_id, type,field_name,tag_key,tag_value,n_tag); - //assert(instance->metric_cnt < instance->metric_size); - //metric_choosen = instance->metric[metric_id] = metric_new(type,field_name,tag_key,tag_value,n_tag); - //metric_choosen = metrics_array[block_in_index] = metric_new(type,field_name,tag_key,tag_value,n_tag); + + metric_id = atomic_inc(&instance->metric_cnt) - 1; + metric_slot = read_metric_slot(instance, metric_id); + metric = metric_new(type,field_name,tag_key,tag_value,n_tag); + *metric_slot = metric; + switch(type) { case FIELD_TYPE_COUNTER: - instance->counter_cnt++; - memset(&(metric_choosen->counter), 0, sizeof(metric_choosen->counter)); + memset(&(metric->counter), 0, sizeof(metric->counter)); break; case FIELD_TYPE_GAUGE: - instance->gauge_cnt++; - memset(&(metric_choosen->gauge), 0, sizeof(metric_choosen->gauge)); - break; - case FILED_TYPE_HISTOGRAM: - //instance->histogram_cnt++; - // TODO what? - break; - case FIELD_TYPE_SUMMARY: - //instance->summary_cnt++; - //TODO what ? + memset(&(metric->gauge), 0, sizeof(metric->gauge)); break; default: assert(0); @@ -505,8 +388,6 @@ int fieldstat_register(struct fieldstat_instance *instance, enum field_type type return metric_id; } - -//long long get_metric_unit_val(display_manifest_t* p, int column_seq,enum field_calc_algo calc_type,int is_refer) long long get_metric_unit_val(struct metric_t *metric,enum field_calc_algo calc_type,int is_refer) { stat_unit_t* target = NULL; @@ -519,8 +400,6 @@ long long get_metric_unit_val(struct metric_t *metric,enum field_calc_algo calc_ case FIELD_TYPE_GAUGE: target = &(metric->gauge); break; - case FILED_TYPE_HISTOGRAM: - case FIELD_TYPE_SUMMARY: default: break; } @@ -542,6 +421,7 @@ long long get_metric_unit_val(struct metric_t *metric,enum field_calc_algo calc_ break; default: assert(0); + break; } return value; } @@ -577,7 +457,8 @@ void append_line_protocol_line(struct fieldstat_instance *instance, const char* instance->line_protocol_send_buff_offset += snprintf(instance->line_protocol_send_buff + instance->line_protocol_send_buff_offset, sizeof(instance->line_protocol_send_buff) - instance->line_protocol_send_buff_offset, "%s%s %s\n", - measurement, tag_set, field_set); + measurement, tag_set, field_set + ); return; } @@ -587,7 +468,12 @@ static int output_line_protocol_tag_set_buf(metric_t *metric, char *tag_set_buff char *tag_set_buff_append = tag_set_buff; for(i = 0; i < (int)metric->n_tag; i++) { - tag_set_buff_append += snprintf(tag_set_buff_append, size - (tag_set_buff_append - tag_set_buff), ",%s=%s", metric->tag_key[i],metric->tag_value[i]); + tag_set_buff_append += snprintf(tag_set_buff_append, + size - (tag_set_buff_append - tag_set_buff), + ",%s=%s", + metric->tag_key[i], + metric->tag_value[i] + ); } return tag_set_buff_append - tag_set_buff; } @@ -636,10 +522,19 @@ static void output_line_protocol_table(struct fieldstat_instance *instance) break; } - field_set_buff_append += snprintf(field_set_buff_append, sizeof(field_set_buff) - (field_set_buff - field_set_buff), "%s=%lld,", metric->table_column_name, value); + field_set_buff_append += snprintf(field_set_buff_append, + sizeof(field_set_buff) - (field_set_buff - field_set_buff), + "%s=%lld,", + metric->table_column_name, + value + ); } - tag_set_buff_append += snprintf(tag_set_buff_append, sizeof(tag_set_buff) - (tag_set_buff_append - tag_set_buff), ",app_name=%s", instance->name); + tag_set_buff_append += snprintf(tag_set_buff_append, + sizeof(tag_set_buff) - (tag_set_buff_append - tag_set_buff), + ",app_name=%s", + instance->name + ); output_line_protocol_tag_set_buf(metric, tag_set_buff_append, sizeof(tag_set_buff) - (tag_set_buff_append - tag_set_buff)); if(field_set_buff_append - field_set_buff > 0) @@ -685,13 +580,11 @@ int line_protocol_output(struct fieldstat_instance *instance) if(value != 0) { snprintf(field_set_buff, UDP_PAYLOAD_SIZE, "%s=%lld", metric->field_name, value); - tag_set_buff_append += snprintf(tag_set_buff_append, sizeof(tag_set_buff) - (tag_set_buff_append - tag_set_buff), ",app_name=%s", instance->name); - /* - for(j = 0; j < (int)metric->n_tag; j++) - { - tag_set_buff_append += snprintf(tag_set_buff_append, sizeof(tag_set_buff) - (tag_set_buff_append - tag_set_buff), ",%s=%s", metric->tag_key[i],metric->tag_value[i]); - } - */ + tag_set_buff_append += snprintf(tag_set_buff_append, + sizeof(tag_set_buff) - (tag_set_buff_append - tag_set_buff), + ",app_name=%s", + instance->name + ); output_line_protocol_tag_set_buf(metric, tag_set_buff_append, sizeof(tag_set_buff) - (tag_set_buff_append - tag_set_buff)); append_line_protocol_line(instance, metric->field_name, tag_set_buff, field_set_buff); tag_set_buff_append = tag_set_buff; @@ -703,13 +596,11 @@ int line_protocol_output(struct fieldstat_instance *instance) if(value != 0) { snprintf(field_set_buff, UDP_PAYLOAD_SIZE, "%s=%lld", metric->field_name, value); - tag_set_buff_append += snprintf(tag_set_buff_append, sizeof(tag_set_buff) - (tag_set_buff_append - tag_set_buff), ",app_name=%s", instance->name); - /* - for(j = 0; j < (int)metric->n_tag; j++) - { - tag_set_buff_append += snprintf(tag_set_buff_append, sizeof(tag_set_buff) - (tag_set_buff_append - tag_set_buff), ",%s=%s", metric->tag_key[i],metric->tag_value[i]); - } - */ + tag_set_buff_append += snprintf(tag_set_buff_append, + sizeof(tag_set_buff) - (tag_set_buff_append - tag_set_buff), + ",app_name=%s", + instance->name + ); output_line_protocol_tag_set_buf(metric, tag_set_buff_append, sizeof(tag_set_buff) - (tag_set_buff_append - tag_set_buff)); append_line_protocol_line(instance, metric->field_name, tag_set_buff, field_set_buff); tag_set_buff_append = tag_set_buff; @@ -732,19 +623,34 @@ static int print_buf_tag_append_position(metric_t *metric, char *print_buf_tags, int i = 0; char *print_buf_tags_append_position = print_buf_tags; - print_buf_tags_append_position += snprintf(print_buf_tags_append_position, size - (print_buf_tags_append_position - print_buf_tags),"{"); - for(; i < (int)metric->n_tag; i++) + if(metric->n_tag <= 0) { - if(i == 0) - { - print_buf_tags_append_position += snprintf(print_buf_tags_append_position, size - (print_buf_tags_append_position - print_buf_tags),"%s=\"%s\"", metric->tag_key[i],metric->tag_value[i]); - } - else - { - print_buf_tags_append_position += snprintf(print_buf_tags_append_position, size - (print_buf_tags_append_position - print_buf_tags),",%s=\"%s\"", metric->tag_key[i],metric->tag_value[i]); - } + return 0; + } + + print_buf_tags_append_position += snprintf(print_buf_tags_append_position, + size - (print_buf_tags_append_position - print_buf_tags), + "{" + ); + for(i = 0; i < (int)metric->n_tag; i++) + { + print_buf_tags_append_position += snprintf(print_buf_tags_append_position, + size - (print_buf_tags_append_position - print_buf_tags), + ",%s=\"%s\"", + metric->tag_key[i], + metric->tag_value[i] + ); } - print_buf_tags_append_position += snprintf(print_buf_tags_append_position, size - (print_buf_tags_append_position - print_buf_tags),"}"); + + if(print_buf_tags_append_position - print_buf_tags > 0) + { + print_buf_tags_append_position--; + } + + print_buf_tags_append_position += snprintf(print_buf_tags_append_position, + size - (print_buf_tags_append_position - print_buf_tags), + "}" + ); return print_buf_tags_append_position - print_buf_tags; } @@ -790,7 +696,13 @@ static int output_file_format_default_type_gauge(struct fieldstat_instance *inst //value=value * metric->output_scaling * 1000 / interval_ms; memset(print_buf_tags,0, sizeof(print_buf_tags)); print_buf_tag_append_position(metric, print_buf_tags, sizeof(print_buf_tags)); - print_buf_append_position += snprintf(print_buf_append_position, size - (print_buf_append_position - print_buf), "%s %s: %-10lld\t", metric->field_name, print_buf_tags, value); + print_buf_append_position += snprintf(print_buf_append_position, + size - (print_buf_append_position - print_buf), + "%s %s: %-10lld\t", + metric->field_name, + print_buf_tags, + value + ); j++; if(j == STATUS_PER_LINE) { @@ -855,7 +767,12 @@ static int output_file_format_default_type_counter(struct fieldstat_instance *in metric = get_metric(instance, metric_id[i+j]); memset(print_buf_tags,0, sizeof(print_buf_tags)); print_buf_tag_append_position(metric, print_buf_tags, sizeof(print_buf_tags)); - print_buf_append_position += snprintf(print_buf_append_position, size - (print_buf_append_position - print_buf), "%10s %s\t", metric->field_name, print_buf_tags); + print_buf_append_position += snprintf(print_buf_append_position, + size - (print_buf_append_position - print_buf), + "%10s %s\t", + metric->field_name, + print_buf_tags + ); } print_buf_append_position += snprintf(print_buf_append_position, size - (print_buf_append_position-print_buf), "\nsum\t"); @@ -864,19 +781,33 @@ static int output_file_format_default_type_counter(struct fieldstat_instance *in //metric = instance->metric[metric_id[i+j]]; metric = get_metric(instance, metric_id[i+j]); value = get_metric_unit_val(metric,FS_CALC_CURRENT, 1); - print_buf_append_position += snprintf(print_buf_append_position, sizeof(print_buf) - (print_buf_append_position - print_buf), "%10lld\t", value); + print_buf_append_position += snprintf(print_buf_append_position, + sizeof(print_buf) - (print_buf_append_position - print_buf), + "%10lld\t", + value + ); } - print_buf_append_position += snprintf(print_buf_append_position, sizeof(print_buf) - (print_buf_append_position - print_buf), "\nspeed/s\t"); + print_buf_append_position += snprintf(print_buf_append_position, + sizeof(print_buf) - (print_buf_append_position - print_buf), + "\nspeed/s\t" + ); for(j=0;j<FIELD_PER_LINE&&i+j<metric_cnt;j++) { //metric = instance->metric[metric_id[i+j]]; metric = get_metric(instance, metric_id[i+j]); value = get_metric_unit_val(metric,FS_CALC_SPEED, 0); - print_buf_append_position += snprintf(print_buf_append_position, size - (print_buf_append_position - print_buf), "%10lld\t", value*1000/interval_ms); + print_buf_append_position += snprintf(print_buf_append_position, + size - (print_buf_append_position - print_buf), + "%10lld\t", + value*1000/interval_ms + ); } i += (j-1); - print_buf_append_position += snprintf(print_buf_append_position, size - (print_buf_append_position - print_buf), "\n"); + print_buf_append_position += snprintf(print_buf_append_position, + size - (print_buf_append_position - print_buf), + "\n" + ); } if(print_buf_append_position - print_buf > 0) @@ -885,7 +816,11 @@ static int output_file_format_default_type_counter(struct fieldstat_instance *in { print_buf_append_position--; } - print_buf_append_position += snprintf(print_buf_append_position, size - (print_buf_append_position - print_buf),"\n%s\n", draw_line); + print_buf_append_position += snprintf(print_buf_append_position, + size - (print_buf_append_position - print_buf), + "\n%s\n", + draw_line + ); } return print_buf_append_position - print_buf; @@ -917,7 +852,11 @@ static int output_file_format_default_table(struct fieldstat_instance *instance, print_buf_append_position += snprintf(print_buf_append_position, size - (print_buf - print_buf),"\t\t\t"); for(k = 0; k < (int)table_column_size; k++) { - print_buf_append_position += snprintf(print_buf_append_position ,size - (print_buf_append_position - print_buf), "\t%10s", table_column[k]->field_name); + print_buf_append_position += snprintf(print_buf_append_position, + size - (print_buf_append_position - print_buf), + "\t%10s", + table_column[k]->field_name + ); } for(j = 0; j < instance->per_table_line_number[i]; j++) @@ -931,13 +870,25 @@ static int output_file_format_default_table(struct fieldstat_instance *instance, if(k == 0) { print_buf_tag_append_position(metric, print_buf_tags, sizeof(print_buf_tags)); - print_buf_append_position += snprintf(print_buf_append_position, size - (print_buf_append_position - print_buf), "\n%s %-20s\t", metric->field_name,print_buf_tags); + print_buf_append_position += snprintf(print_buf_append_position, + size - (print_buf_append_position - print_buf), + "\n%s %-20s\t", + metric->field_name, + print_buf_tags + ); } value = get_metric_unit_val(metric, FS_CALC_CURRENT, 0); - print_buf_append_position += snprintf(print_buf_append_position, size - (print_buf_append_position - print_buf), "%10lld\t", value); + print_buf_append_position += snprintf(print_buf_append_position, + size - (print_buf_append_position - print_buf), + "%10lld\t", + value + ); } } - print_buf_append_position += snprintf(print_buf_append_position,size - (print_buf_append_position - print_buf), "\n"); + print_buf_append_position += snprintf(print_buf_append_position, + size - (print_buf_append_position - print_buf), + "\n" + ); if(print_buf_append_position - print_buf > 0) { @@ -945,7 +896,11 @@ static int output_file_format_default_table(struct fieldstat_instance *instance, { print_buf_append_position--; } - print_buf_append_position += snprintf(print_buf_append_position, size - (print_buf_append_position - print_buf), "\n%s\n", draw_line); + print_buf_append_position += snprintf(print_buf_append_position, + size - (print_buf_append_position - print_buf), + "\n%s\n", + draw_line + ); } } return print_buf_append_position - print_buf; @@ -1313,7 +1268,8 @@ struct metric_id_list fieldstat_register_table_metrics(struct fieldstat_instance int metric_id = 0; int i = 0; int per_table_line_num = 0; - struct metric_t * metric_choosen = NULL; + struct metric_t * metric = NULL; + struct metric_t **metric_slot = NULL; int *table_line = NULL; metric_t **table_column = instance->table_metrics[table_id].column; int table_column_size = instance->table_metrics[table_id].column_size; @@ -1348,33 +1304,25 @@ struct metric_id_list fieldstat_register_table_metrics(struct fieldstat_instance for( i = 0; i < table_column_size; i ++) { metric_id = atomic_inc(&instance->metric_cnt) - 1; - metric_choosen = create_metric(instance,metric_id, table_column[i]->field_type,field_name,tag_key,tag_value,n_tag); + metric_slot = read_metric_slot(instance, metric_id); + metric = metric_new(table_column[i]->field_type,field_name,tag_key,tag_value,n_tag); + *metric_slot = metric; table_line[i] = metric_id; - metric_choosen->table_id = table_id; - metric_choosen->belong_to_table = 1; - metric_choosen->table_column_id = i; - metric_choosen->line_seq ++; - metric_choosen->table_column_name = strdup(table_column[i]->field_name); + metric->table_id = table_id; + metric->belong_to_table = 1; + metric->table_column_id = i; + metric->line_seq ++; + metric->table_column_name = strdup(table_column[i]->field_name); - switch(metric_choosen->field_type) + switch(metric->field_type) { case FIELD_TYPE_COUNTER: - instance->counter_cnt++; - memset(&(metric_choosen->counter), 0, sizeof(metric_choosen->counter)); + memset(&(metric->counter), 0, sizeof(metric->counter)); break; case FIELD_TYPE_GAUGE: - instance->gauge_cnt++; - memset(&(metric_choosen->gauge), 0, sizeof(metric_choosen->gauge)); - break; - case FILED_TYPE_HISTOGRAM: - //instance->histogram_cnt++; - // TODO what? - break; - case FIELD_TYPE_SUMMARY: - //instance->summary_cnt++; - //TODO what ? + memset(&(metric->gauge), 0, sizeof(metric->gauge)); break; default: assert(0); @@ -1408,17 +1356,22 @@ struct metric_id_list fieldstat_register_table_metrics(struct fieldstat_instance static int prometheus_get_fs_instance_id(struct prometheus_endpoint_instance *global_prometheus_output, char *uri, int uri_len) { int i = 0; + char instance_name_url[INSTANCE_NAME_LEN + 1] = {0}; + int instance_name_url_len = 0; - if(uri_len == (int)strlen(global_prometheus_output->url_path) && - 0 == memcmp(uri, global_prometheus_output->url_path, strlen(global_prometheus_output->url_path))) + if(uri_len == (int)strlen(global_prometheus_output->url_path) + && 0 == memcmp(uri, global_prometheus_output->url_path, strlen(global_prometheus_output->url_path))) { return global_prometheus_output->fs_instance_cnt; } - for( i = 0; i < global_prometheus_output->fs_instance_cnt; i++) + for(i = 0; i < global_prometheus_output->fs_instance_cnt; i++) { - if(uri_len - 1 == (int)strlen(global_prometheus_output->fs_instance[i]->name) && - 0 == memcmp( uri + 1, global_prometheus_output->fs_instance[i]->name, strlen(global_prometheus_output->fs_instance[i]->name))) + memset(instance_name_url, 0, sizeof(instance_name_url)); + instance_name_url_len = snprintf(instance_name_url, sizeof(instance_name_url),"/%s",global_prometheus_output->fs_instance[i]->name); + + if(uri_len == instance_name_url_len + && 0 == memcmp( uri, instance_name_url, instance_name_url_len)) { return i; } @@ -1459,7 +1412,7 @@ static void prometheus_output_uri_list(struct prometheus_endpoint_instance *prom return; } -static int prometheus_output_get_metric_tags(struct metric_t *metric, char *tags_buff, unsigned int size, char *instance_app_name) +static int prometheus_output_read_metric_tags(struct metric_t *metric, char *instance_app_name, char *tags_buff, unsigned int size) { int i = 0; char unescape[STR_LEN_256] = {0}; @@ -1482,7 +1435,7 @@ static int prometheus_output_get_metric_tags(struct metric_t *metric, char *tags } -static int prometheus_output_get_metric_name(struct metric_t *metric, char *name_buff, unsigned int size, char *instance_app_name) +static int prometheus_output_read_metric_name(struct metric_t *metric, char *instance_app_name, char *name_buff, unsigned int size) { char unescape[256] = {0}; char *name_buff_append_position = name_buff; @@ -1508,7 +1461,7 @@ static int prometheus_output_histogram_and_summary(struct metric_t *metric, char int i=0,used_len=0; struct hdr_iter iter; - char output_format[STR_LEN_64] = {0}; + char *output_format = NULL; //struct histogram_t* h=&(p->histogram); struct histogram_t *h = &(metric->histogram); @@ -1518,12 +1471,12 @@ static int prometheus_output_histogram_and_summary(struct metric_t *metric, char if(metric->field_type == FILED_TYPE_HISTOGRAM) { - snprintf(output_format, sizeof(output_format), "%%s_bucket{%%s,le=\"%%0.2f\"} %%llu\n"); + output_format = (char *)"%s_bucket{%s,le=\"%0.2f\"} %llu\n"; } if(metric->field_type == FIELD_TYPE_SUMMARY) { - snprintf(output_format, sizeof(output_format), "%%s{%%s,quantile=\"%%0.2f\"} %%llu\n"); + output_format = (char *)"%s{%s,quantile=\"%0.2f\"} %llu\n"; } hdr_init(h->lowest_trackable_value, h->highest_trackable_value, h->significant_figures, &(h_tmp)); @@ -1534,7 +1487,15 @@ static int prometheus_output_histogram_and_summary(struct metric_t *metric, char for(i=0;i<bin_num;i++) { - value= hdr_count_le_value(h_out, (long long)bins[i]); + if(metric->field_type == FILED_TYPE_HISTOGRAM) + { + value = (long long)hdr_count_le_value(h_out, (long long)bins[i]); + } + if(metric->field_type == FIELD_TYPE_SUMMARY) + { + value=(long long)hdr_value_at_percentile(h_out, bins[i]); + } + used_len+=snprintf(payload+used_len, payload_len-used_len, output_format, @@ -1578,26 +1539,30 @@ static int prometheus_get_instance_metric_playload(struct fieldstat_instance *in int i = 0; struct metric_t *metric = NULL; long long value = 0; - char metric_name[STR_LEN_256] = {0}; //need to macro match the regex [a-zA-Z_:][a-zA-Z0-9_:]* - char app_name[STR_LEN_256] = {0}; //using macro - char metric_tags[STR_LEN_1024] = {0}; //label name match the regex [a-zA-Z_:][a-zA-Z0-9_:]* + char metric_name[256] = {0}; //match the regex [a-zA-Z_:][a-zA-Z0-9_:]* + char instance_name[256] = {0}; + char metric_tags[1024] = {0}; //label name match the regex [a-zA-Z_:][a-zA-Z0-9_:]* int append_offset = offset; + char *new_payload = NULL; + int new_payload_size = 0; - if(instance == NULL || instance->running != 1) + if(instance->running != 1) { return -1; } + if(payload == NULL) { return -1; } + new_payload = *payload; + new_payload_size = *payload_size; - str_unescape(instance->name, app_name, sizeof(app_name)); + str_unescape(instance->name, instance_name, sizeof(instance_name)); for(i = 0; i < instance->metric_cnt; i++) { - //metric = instance->metric[i]; metric = get_metric(instance, i); if(metric->is_ratio == 1) @@ -1609,38 +1574,46 @@ static int prometheus_get_instance_metric_playload(struct fieldstat_instance *in continue; } - //relloc - //type = [counter, gauge] - if( *payload_size - append_offset <= LEFT_MIN_BUFF_LEN) + if( new_payload_size - append_offset <= LEFT_MIN_BUFF_LEN) { - *payload_size += REALLOC_SCALE_SIZE; - *payload = (char *)realloc(*payload, *payload_size); + new_payload_size += REALLOC_SCALE_SIZE; + new_payload = (char *)realloc(new_payload, new_payload_size); } - prometheus_output_get_metric_name(metric, metric_name, sizeof(metric_name), app_name); //TODO refactor - prometheus_output_get_metric_tags(metric, metric_tags, sizeof(metric_tags), app_name); //TODO refactor + prometheus_output_read_metric_name(metric, instance_name, metric_name, sizeof(metric_name)); + prometheus_output_read_metric_tags(metric, instance_name, metric_tags, sizeof(metric_tags)); switch(metric->field_type) { case FIELD_TYPE_COUNTER: case FIELD_TYPE_GAUGE: value = get_metric_unit_val(metric, FS_CALC_CURRENT, 1); - append_offset += snprintf(*payload + append_offset, *payload_size - append_offset, - "%s{%s} %llu\n", metric_name, metric_tags, value); + append_offset += snprintf(new_payload + append_offset, + new_payload_size - append_offset, + "%s{%s} %llu\n", + metric_name, + metric_tags, + value + ); break; case FIELD_TYPE_SUMMARY: case FILED_TYPE_HISTOGRAM: - append_offset += prometheus_output_histogram_and_summary(metric,*payload + append_offset, *payload_size - append_offset, app_name, metric_name, metric_tags); + append_offset += prometheus_output_histogram_and_summary(metric,new_payload + append_offset, + new_payload_size - append_offset, instance_name, metric_name, metric_tags); break; default: break; } } + + *payload = new_payload; + *payload_size = new_payload_size; + return append_offset; } -static void prometheus_output_instance_metric(struct prometheus_endpoint_instance *prometheus_output, struct http_request_s* request, int fs_instance_id) +static void prometheus_output_instance_metric(struct prometheus_endpoint_instance *prometheus_output, struct http_request_s* request, int fs_instance_idx) { int i = 0; int payload_size = 0; @@ -1649,7 +1622,7 @@ static void prometheus_output_instance_metric(struct prometheus_endpoint_instanc struct fieldstat_instance *instance = NULL; struct http_response_s* response = NULL; - if(fs_instance_id == prometheus_output->fs_instance_cnt) + if(fs_instance_idx == prometheus_output->fs_instance_cnt) { for(i = 0; i < prometheus_output->fs_instance_cnt; i++) { @@ -1659,7 +1632,7 @@ static void prometheus_output_instance_metric(struct prometheus_endpoint_instanc } else { - instance = prometheus_output->fs_instance[fs_instance_id]; + instance = prometheus_output->fs_instance[fs_instance_idx]; payload_offset = prometheus_get_instance_metric_playload(instance, &payload, &payload_size, payload_offset); } @@ -1680,62 +1653,50 @@ static void prometheus_output_instance_metric(struct prometheus_endpoint_instanc static void prometheus_endpoint_instance_output(struct http_request_s* request) { + int fs_instance_idx = -1; struct http_string_s uri; - struct prometheus_endpoint_instance *prometheus_instance = NULL; - int fs_instance_idx = -1; + struct prometheus_endpoint_instance *prometheus_endpoint_instance = &g_prometheus_endpoint_instance;; - prometheus_instance = &g_prometheus_endpoint_instance; uri = http_request_target(request); - fs_instance_idx = prometheus_get_fs_instance_id(prometheus_instance, (char *)uri.buf, uri.len); + fs_instance_idx = prometheus_get_fs_instance_id(prometheus_endpoint_instance, (char *)uri.buf, uri.len); + + fs_instance_idx == -1 ? + prometheus_output_uri_list(prometheus_endpoint_instance, request) + :prometheus_output_instance_metric(prometheus_endpoint_instance, request, fs_instance_idx); - if(fs_instance_idx == -1) - { - prometheus_output_uri_list(prometheus_instance, request); - return; - } - else - { - prometheus_output_instance_metric(prometheus_instance, request, fs_instance_idx); - } return; } -void *prometheus_endpoin_listen(void *arg) +static void *prometheus_endpoint_listen_thread_entry(void *arg) { struct prometheus_endpoint_instance *global_prometheus = (struct prometheus_endpoint_instance *)arg; - - if(global_prometheus != NULL) - { - global_prometheus->server_handle = http_server_init(global_prometheus->port , prometheus_endpoint_instance_output); - http_server_listen(global_prometheus->server_handle); - } - + http_server_listen(global_prometheus->server_handle); return NULL; } - int fieldstat_global_enable_prometheus_endpoint(unsigned short listen_port, const char *url) { - if(url == NULL) + g_prometheus_endpoint_instance.server_handle = http_server_init(listen_port, prometheus_endpoint_instance_output); + if(g_prometheus_endpoint_instance.server_handle == NULL) { - g_prometheus_endpoint_instance.url_path = (char *)calloc(strlen((char *)"/metrics")+1, 1); - memcpy(g_prometheus_endpoint_instance.url_path, (char *)"/metrics", strlen((char *)"/metrics")); + return -1; } + g_prometheus_endpoint_instance.url_path = url == NULL ? strdup(PROMETHEUS_ENDPOINT_DEFAULT_URL):strdup(url); g_prometheus_endpoint_instance.port = listen_port; - g_prometheus_endpoint_instance.url_path = strdup(url); g_prometheus_endpoint_instance.running = 1; g_prometheus_endpoint_instance.fs_instance = (struct fieldstat_instance **)calloc( sizeof(struct fieldstat_instance *), g_prometheus_endpoint_instance.fs_instance_size); - pthread_create(&g_prometheus_endpoint_instance.tid, NULL, prometheus_endpoin_listen, (void *)&g_prometheus_endpoint_instance); + pthread_create(&g_prometheus_endpoint_instance.tid, NULL, prometheus_endpoint_listen_thread_entry, (void *)&g_prometheus_endpoint_instance); + return 0; } -int fieldstat_set_prometheus_output(struct fieldstat_instance *instance) //TODO +int fieldstat_set_prometheus_output(struct fieldstat_instance *instance) { - int i = 0; + int fs_instance_id = 0; if(g_prometheus_endpoint_instance.running != 1) { @@ -1748,8 +1709,8 @@ int fieldstat_set_prometheus_output(struct fieldstat_instance *instance) //TODO g_prometheus_endpoint_instance.fs_instance = (struct fieldstat_instance **)realloc(g_prometheus_endpoint_instance.fs_instance, g_prometheus_endpoint_instance.fs_instance_size); } - i = g_prometheus_endpoint_instance.fs_instance_cnt++; - g_prometheus_endpoint_instance.fs_instance[i] = instance; + fs_instance_id = g_prometheus_endpoint_instance.fs_instance_cnt++; + g_prometheus_endpoint_instance.fs_instance[fs_instance_id] = instance; return 0; } @@ -1870,7 +1831,8 @@ error_out: int fieldstat_register_histogram(struct fieldstat_instance *instance, enum field_type type, const char *field_name, const char *tag_key[], const char *tag_value[], size_t n_tag, const char * bins,const long long lowest_trackable_value,long long highest_trackable_value,int significant_figures) { - struct metric_t *metric_choosen = NULL; + struct metric_t *metric = NULL; + struct metric_t **metric_slot = NULL; int metric_id = -1; int ret; @@ -1894,16 +1856,18 @@ int fieldstat_register_histogram(struct fieldstat_instance *instance, enum field } metric_id = atomic_inc(&instance->metric_cnt) - 1; - metric_choosen = create_metric(instance, metric_id, type, field_name, tag_key, tag_value, n_tag); + metric_slot = read_metric_slot(instance, metric_id); + metric = metric_new(type,field_name,tag_key,tag_value,n_tag); + *metric_slot = metric; - metric_choosen->histogram.highest_trackable_value = (int64_t)highest_trackable_value; - metric_choosen->histogram.lowest_trackable_value = (int64_t)lowest_trackable_value; - metric_choosen->histogram.significant_figures = significant_figures; - metric_choosen->histogram.bins_num = parse_histogram_bin_format((const char*)bins, &(metric_choosen->histogram.bins), type); + metric->histogram.highest_trackable_value = (int64_t)highest_trackable_value; + metric->histogram.lowest_trackable_value = (int64_t)lowest_trackable_value; + metric->histogram.significant_figures = significant_figures; + metric->histogram.bins_num = parse_histogram_bin_format((const char*)bins, &(metric->histogram.bins), type); - ret = hdr_init((int64_t)lowest_trackable_value, (int64_t)highest_trackable_value, significant_figures, &(metric_choosen->histogram.changing)); + ret = hdr_init((int64_t)lowest_trackable_value, (int64_t)highest_trackable_value, significant_figures, &(metric->histogram.changing)); assert(ret==0); - ret = hdr_init((int64_t)lowest_trackable_value, (int64_t)highest_trackable_value, significant_figures, &(metric_choosen->histogram.accumulated)); + ret = hdr_init((int64_t)lowest_trackable_value, (int64_t)highest_trackable_value, significant_figures, &(metric->histogram.accumulated)); assert(ret==0); switch(type) diff --git a/src/fieldstat_internal.h b/src/fieldstat_internal.h index ee38a27..e3f979f 100644 --- a/src/fieldstat_internal.h +++ b/src/fieldstat_internal.h @@ -27,12 +27,40 @@ #define BLOCK_LIST_SIZE 1024*16 +#define URL_MAX_LEN 2048 +#define LEN_IP_MAX 32 //?????? 32 from document +#define LEN_FORMAT_MAX 32 +#define LEN_PATH_MAX 256 +#define NUM_MAX_TABLE 64 +#define TABLE_COLUMN_SIZE 32 +#define UDP_PAYLOAD_SIZE 1460 +#define LEFT_MIN_BUFF_LEN 1024 +#define REALLOC_SCALE_SIZE 2048 +#define STR_LEN_32 32 +#define STR_LEN_64 64 +#define STR_LEN_256 256 +#define STR_LEN_1024 1024 +#define NUM_MAX_METRIC_IN_TABLE 1024 +#define HISTOGRAM_WIDTH 10 +#define INSTANCE_NAME_LEN 32 +#define PROMETHEUS_ENDPOINT_DEFAULT_URL "/metrics" + + + enum field_calc_algo { FS_CALC_CURRENT=0, FS_CALC_SPEED }; +enum field_op +{ + FS_OP_ADD=1, + FS_OP_SET, + FS_OP_SUB +}; + + struct stat_unit_t { struct threadsafe_counter changing; @@ -77,14 +105,76 @@ struct metric_t { struct stat_unit_t counter; struct stat_unit_t gauge; - struct stat_unit_t single;//for status and field struct stat_unit_t* line; //for line struct histogram_t histogram; - int column_seq; //for column }; }; +struct fieldstat_instance +{ + char name[INSTANCE_NAME_LEN]; + //char *statsd_server_ip; + //char statsd_server_str_ip[LEN_IP_MAX]; + unsigned int statsd_server_ip; + unsigned short statsd_server_port; + int statsd_output_enable; + + //char line_protocol_server_str_ip[LEN_IP_MAX]; + unsigned int line_protocol_server_ip; + unsigned short line_protocol_server_port; + int line_protocol_output_enable; + + char local_output_filename[LEN_PATH_MAX]; + char local_output_format[LEN_FORMAT_MAX]; + int local_output_enable; + + int background_thread_disable; //default:1 + int output_interval_s; //default:2 + int running; + + struct metric_t **metric_block_list[BLOCK_LIST_SIZE]; + int metric_cnt; + int metric_size; + //struct metric_t **metric; + struct{ + struct metric_t **column; + size_t column_size; + } table_metrics[NUM_MAX_TABLE]; + int *index_table[NUM_MAX_TABLE][TABLE_COLUMN_SIZE]; + int per_table_line_number[NUM_MAX_TABLE]; + + int table_num; + int line_seq; + + int prometheus_output_enable; + + int histogram_cnt; + int summary_cnt; + + struct timespec last_output_time; + + pthread_t cfg_mon_t; + char line_protocol_send_buff[UDP_PAYLOAD_SIZE]; + size_t line_protocol_send_buff_offset; + int line_protocol_socket; + pthread_mutex_t output_lock; + + + FILE* fp; +}; + +struct prometheus_endpoint_instance +{ + unsigned short port; + char *url_path; + pthread_t tid; + int running; + struct http_server_s *server_handle; + int fs_instance_cnt; + struct fieldstat_instance **fs_instance; //TO refactor + int fs_instance_size; // number +}; diff --git a/src/fs2prometheus.cpp b/src/fs2prometheus.cpp deleted file mode 100644 index bb64d9f..0000000 --- a/src/fs2prometheus.cpp +++ /dev/null @@ -1,429 +0,0 @@ -//#include <stdio.h> -//#include <string.h> -#include <pthread.h> - -#define HTTPSERVER_IMPL -#include "httpserver.h" -#include "field_stat2.h" -#include "field_stat_internal.h" - -#define STEP_SIZE 1024 -#define LEFT_MIN_BUFF_LEN 256 -#define MAX_URL_PATH_LEN 128 -#define FS2_HANDLE_STEP_NUM 16 - -struct FS_library_runtime -{ - pthread_t tid; - int fs2_handle_cnt; - int using_fs2_handle_cnt; - unsigned short create_thread; - unsigned short port; - char *url_path; - struct http_server_s *server_handle; - pthread_mutex_t library_lock; - struct FS_space_t **fs2_handle; -}; - -struct FS_library_runtime g_FS2_LIBRARY_handle={ - 0, 0, 0, 0, 9273, NULL, NULL, PTHREAD_MUTEX_INITIALIZER, NULL}; - -static char* str_unescape(char* s, char *d, int d_len) -{ - int i=0,j=0; - int len=strlen(s); - for(i=0; i<len && j<d_len; i++) - { - if(s[i]=='(' || s[i]==')' || s[i]=='{' || s[i]=='}' || - s[i]=='/' || s[i]=='\\' || s[i]=='%' || s[i]=='*' || - s[i]=='$' || s[i]=='-' || s[i]==',' || s[i]==';') - { - if(i==0) - { - continue; - } - - d[j++]='_'; - } - else - { - d[j++]=s[i]; - } - } - - if(d[j-1]=='_') - { - j-=1; - } - - d[j]='\0'; - - return 0; -} - -static int check_http_request(struct FS_library_runtime *_handle, char *uri, int uri_len) -{ - int i=0; - if(uri_len==(int)strlen(_handle->url_path) && !(memcmp(uri, _handle->url_path, strlen(_handle->url_path)))) - { - return _handle->using_fs2_handle_cnt; - } - - for(i=0; i<_handle->using_fs2_handle_cnt; i++) - { - if(uri_len-1==(int)strlen(_handle->fs2_handle[i]->app_name) - && !(memcmp(uri+1, _handle->fs2_handle[i]->app_name, strlen(_handle->fs2_handle[i]->app_name)))) - { - return i; - } - } - - return -1; -} - -static int histgram_output_summary(display_manifest_t* p, char *app_name, double * bins, int bin_num, char*payload, int payload_len) -{ - long long value=0; - int i=0,used_len=0; - char line_name[128]={0}; - struct histogram_t* h=&(p->histogram); - struct hdr_histogram* h_out=NULL, *h_tmp=NULL; - - hdr_init(h->lowest_trackable_value, h->highest_trackable_value, h->significant_figures, &(h_tmp)); - - hdr_add(h_tmp, h->accumulated); - hdr_add(h_tmp, h->changing); - h_out=h_tmp; - - for(i=0;i<bin_num;i++) - { - value=(long long)hdr_value_at_percentile(h_out, bins[i]); - str_unescape(p->name, line_name, sizeof(line_name)); - used_len+=snprintf(payload+used_len, - payload_len-used_len, - "%s_%s{app_name=\"%s\",quantile=\"%f\"} %llu\n", - app_name, - line_name, - app_name, - bins[i]/100, - value - ); - } - - str_unescape(p->name, line_name, sizeof(line_name)); - used_len+=snprintf(payload+used_len, - payload_len-used_len, - "%s_%s_count{app_name=\"%s\"} %llu\n", - app_name, - line_name, - app_name, - (long long)(h_out->total_count) - ); - - hdr_close(h_tmp); - h_tmp=NULL; - - return used_len; -} - -static void FS_library_promethues_output(struct http_request_s* request) -{ - int i=0,j=0,k=0; - int payload_len=0; - int used_len=0; - long long value=0; - char* payload=NULL; - long long sum=0; - int output_cnt=0; - int check_flag=0; - char line_name[128]={0}; - char column_name[128]={0}; - char app_name[128]={0}; - struct hdr_iter iter; - struct FS_space_t *fs2_handle=NULL; - struct display_manifest_t *p=NULL,*p_column=NULL; - struct FS_library_runtime *_handle=(struct FS_library_runtime *)(&g_FS2_LIBRARY_handle); - - struct http_response_s* response=NULL; - struct http_string_s uri=http_request_target(request); - int fs2_handle_idx=check_http_request(_handle, (char *)uri.buf, uri.len); - if(fs2_handle_idx==-1) - { - payload_len=_handle->using_fs2_handle_cnt * 128; - payload=(char *)calloc(1, payload_len); - - used_len=strlen("url_path:\n\t"); - memcpy(payload, "url_path:\n\t", used_len); - - memcpy(payload+used_len, _handle->url_path, strlen(_handle->url_path)); - used_len+=strlen(_handle->url_path); - - for(i=0; i<_handle->using_fs2_handle_cnt; i++) - { - used_len+=snprintf(payload+used_len, payload_len-used_len, "\n\t/%s",_handle->fs2_handle[i]->app_name); - } - - payload[used_len++]='\n'; - payload[used_len]='\0'; - - response = http_response_init(); - http_response_status(response, 404); - http_response_header(response, "Content-Type", "text/plain; charset=utf-8"); - http_response_body(response, payload, strlen(payload)); - http_respond(request, response); - - free(payload); - payload=NULL; - return ; - } - - if(fs2_handle_idx==_handle->using_fs2_handle_cnt) - { - i=0; - check_flag=1; - output_cnt=_handle->using_fs2_handle_cnt; - } - else - { - check_flag=0; - i=fs2_handle_idx; - output_cnt=fs2_handle_idx+1; - } - - for(; i<output_cnt; i++) - { - fs2_handle=_handle->fs2_handle[i]; - if(fs2_handle->running==0 || (check_flag==1 && fs2_handle->output_prometheus!=1)) - { - continue; - } - - pthread_mutex_lock(&(fs2_handle->reg_lock)); - for(k=0;k<fs2_handle->display_cnt;k++) - { - p=fs2_handle->display[k]; - if(p->not_send_to_server==1||p->is_ratio==1) - { - continue; - } - - if(payload_len-used_len<=LEFT_MIN_BUFF_LEN) - { - payload_len+=STEP_SIZE; - payload=(char *)realloc(payload, payload_len); - } - - switch(p->style) - { - case FS_STYLE_STATUS: - case FS_STYLE_FIELD: - str_unescape(p->name, line_name, sizeof(line_name)); - str_unescape(fs2_handle->app_name, app_name, sizeof(app_name)); - value=get_stat_unit_val(p, 0, FS_CALC_CURRENT, 1); - used_len+=snprintf(payload+used_len, - payload_len-used_len, - "%s_%s{app_name=\"%s\"} %llu\n", - app_name, - line_name, - app_name, - value - ); - break; - case FS_STYLE_LINE: - for(j=0;j<fs2_handle->column_cnt;j++) - { - p_column=fs2_handle->display[fs2_handle->cloumn_id[j]]; - if(p_column->not_send_to_server==1||p_column->is_ratio==1) - { - continue; - } - str_unescape(p->name, line_name, sizeof(line_name)); - str_unescape(p_column->name, column_name, sizeof(column_name)); - str_unescape(fs2_handle->app_name, app_name, sizeof(app_name)); - value=get_stat_unit_val(p, p_column->column_seq, FS_CALC_CURRENT, 1); - used_len+=snprintf(payload+used_len, - payload_len-used_len, - "%s_%s{app_name=\"%s\",line_name=\"%s\"} %llu\n", - app_name, - column_name, - app_name, - line_name, - value - ); - - if(payload_len-used_len<=LEFT_MIN_BUFF_LEN) - { - payload_len+=STEP_SIZE; - payload=(char *)realloc(payload, payload_len); - } - } - break; - case FS_STYLE_HISTOGRAM: - if(p->style!=FS_STYLE_HISTOGRAM) - { - continue; - } - - if(payload_len-used_len<=STEP_SIZE) - { - payload_len+=STEP_SIZE; - payload=(char *)realloc(payload, payload_len); - } - - str_unescape(fs2_handle->app_name, app_name, sizeof(app_name)); - - used_len+=histgram_output_summary(p, - app_name, - fs2_handle->histogram_bins, - fs2_handle->histogram_bin_num, - payload+used_len, - payload_len-used_len - ); - - if(p->histogram.previous_changed!=NULL) - { - hdr_iter_recorded_init(&iter, p->histogram.accumulated); - while (hdr_iter_next(&iter)) - { - sum+=(long long)iter.value; - } - - str_unescape(p->name, line_name, sizeof(line_name)); - str_unescape(fs2_handle->app_name, app_name, sizeof(app_name)); - used_len+=snprintf(payload+used_len, - payload_len-used_len, - "%s_%s_sum{app_name=\"%s\"} %llu\n", - app_name, - line_name, - app_name, - sum - ); - - if(payload_len-used_len<=LEFT_MIN_BUFF_LEN) - { - payload_len+=STEP_SIZE; - payload=(char *)realloc(payload, payload_len); - } - } - break; - default: - break; - } - } - pthread_mutex_unlock(&(fs2_handle->reg_lock)); - } - - if(payload!=NULL) - { - response = http_response_init(); - http_response_status(response, 200); - http_response_header(response, "Content-Type", "text/plain; charset=utf-8"); - http_response_body(response, payload, strlen(payload)); - http_respond(request, response); - - free(payload); - payload=NULL; - } - - return; -} - -void *FS_library_promethues_listen(void *arg) -{ - struct FS_library_runtime *_handle=(struct FS_library_runtime *)arg; - - if(_handle!=NULL) - { - _handle->server_handle=http_server_init(_handle->port, FS_library_promethues_output); - //pthread_testcancel(); - http_server_listen(_handle->server_handle); - } - - return NULL; -} - -int FS_library_promethues_register(screen_stat_handle_t handle) -{ - struct FS_library_runtime *_handle=&g_FS2_LIBRARY_handle; - if(handle!=NULL) - { - if(_handle->fs2_handle==NULL - || _handle->using_fs2_handle_cnt >= _handle->fs2_handle_cnt) - { - _handle->fs2_handle_cnt+=FS2_HANDLE_STEP_NUM; - _handle->fs2_handle=(struct FS_space_t **)realloc(_handle->fs2_handle, sizeof(struct FS_space_t *)*(_handle->fs2_handle_cnt)); - } - - pthread_mutex_lock(&_handle->library_lock); - int i=_handle->using_fs2_handle_cnt; - _handle->fs2_handle[i]=(struct FS_space_t *)handle; - _handle->using_fs2_handle_cnt++; - pthread_mutex_unlock(&_handle->library_lock); - - return 1; - } - - return 0; -} - - -int FS_library_set_prometheus_port(unsigned short port) -{ - g_FS2_LIBRARY_handle.port=port; - - return 1; -} -int FS_library_set_prometheus_url_path(const char *url_path) -{ - if(g_FS2_LIBRARY_handle.url_path != NULL) - { - free(g_FS2_LIBRARY_handle.url_path); - g_FS2_LIBRARY_handle.url_path = NULL; - } - g_FS2_LIBRARY_handle.url_path=(char *)calloc(1, strlen(url_path)+1); - memcpy(g_FS2_LIBRARY_handle.url_path, url_path, strlen(url_path)); - - return 1; -} - -int FS_library_init(void) -{ - if(g_FS2_LIBRARY_handle.url_path == NULL) - { - g_FS2_LIBRARY_handle.url_path = (char *)calloc(strlen((char *)"/metrics")+1, 1); - memcpy(g_FS2_LIBRARY_handle.url_path, (char *)"/metrics", strlen((char *)"/metrics")); - } - g_FS2_LIBRARY_handle.create_thread = 1; - pthread_create(&g_FS2_LIBRARY_handle.tid, NULL, FS_library_promethues_listen, (void *)&g_FS2_LIBRARY_handle); - - return 0; - -} - -void FS_library_destroy(void) -{ - void* ret ; - if(g_FS2_LIBRARY_handle.create_thread == 1) - { - g_FS2_LIBRARY_handle.create_thread = 0; - pthread_cancel(g_FS2_LIBRARY_handle.tid); - pthread_join(g_FS2_LIBRARY_handle.tid, &ret); - } - if(g_FS2_LIBRARY_handle.url_path != NULL) - { - free(g_FS2_LIBRARY_handle.url_path); - g_FS2_LIBRARY_handle.url_path = NULL; - } - if(g_FS2_LIBRARY_handle.fs2_handle) - { - free(g_FS2_LIBRARY_handle.fs2_handle); - g_FS2_LIBRARY_handle.fs2_handle=NULL; - } - - g_FS2_LIBRARY_handle.using_fs2_handle_cnt=0; - g_FS2_LIBRARY_handle.fs2_handle_cnt=0; - - return ; - -} - diff --git a/test/fs2_test.cpp b/test/fieldstat_test.cpp index 3c16f29..88389c4 100644 --- a/test/fs2_test.cpp +++ b/test/fieldstat_test.cpp @@ -50,6 +50,7 @@ int main(int argc, char *argv[]) const char *field_list_0[] = {"c0", "c1", "c2"}; struct metric_id_list id_list; + fieldstat_global_enable_prometheus_endpoint(9010, "/metrics"); test_instance = fieldstat_instance_create("test"); @@ -66,7 +67,7 @@ int main(int argc, char *argv[]) printf("Set output_interval failed!\n"); } - ret = fieldstat_backgroud_thead_disable(test_instance); + ret = fieldstat_background_thead_disable(test_instance); if(ret == -1) { printf("Set backgroud thread disable failed!\n"); |
