summaryrefslogtreecommitdiff
path: root/decoders/http/http_decoder_stat.c
blob: a8240c207199fe90160a2191ad48d10e81d6534f (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
#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