suricata
output-json-stats.c
Go to the documentation of this file.
1 /* Copyright (C) 2024 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 #include "../suricata-common.h"
19 
20 #include "../output-json-stats.h"
21 
22 #include "../util-unittest.h"
23 
24 static int OutputJsonStatsTest01(void)
25 {
26  StatsRecord total_records[] = { { 0 }, { 0 } };
27  StatsRecord thread_records[2];
28  thread_records[0].name = "capture.kernel_packets";
29  thread_records[0].short_name = "kernel_packets";
30  thread_records[0].tm_name = "W#01-bond0.30";
31  thread_records[0].value = 42;
32  thread_records[1].name = "capture.kernel_drops";
33  thread_records[1].short_name = "kernel_drops";
34  thread_records[1].tm_name = "W#01-bond0.30";
35  thread_records[1].value = 4711;
36 
37  StatsTable table = {
38  .nstats = 2,
39  .stats = &total_records[0],
40  .ntstats = 1,
41  .tstats = &thread_records[0],
42  };
43 
44  json_t *r = StatsToJSON(&table, JSON_STATS_TOTALS | JSON_STATS_THREADS);
45  if (!r)
46  return 0;
47 
48  // Remove variable content
49  json_object_del(r, "uptime");
50 
51  char *serialized = json_dumps(r, 0);
52 
53  // Cheesy comparison
54  const char *expected = "{\"threads\": {\"W#01-bond0.30\": {\"capture\": {\"kernel_packets\": "
55  "42, \"kernel_drops\": 4711}}}}";
56 
57  int cmp_result = strcmp(expected, serialized);
58  if (cmp_result != 0)
59  printf("unexpected result\nexpected=%s\ngot=%s\n", expected, serialized);
60 
61  free(serialized);
62  json_decref(r);
63 
64  return cmp_result == 0;
65 }
66 
67 static int OutputJsonStatsTest02(void)
68 {
69  StatsRecord total_records[4] = { 0 };
70  StatsRecord thread_records[8] = { 0 };
71 
72  // Totals
73  total_records[0].name = "tcp.syn";
74  total_records[0].short_name = "syn";
75  total_records[0].tm_name = NULL;
76  total_records[0].value = 1234;
77 
78  // Worker
79  // thread_records[0] is a global counter
80  thread_records[1].name = "capture.kernel_packets";
81  thread_records[1].short_name = "kernel_packets";
82  thread_records[1].tm_name = "W#01-bond0.30";
83  thread_records[1].value = 42;
84  thread_records[2].name = "capture.kernel_drops";
85  thread_records[2].short_name = "kernel_drops";
86  thread_records[2].tm_name = "W#01-bond0.30";
87  thread_records[2].value = 4711;
88  // thread_records[3] is a FM specific counter
89 
90  // Flow manager
91  // thread_records[4] is a global counter
92  // thread_records[5] is a worker specific counter
93  // thread_records[6] is a worker specific counter
94  thread_records[7].name = "flow.mgr.full_hash_passes";
95  thread_records[7].short_name = "full_hash_passes";
96  thread_records[7].tm_name = "FM#01";
97  thread_records[7].value = 10;
98 
99  StatsTable table = {
100  .nstats = 4,
101  .stats = &total_records[0],
102  .ntstats = 2,
103  .tstats = &thread_records[0],
104  };
105 
106  json_t *r = StatsToJSON(&table, JSON_STATS_TOTALS | JSON_STATS_THREADS);
107  if (!r)
108  return 0;
109 
110  // Remove variable content
111  json_object_del(r, "uptime");
112 
113  char *serialized = json_dumps(r, 0);
114 
115  // Cheesy comparison
116  const char *expected = "{\"tcp\": {\"syn\": 1234}, \"threads\": {\"W#01-bond0.30\": "
117  "{\"capture\": {\"kernel_packets\": "
118  "42, \"kernel_drops\": 4711}}, \"FM#01\": {\"flow\": {\"mgr\": "
119  "{\"full_hash_passes\": 10}}}}}";
120 
121  int cmp_result = strcmp(expected, serialized);
122  if (cmp_result != 0)
123  printf("unexpected result\nexpected=%s\ngot=%s\n", expected, serialized);
124 
125  free(serialized);
126  json_decref(r);
127 
128  return cmp_result == 0;
129 }
130 
132 {
133  UtRegisterTest("OutputJsonStatsTest01", OutputJsonStatsTest01);
134  UtRegisterTest("OutputJsonStatsTest02", OutputJsonStatsTest02);
135 }
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
StatsRecord_
Definition: output-stats.h:31
JSON_STATS_TOTALS
#define JSON_STATS_TOTALS
Definition: output-json-stats.h:29
StatsRecord_::name
const char * name
Definition: output-stats.h:32
StatsTable_
Definition: output-stats.h:39
StatsRecord_::value
int64_t value
Definition: output-stats.h:35
StatsToJSON
json_t * StatsToJSON(const StatsTable *st, uint8_t flags)
turn StatsTable into a json object
Definition: output-json-stats.c:211
StatsRecord_::tm_name
const char * tm_name
Definition: output-stats.h:34
JSON_STATS_THREADS
#define JSON_STATS_THREADS
Definition: output-json-stats.h:30
StatsRecord_::short_name
const char * short_name
Definition: output-stats.h:33
OutputJsonStatsRegisterTests
void OutputJsonStatsRegisterTests(void)
Definition: output-json-stats.c:131
StatsTable_::nstats
uint32_t nstats
Definition: output-stats.h:42