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
|
#include <assert.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include "http_decoder_stat.h"
#ifdef __cplusplus
extern "C"
{
#endif
static const struct hd_stat_config_tuple g_httpd_stat_tuple[HTTP_STAT_MAX] =
{
{HTTP_C2S_BYTES, "http_c2s_bytes"},
{HTTP_S2C_BYTES, "http_s2c_bytes"},
{HTTP_C2S_TCP_SEG, "http_c2s_tcp_seg"},
{HTTP_S2C_TCP_SEG, "http_s2c_tcp_seg"},
{HTTP_C2S_HEADERS, "http_c2s_headers"},
{HTTP_S2C_HEADERS, "http_s2c_headers"},
{HTTP_C2S_ZIP_BYTES, "http_c2s_zip_bytes"},
{HTTP_S2C_ZIP_BYTES, "http_s2c_zip_bytes"},
{HTTP_C2S_UNZIP_BYTES, "http_c2s_unzip_bytes"},
{HTTP_S2C_UNZIP_BYTES, "http_s2c_unzip_bytes"},
{HTTP_URL_BYTES, "http_url_bytes"},
{HTTP_SESSION_NEW, "http_session_new"},
{HTTP_SESSION_FREE, "http_session_free"},
{HTTP_TRANSACTION_NEW, "http_transaction_new"},
{HTTP_TRANSACTION_FREE, "http_transaction_free"},
{HTTP_C2S_ASYMMETRY_SESSION, "http_c2s_asymmetry_sess"},
{HTTP_S2C_ASYMMETRY_SESSION, "http_s2c_asymmetry_sess"},
{HTTP_C2S_ASYMMETRY_TRANSACTION, "http_c2s_asymmetry_trans"},
{HTTP_S2C_ASYMMETRY_TRANSACTION, "http_s2c_asymmetry_trans"},
{HTTP_STAT_PARSE_ERR, "http_parse_error"},
};
void http_stat_free(struct http_stat *hd_stat)
{
if (hd_stat->fs4_ins != NULL)
{
fieldstat_easy_free(hd_stat->fs4_ins);
}
}
static struct fieldstat_easy *http_get_fs4_ins(struct module_manager *mod_mgr)
{
// todo: use stellar global fieldstat4 instance
struct fieldstat_easy *fs4 = fieldstat_easy_new(module_manager_get_max_thread_num(mod_mgr), "HTTP", NULL, 0);
fieldstat_easy_enable_auto_output(fs4, "./log/http.fs4", 1);
return fs4;
}
int http_stat_init(struct module_manager *mod_mgr, struct http_stat *hd_stat)
{
assert(sizeof(g_httpd_stat_tuple) / sizeof(struct hd_stat_config_tuple) == HTTP_STAT_MAX);
if (sizeof(g_httpd_stat_tuple) / sizeof(struct hd_stat_config_tuple) != HTTP_STAT_MAX)
{
fprintf(stderr, "enum http_decoder_stat_type number not match with g_httpd_stat_tuple!");
return -1;
}
hd_stat->fs4_ins = http_get_fs4_ins(mod_mgr);
if (NULL == hd_stat->fs4_ins)
{
fprintf(stderr, "fieldstat_easy_new failed.");
return -1;
}
for (int i = 0; i < HTTP_STAT_MAX; i++)
{
hd_stat->field_stat_id[i] = fieldstat_easy_register_counter(hd_stat->fs4_ins, g_httpd_stat_tuple[i].name);
if (hd_stat->field_stat_id[i] < 0)
{
fprintf(stderr, "fieldstat_easy_register_counter %s failed.", g_httpd_stat_tuple[i].name);
fieldstat_easy_free(hd_stat->fs4_ins);
hd_stat->fs4_ins = NULL;
return -1;
}
}
return 0;
}
void http_stat_update(struct http_stat *hd_stat, int thread_id, enum http_decoder_stat_type type, long long value)
{
assert(hd_stat);
assert(thread_id >= 0);
assert(type < HTTP_STAT_MAX);
// todo: performance optimization, use batch update
fieldstat_easy_counter_incrby(hd_stat->fs4_ins, thread_id, hd_stat->field_stat_id[type], NULL, 0, value);
}
void http_stat_update_tcp_seg(struct http_stat *stat, int thread_id, enum flow_type ftype, long long value)
{
if (FLOW_TYPE_C2S == ftype)
{
http_stat_update(stat, thread_id, HTTP_C2S_BYTES, value);
http_stat_update(stat, thread_id, HTTP_C2S_TCP_SEG, 1);
}
else
{
http_stat_update(stat, thread_id, HTTP_S2C_BYTES, value);
http_stat_update(stat, thread_id, HTTP_S2C_TCP_SEG, 1);
}
}
#ifdef __cplusplus
}
#endif
|