summaryrefslogtreecommitdiff
path: root/service/src/monit.c
blob: 08263fd26e62f5a8edbfe0d3b4a12994729e39fd (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
284
285
286
287
288
289
290
291
/* \brief 状态监测数据输出
 *
 * \author Lu Qiuwen<[email protected]>
 * \date 2016-11-30
 */

#include <rte_ethdev.h>
#include <rte_latencystats.h>
#include <rte_malloc.h>
#include <rte_pci.h>
#include <sc_common.h>
#include <sc_devmgr.h>
#include <sc_vdev.h>

#include "cJSON.h"
#include "common.h"

extern unsigned int g_monit_interval;

static cJSON * __create_uint64_array(const uint64_t * value, int nr_value)
{
    struct cJSON * uint64_array = cJSON_CreateArray();
    for (int i = 0; i < nr_value; i++)
    {
        cJSON_AddItemToArray(uint64_array, cJSON_CreateNumber(value[i]));
    }

    return uint64_array;
}

static cJSON * __create_uint64_delta_array(const uint64_t * value_large, const uint64_t * value_small, int nr_value,
                                           int interval)
{
    struct cJSON * uint64_array = cJSON_CreateArray();
    for (int i = 0; i < nr_value; i++)
    {
        uint64_t delta = (value_large[i] - value_small[i]) / interval;
        cJSON_AddItemToArray(uint64_array, cJSON_CreateNumber(delta));
    }

    return uint64_array;
}

static cJSON * __create_vdev_stats(struct vdev * vdev, unsigned int nr_serv_thread)
{
    struct vdev_stat_info _stat_info;
    struct vdev_stat_info _stat_info_last;

    vdev_stats_get(vdev, &_stat_info);
    vdev_stats_last_get(vdev, &_stat_info_last);
    vdev_stats_last_save(vdev, &_stat_info);

    /* 统计节点句柄 */
    struct cJSON * j_vdev_stats = cJSON_CreateObject();
    /* 累计量 */
    struct cJSON * j_vdev_value = cJSON_CreateObject();
    /* 瞬时值 */
    struct cJSON * j_vdev_speed = cJSON_CreateObject();

#define __JOIN_VDEV_VALUE_STATS_ITEM(item)                                                                             \
    do                                                                                                                 \
    {                                                                                                                  \
        cJSON_AddItemToObject(j_vdev_value, #item, __create_uint64_array(_stat_info.item, nr_serv_thread));            \
    } while (0)

    __JOIN_VDEV_VALUE_STATS_ITEM(rx_on_line);
    __JOIN_VDEV_VALUE_STATS_ITEM(rx_deliver);
    __JOIN_VDEV_VALUE_STATS_ITEM(rx_missed);
    __JOIN_VDEV_VALUE_STATS_ITEM(rx_total_len);

    __JOIN_VDEV_VALUE_STATS_ITEM(tx_on_line);
    __JOIN_VDEV_VALUE_STATS_ITEM(tx_deliver);
    __JOIN_VDEV_VALUE_STATS_ITEM(tx_missed);
    __JOIN_VDEV_VALUE_STATS_ITEM(tx_total_len);

    __JOIN_VDEV_VALUE_STATS_ITEM(ftx_on_line);
    __JOIN_VDEV_VALUE_STATS_ITEM(ftx_deliver);
    __JOIN_VDEV_VALUE_STATS_ITEM(ftx_missed);
    __JOIN_VDEV_VALUE_STATS_ITEM(ftx_total_len);

    __JOIN_VDEV_VALUE_STATS_ITEM(ltx_on_line);
    __JOIN_VDEV_VALUE_STATS_ITEM(ltx_deliver);
    __JOIN_VDEV_VALUE_STATS_ITEM(ltx_missed);
    __JOIN_VDEV_VALUE_STATS_ITEM(ltx_total_len);

    /* notify events */
#if 0
    __JOIN_VDEV_VALUE_STATS_ITEM(notify_state_waiting);
    __JOIN_VDEV_VALUE_STATS_ITEM(notify_state_running);
    __JOIN_VDEV_VALUE_STATS_ITEM(notify_state_ready);
#endif

    __JOIN_VDEV_VALUE_STATS_ITEM(batch_size_total);
    __JOIN_VDEV_VALUE_STATS_ITEM(batch_size_count);

#define __JOIN_VDEV_SPEED_STATS_ITEM(item)                                                                             \
    do                                                                                                                 \
    {                                                                                                                  \
        cJSON_AddItemToObject(                                                                                         \
            j_vdev_speed, #item,                                                                                       \
            __create_uint64_delta_array(_stat_info.item, _stat_info_last.item, nr_serv_thread, g_monit_interval));     \
    } while (0)

    __JOIN_VDEV_SPEED_STATS_ITEM(rx_on_line);
    __JOIN_VDEV_SPEED_STATS_ITEM(rx_deliver);
    __JOIN_VDEV_SPEED_STATS_ITEM(rx_missed);
    __JOIN_VDEV_SPEED_STATS_ITEM(rx_total_len);

    __JOIN_VDEV_SPEED_STATS_ITEM(tx_on_line);
    __JOIN_VDEV_SPEED_STATS_ITEM(tx_deliver);
    __JOIN_VDEV_SPEED_STATS_ITEM(tx_missed);
    __JOIN_VDEV_SPEED_STATS_ITEM(tx_total_len);

    __JOIN_VDEV_SPEED_STATS_ITEM(ftx_on_line);
    __JOIN_VDEV_SPEED_STATS_ITEM(ftx_deliver);
    __JOIN_VDEV_SPEED_STATS_ITEM(ftx_missed);
    __JOIN_VDEV_SPEED_STATS_ITEM(ftx_total_len);

    __JOIN_VDEV_SPEED_STATS_ITEM(ltx_on_line);
    __JOIN_VDEV_SPEED_STATS_ITEM(ltx_deliver);
    __JOIN_VDEV_SPEED_STATS_ITEM(ltx_missed);
    __JOIN_VDEV_SPEED_STATS_ITEM(ltx_total_len);

    cJSON_AddItemToObject(j_vdev_stats, "accumulative", j_vdev_value);
    cJSON_AddItemToObject(j_vdev_stats, "speed", j_vdev_speed);
    return j_vdev_stats;
}

static cJSON * monit_pkt_latency_global(struct sc_main * sc)
{
    if (sc->en_pkt_latency == 0)
    {
        return NULL;
    }

    static struct rte_metric_name * metric_names = NULL;
    static struct rte_metric_value * metric_values = NULL;
    static unsigned int nr_metrics = 0;

    if (metric_names == NULL)
    {
        nr_metrics = rte_latencystats_get_names(NULL, 0);
        metric_names = ZMALLOC(sizeof(struct rte_metric_name) * nr_metrics);
        metric_values = ZMALLOC(sizeof(struct rte_metric_value) * nr_metrics);

        rte_latencystats_get_names(metric_names, nr_metrics);
        rte_latencystats_get(metric_values, nr_metrics);
    }

    assert(metric_names != NULL);
    assert(metric_values != NULL);

    rte_latencystats_update();

    /* get the metric value */
    cJSON * j_metric = cJSON_CreateObject();
    rte_latencystats_get(metric_values, nr_metrics);

    for (unsigned int i = 0; i < nr_metrics; i++)
    {
        struct rte_metric_name * name_iter = &metric_names[i];
        struct rte_metric_value * value_iter = &metric_values[i];
        cJSON_AddNumberToObject(j_metric, name_iter->name, value_iter->value);
    }

    return j_metric;
}

// 运行时原始报文设备统计计数
static cJSON * monit_vdev(struct sc_main * sc)
{
    struct cJSON * j_raw_device_array = cJSON_CreateArray();
    struct vdev * vdev_iter = NULL;
    unsigned int vdev_next = 0;

    while (vdev_iterate(sc->vdev_main, &vdev_iter, &vdev_next) >= 0)
    {
        cJSON * j_vdev = cJSON_CreateObject();
        cJSON_AddStringToObject(j_vdev, "symbol", vdev_iter->symbol);
        cJSON_AddItemToObject(j_vdev, "stats", __create_vdev_stats(vdev_iter, sc->nr_io_thread));
        cJSON_AddItemToArray(j_raw_device_array, j_vdev);
    }

    return j_raw_device_array;
}

// 基础运行参数
static cJSON * monit_service_info(struct sc_main * sc)
{
    struct cJSON * j_service_info = cJSON_CreateObject();
    time_t _now_time = time(NULL);

    cJSON_AddNumberToObject(j_service_info, "unixtime", _now_time);
    cJSON_AddStringToObject(j_service_info, "g_cfgfile", sc->local_cfgfile);
    cJSON_AddStringToObject(j_service_info, "g_hwfile", sc->local_hwfile);
    return j_service_info;
}

extern cJSON * mrb_monit_loop(struct sc_main * sc);
extern cJSON * app_monit_loop(struct sc_main * sc);
extern cJSON * malloc_monit_loop(struct sc_main * sc);
extern cJSON * service_monit_loop(struct sc_main * sc);
extern cJSON * vwire_ingress_node_monit_loop(struct sc_main * sc);
extern cJSON * classifier_node_monit_loop(struct sc_main * sc);
extern cJSON * forwarder_node_monit_loop(struct sc_main * sc);
extern cJSON * vwire_egress_node_monit_loop(struct sc_main * sc);
extern cJSON * lb_node_monit_loop(struct sc_main * sc);
extern cJSON * ef_ingress_node_monit_loop(struct sc_main * sc);
extern cJSON * ef_egress_node_monit_loop(struct sc_main * sc);
extern cJSON * eth_ingress_node_monit_loop(struct sc_main * sc);
extern cJSON * bridge_node_monit_loop(struct sc_main * sc);
extern cJSON * eth_egress_node_monit_loop(struct sc_main * sc);
extern cJSON * bfd_node_monit_loop(struct sc_main * sc);
extern cJSON * shmdev_tx_node_monit_loop(struct sc_main * sc);
extern cJSON * shmdev_rx_node_monit_loop(struct sc_main * sc);
extern cJSON * health_check_ask_node_monit_loop(struct sc_main * sc);
extern cJSON * health_check_deal_answer_node_monit_loop(struct sc_main * sc);
extern cJSON * health_check_session_monit_loop(struct sc_main * sc);
extern cJSON * forwarder_table_monit_loop(struct sc_main * sc);
extern cJSON * ef_peer_monit_loop(struct sc_main * sc);
extern cJSON * olp_manager_monit_loop(struct sc_main * sc);
extern cJSON * tera_ingress_node_monit_loop(struct sc_main * sc);
extern cJSON * tera_egress_node_monit_loop(struct sc_main * sc);
extern cJSON * devmgr_monit_loop(struct sc_main * sc);
extern cJSON * dp_trace_monit_loop(struct sc_main * sc);
extern cJSON * phydev_rx_node_monit_loop(struct sc_main * sc);
extern cJSON * lai_node_monit_loop(struct sc_main * sc);

static cJSON * monit_root(struct sc_main * sc)
{
    struct cJSON * j_root = cJSON_CreateObject();
    cJSON_AddItemToObject(j_root, "general", monit_service_info(sc));
    cJSON_AddItemToObject(j_root, "device", devmgr_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "raw", monit_vdev(sc));
    cJSON_AddItemToObject(j_root, "mrb", mrb_monit_loop(sc));
#if 0
    cJSON_AddItemToObject(j_root, "malloc", malloc_monit_loop(sc));
#endif
    cJSON_AddItemToObject(j_root, "app", app_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "service", service_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "pkt_latency", monit_pkt_latency_global(sc));

    // cJSON_AddItemToObject(j_root, "offload", smartoffload_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "phydev", phydev_rx_node_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "eth-ingress", eth_ingress_node_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "bridge", bridge_node_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "vwire-ingress", vwire_ingress_node_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "ef-ingress", ef_ingress_node_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "tera-ingress", tera_ingress_node_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "bfd", bfd_node_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "classifier", classifier_node_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "forwarder", forwarder_node_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "link-aware-injector", lai_node_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "vwire-egress", vwire_egress_node_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "lb", lb_node_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "ef-egress", ef_egress_node_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "tera-egress", tera_egress_node_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "shmdev_tx", shmdev_tx_node_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "shmdev_rx", shmdev_rx_node_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "eth-egress", eth_egress_node_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "health-check-ask", health_check_ask_node_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "health-check-deal-answer", health_check_deal_answer_node_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "health-session-state", health_check_session_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "forwarder-table", forwarder_table_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "ef-peer-table", ef_peer_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "OBP", olp_manager_monit_loop(sc));
    cJSON_AddItemToObject(j_root, "dp-trace-path", dp_trace_monit_loop(sc));

    return j_root;
}

int sc_monit_loop(struct sc_main * sc)
{
    cJSON * j_root = monit_root(sc);
    char * str_json_print = cJSON_Print(j_root);

    FILE * fp_monit = fopen(sc->local_monitfile, "w");
    if (fp_monit == NULL)
    {
        MR_WARNING("monit file %s open failed, cannot dump program stat info : %s", sc->local_monitfile,
                   strerror(errno));
        return 0;
    }

    fprintf(fp_monit, "%s", str_json_print);
    fclose(fp_monit);
    free(str_json_print);
    cJSON_Delete(j_root);

    return 0;
}