summaryrefslogtreecommitdiff
path: root/src/fieldstat_internal.h
blob: e471116cc1b6b1761ca600823dfe843d25e3970f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
#pragma once

#include <pthread.h>
#include "hdr_histogram.h"
#include "threadsafe_counter.h"
#include "fieldstat.h"
#include <assert.h>
#include <string.h>
#include "cJSON.h"
#include <sys/socket.h>//socket
#include <sys/types.h>//socket
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h> //strerror
#include <errno.h>//strerror
#include <fcntl.h>//fcntl
#include <unistd.h>//fcntl
#include <net/if.h>//fcntl
#include <sys/ioctl.h>//ioctl
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <pthread.h>
#include <assert.h>
#include <sys/time.h>
#include "uthash.h"

#define	INIT_STAT_FIELD_NUM		1024
#define MAX_PATH_LEN			256

#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



#define N_TAG_MAX				32
#define	NUM_INIT_METRICS		16384
#define	BLOCK_LIST_SIZE			16384


#define URL_MAX_LEN			2048
#define LEN_IP_MAX			32  //?????? 32 from document 
#define LEN_FORMAT_MAX		32
#define LEN_PATH_MAX		256
#define	TABLE_MAX_NUM		64
#define TABLE_COLUMN_SIZE	64
#define	UDP_PAYLOAD_SIZE	512
#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"
#define	TABLE_LINE_SCALE_NUM		1024

#define METRIC_SIZE	1024



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;
	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;
	int bins_num;
	double *bins;
};

struct table_line
{
	char *name;
	size_t n_tag;
	char *tag_key[N_TAG_MAX];
	char *tag_value[N_TAG_MAX];

	int metric_id_belong_to_line[TABLE_COLUMN_SIZE];
};

struct table_metric
{
	char *name;
	char *column_name[TABLE_COLUMN_SIZE];
	enum field_type column_type[TABLE_COLUMN_SIZE];
	int column_invisible[TABLE_COLUMN_SIZE];
	int column_cnt;

	int line_cnt;
	struct table_line **line_block[BLOCK_LIST_SIZE];
};


struct metric
{
	char *field_name;
	enum field_type field_type;
	size_t n_tag;
	char *tag_key[N_TAG_MAX];
	char *tag_value[N_TAG_MAX];
	int output_scaling;

	int is_invisible;
	int is_ratio;
	int not_send_to_server;
	int numerator_id;
	int denominator_id;
	struct table_metric *table;
	int table_column_id;
	int output_window;

	union
	{
		struct stat_unit_t counter;
		struct stat_unit_t gauge;
		struct histogram_t histogram;
	};
};


struct line_protocol_output
{
	unsigned int server_ip;
	unsigned short server_port;
	int send_socket;
	char send_buf[UDP_PAYLOAD_SIZE];
	unsigned int send_buf_offset;
};

struct fieldstat_instance
{
	char name[INSTANCE_NAME_LEN];
	unsigned int statsd_server_ip;
	unsigned short statsd_server_port;
	int statsd_output_enable;

	char local_output_filename[LEN_PATH_MAX];
	char local_output_format[LEN_FORMAT_MAX];
	int local_output_enable;
	FILE* local_output_fp;

	struct line_protocol_output line_protocol_output;
	int line_protocol_output_enable;

	int background_thread_disable;
	pthread_t background_thread;
	int background_thread_is_created;

	int output_interval_ms;
	int running;

	struct metric **metric_block_list[BLOCK_LIST_SIZE];

	int metric_cnt;
	//struct metric **metric;

	struct table_metric *table_metrics[TABLE_MAX_NUM];

	int table_num;

	int prometheus_output_enable;

	int histogram_cnt;
	int summary_cnt;

	struct timespec last_output_time;
	int output_type;   // 0b0000:not output, 0b1000:output file, 0b0100:output line_protocol, 0b0010: output statsd, 0b0001: output prometheus 
};

struct prometheus_endpoint_instance
{
	unsigned short port;
	char *url_path;
	pthread_t tid;
	int thread_created;
	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 dynamic_metric
{
	char metric_key[METRIC_SIZE];
	unsigned int metric_keylen;

	struct metric **metrics;
	UT_hash_handle hh;
};

struct fieldstat_dynamic_instance
{
	char name[INSTANCE_NAME_LEN];
	struct line_protocol_output line_protocol_output;
	int line_protocol_output_enable;

	int background_thread_disable;
	int output_interval_ms;
	int running;

	struct table_metric *table_metrics[TABLE_MAX_NUM];
	int table_num;
	struct timespec last_output_time;

	pthread_t background_thread;
	int background_thread_is_created;

	struct dynamic_metric **n_thread_dynamic_metric;
	int n_thread;
	int output_type;   // 0b0000:not output, 0b1000:output file, 0b0100:output line_protocol, 0b0010: output statsd, 0b0001: output prometheus 
	pthread_spinlock_t *uthash_locks;
};

void prometheus_endpoint_instance_output(struct http_request_s* request);

char* __str_dup(const char* str);
long long hdr_count_le_value(const struct hdr_histogram* h, long long value);
struct metric * get_metric(struct fieldstat_instance *instance, int metric_id);
long long get_metric_unit_val(struct metric *metric,enum field_calc_algo calc_type,int is_refer);
long long read_metric_current_value(struct metric *metric);
int is_valid_field_name(const char* name);
int is_valid_tags(const struct fieldstat_tag *tags, size_t n_tags);
struct metric ** read_metric_slot(struct fieldstat_instance *instance, int metric_id);
struct metric * metric_new(enum field_type type, const char *field_name, const struct fieldstat_tag tags[], size_t n_tag);
void metric_free(struct metric *metric);
int file_output(struct fieldstat_instance *instance,long long interval_ms);
struct table_line * read_table_line(struct table_metric *table, int line_id);
int send_udp(int sd, unsigned int dest_ip, unsigned short dest_port, const char * data, int len);
int line_protocol_output(struct fieldstat_instance *instance);
void get_current_table_line_cnt(struct fieldstat_instance *instance, int n_table, int *table_line_cnt);
int startup_udp();

void metric_value_operate(struct metric *metric, enum field_op op, long long value);
struct table_metric* table_metric_new(const char *name, const char *column_name[], enum field_type column_type[], size_t n_column);
void table_metric_free(struct table_metric *table);

struct table_line *table_line_new(const char *name, const struct fieldstat_tag tags[],size_t n_tag);
void table_line_free(struct table_line *table_line);
int line_protocol_dynamic_metric_output(struct fieldstat_dynamic_instance *instance);

struct table_line ** read_table_line_slot(struct table_metric *table, int line_id);

void fieldstat_global_disable_prometheus_endpoint();

int enable_line_protocol_output(struct line_protocol_output *line_protocol_output, const char *ip, unsigned short port);
void disable_line_protocol_output(struct line_protocol_output *line_protocol_output);

void escaping_special_chars(char* str);

int escaping_special_chars_cpoy(char *dest, char *src, size_t n);