suricata
output-json-stats.c
Go to the documentation of this file.
1 /* Copyright (C) 2014-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 /**
19  * \file
20  *
21  * \author Tom DeCanio <td@npulsetech.com>
22  *
23  * Implements JSON stats counters logging portion of the engine.
24  */
25 
26 #include "suricata-common.h"
27 #include "detect.h"
28 #include "pkt-var.h"
29 #include "conf.h"
30 #include "detect-engine.h"
31 
32 #include "threads.h"
33 #include "threadvars.h"
34 #include "tm-threads.h"
35 
36 #include "util-print.h"
37 #include "util-time.h"
38 #include "util-unittest.h"
39 #include "util-validate.h"
40 
41 #include "util-debug.h"
42 #include "output.h"
43 #include "util-privs.h"
44 #include "util-buffer.h"
45 
46 #include "util-logopenfile.h"
47 
48 #include "output-json.h"
49 #include "output-json-stats.h"
50 
51 #define MODULE_NAME "JsonStatsLog"
52 
53 extern bool stats_decoder_events;
54 extern const char *stats_decoder_events_prefix;
55 
56 /**
57  * specify which engine info will be printed in stats log.
58  * ALL means both last reload and ruleset stats.
59  */
60 typedef enum OutputEngineInfo_ {
65 
66 typedef struct OutputStatsCtx_ {
68  uint8_t flags; /** Store mode */
70 
71 typedef struct JsonStatsLogThread_ {
76 
77 static json_t *EngineStats2Json(const DetectEngineCtx *de_ctx,
78  const OutputEngineInfo output)
79 {
80  char timebuf[64];
81  const SigFileLoaderStat *sig_stat = NULL;
82 
83  json_t *jdata = json_object();
84  if (jdata == NULL) {
85  return NULL;
86  }
87 
88  if (output == OUTPUT_ENGINE_LAST_RELOAD || output == OUTPUT_ENGINE_ALL) {
90  CreateIsoTimeString(last_reload, timebuf, sizeof(timebuf));
91  json_object_set_new(jdata, "last_reload", json_string(timebuf));
92  }
93 
94  sig_stat = &de_ctx->sig_stat;
95  if ((output == OUTPUT_ENGINE_RULESET || output == OUTPUT_ENGINE_ALL) &&
96  sig_stat != NULL)
97  {
98  json_object_set_new(jdata, "rules_loaded",
99  json_integer(sig_stat->good_sigs_total));
100  json_object_set_new(jdata, "rules_failed",
101  json_integer(sig_stat->bad_sigs_total));
102  json_object_set_new(jdata, "rules_skipped", json_integer(sig_stat->skipped_sigs_total));
103  }
104 
105  return jdata;
106 }
107 
108 static TmEcode OutputEngineStats2Json(json_t **jdata, const OutputEngineInfo output)
109 {
111  if (de_ctx == NULL) {
112  goto err1;
113  }
114  /* Since we need to deference de_ctx pointer, we don't want to lost it. */
115  DetectEngineCtx *list = de_ctx;
116 
117  json_t *js_tenant_list = json_array();
118  json_t *js_tenant = NULL;
119 
120  if (js_tenant_list == NULL) {
121  goto err2;
122  }
123 
124  while(list) {
125  js_tenant = json_object();
126  if (js_tenant == NULL) {
127  goto err3;
128  }
129  json_object_set_new(js_tenant, "id", json_integer(list->tenant_id));
130 
131  json_t *js_stats = EngineStats2Json(list, output);
132  if (js_stats == NULL) {
133  goto err4;
134  }
135  json_object_update(js_tenant, js_stats);
136  json_array_append_new(js_tenant_list, js_tenant);
137  json_decref(js_stats);
138  list = list->next;
139  }
140 
142  *jdata = js_tenant_list;
143  return TM_ECODE_OK;
144 
145 err4:
146  json_object_clear(js_tenant);
147  json_decref(js_tenant);
148 
149 err3:
150  json_object_clear(js_tenant_list);
151  json_decref(js_tenant_list);
152 
153 err2:
155 
156 err1:
157  json_object_set_new(*jdata, "message", json_string("Unable to get info"));
158  return TM_ECODE_FAILED;
159 }
160 
162  return OutputEngineStats2Json(jdata, OUTPUT_ENGINE_LAST_RELOAD);
163 }
164 
166  return OutputEngineStats2Json(jdata, OUTPUT_ENGINE_RULESET);
167 }
168 
169 static json_t *OutputStats2Json(json_t *js, const char *key)
170 {
171  void *iter;
172 
173  const char *dot = strchr(key, '.');
174  if (dot == NULL)
175  return NULL;
176  if (strlen(dot) > 2) {
177  if (*(dot + 1) == '.' && *(dot + 2) != '\0')
178  dot = strchr(dot + 2, '.');
179  }
180 
181  size_t predot_len = (dot - key) + 1;
182  char s[predot_len];
183  strlcpy(s, key, predot_len);
184 
185  iter = json_object_iter_at(js, s);
186  const char *s2 = strchr(dot+1, '.');
187 
188  json_t *value = json_object_iter_value(iter);
189  if (value == NULL) {
190  value = json_object();
191 
192  if (!strncmp(s, "detect", 6)) {
193  json_t *js_engine = NULL;
194 
195  TmEcode ret = OutputEngineStats2Json(&js_engine, OUTPUT_ENGINE_ALL);
196  if (ret == TM_ECODE_OK && js_engine) {
197  json_object_set_new(value, "engines", js_engine);
198  }
199  }
200  json_object_set_new(js, s, value);
201  }
202  if (s2 != NULL) {
203  return OutputStats2Json(value, &key[dot-key+1]);
204  }
205  return value;
206 }
207 
208 /** \brief turn StatsTable into a json object
209  * \param flags JSON_STATS_* flags for controlling output
210  */
211 json_t *StatsToJSON(const StatsTable *st, uint8_t flags)
212 {
213  const char delta_suffix[] = "_delta";
214  struct timeval tval;
215  gettimeofday(&tval, NULL);
216 
217  json_t *js_stats = json_object();
218  if (unlikely(js_stats == NULL)) {
219  return NULL;
220  }
221 
222  /* Uptime, in seconds. */
223  double up_time_d = difftime(tval.tv_sec, st->start_time);
224  json_object_set_new(js_stats, "uptime",
225  json_integer((int)up_time_d));
226 
227  uint32_t u = 0;
228  if (flags & JSON_STATS_TOTALS) {
229  for (u = 0; u < st->nstats; u++) {
230  if (st->stats[u].name == NULL)
231  continue;
232  if (flags & JSON_STATS_NO_ZEROES && st->stats[u].value == 0) {
233  continue;
234  }
235 
236  json_t *js_type = NULL;
237  const char *stat_name = st->stats[u].short_name;
238  /*
239  * When there's no short-name, the stat is added to
240  * the "global" stats namespace, just like "uptime"
241  */
242  if (st->stats[u].short_name == NULL) {
243  stat_name = st->stats[u].name;
244  js_type = js_stats;
245  } else {
246  js_type = OutputStats2Json(js_stats, st->stats[u].name);
247  }
248  if (js_type != NULL) {
249  json_object_set_new(js_type, stat_name, json_integer(st->stats[u].value));
250 
251  if (flags & JSON_STATS_DELTAS) {
252  /* add +1 to safisfy gcc 15 + -Wformat-truncation=2 */
253  char deltaname[strlen(stat_name) + strlen(delta_suffix) + 2];
254  snprintf(deltaname, sizeof(deltaname), "%s%s", stat_name, delta_suffix);
255  json_object_set_new(js_type, deltaname,
256  json_integer(st->stats[u].value - st->stats[u].pvalue));
257  }
258  }
259  }
260  }
261 
262  /* per thread stats - stored in a "threads" object. */
263  if (st->tstats != NULL && (flags & JSON_STATS_THREADS)) {
264  /* for each thread (store) */
265  json_t *threads = json_object();
266  if (unlikely(threads == NULL)) {
267  json_decref(js_stats);
268  return NULL;
269  }
270  uint32_t x;
271  for (x = 0; x < st->ntstats; x++) {
272  uint32_t offset = x * st->nstats;
273  const char *tm_name = NULL;
274  json_t *thread = NULL;
275 
276  /* for each counter */
277  for (u = offset; u < (offset + st->nstats); u++) {
278  if (st->tstats[u].name == NULL)
279  continue;
280  if (flags & JSON_STATS_NO_ZEROES && st->tstats[u].value == 0) {
281  continue;
282  }
283 
284  DEBUG_VALIDATE_BUG_ON(st->tstats[u].tm_name == NULL);
285 
286  if (tm_name == NULL) {
287  // First time we see a set tm_name. Remember it
288  // and allocate the stats object for this thread.
289  tm_name = st->tstats[u].tm_name;
290  thread = json_object();
291  if (unlikely(thread == NULL)) {
292  json_decref(js_stats);
293  json_decref(threads);
294  return NULL;
295  }
296  } else {
297  DEBUG_VALIDATE_BUG_ON(strcmp(tm_name, st->tstats[u].tm_name) != 0);
298  DEBUG_VALIDATE_BUG_ON(thread == NULL);
299  }
300 
301  json_t *js_type = NULL;
302  const char *stat_name = st->tstats[u].short_name;
303  if (st->tstats[u].short_name == NULL) {
304  stat_name = st->tstats[u].name;
305  js_type = threads;
306  } else {
307  js_type = OutputStats2Json(thread, st->tstats[u].name);
308  }
309 
310  if (js_type != NULL) {
311  json_object_set_new(js_type, stat_name, json_integer(st->tstats[u].value));
312 
313  if (flags & JSON_STATS_DELTAS) {
314  char deltaname[strlen(stat_name) + strlen(delta_suffix) + 2];
315  snprintf(deltaname, sizeof(deltaname), "%s%s", stat_name, delta_suffix);
316  json_object_set_new(js_type, deltaname,
317  json_integer(st->tstats[u].value - st->tstats[u].pvalue));
318  }
319  }
320  }
321  if (tm_name != NULL) {
322  DEBUG_VALIDATE_BUG_ON(thread == NULL);
323  json_object_set_new(threads, tm_name, thread);
324  }
325  }
326  json_object_set_new(js_stats, "threads", threads);
327  }
328  return js_stats;
329 }
330 
331 static int JsonStatsLogger(ThreadVars *tv, void *thread_data, const StatsTable *st)
332 {
333  SCEnter();
334  JsonStatsLogThread *aft = (JsonStatsLogThread *)thread_data;
335 
336  struct timeval tval;
337  gettimeofday(&tval, NULL);
338 
339  json_t *js = json_object();
340  if (unlikely(js == NULL))
341  return 0;
342  char timebuf[64];
343  CreateIsoTimeString(SCTIME_FROM_TIMEVAL(&tval), timebuf, sizeof(timebuf));
344  json_object_set_new(js, "timestamp", json_string(timebuf));
345  json_object_set_new(js, "event_type", json_string("stats"));
346 
347  json_t *js_stats = StatsToJSON(st, aft->statslog_ctx->flags);
348  if (js_stats == NULL) {
349  json_decref(js);
350  return 0;
351  }
352 
353  json_object_set_new(js, "stats", js_stats);
354 
355  OutputJSONBuffer(js, aft->file_ctx, &aft->buffer);
356  MemBufferReset(aft->buffer);
357 
358  json_object_clear(js_stats);
359  json_object_del(js, "stats");
360  json_object_clear(js);
361  json_decref(js);
362 
363  SCReturnInt(0);
364 }
365 
366 static TmEcode JsonStatsLogThreadInit(ThreadVars *t, const void *initdata, void **data)
367 {
369  if (unlikely(aft == NULL))
370  return TM_ECODE_FAILED;
371 
372  if(initdata == NULL)
373  {
374  SCLogDebug("Error getting context for EveLogStats. \"initdata\" argument NULL");
375  goto error_exit;
376  }
377 
379  if (aft->buffer == NULL) {
380  goto error_exit;
381  }
382 
383  /* Use the Output Context (file pointer and mutex) */
384  aft->statslog_ctx = ((OutputCtx *)initdata)->data;
385 
387  if (!aft->file_ctx) {
388  goto error_exit;
389  }
390 
391  *data = (void *)aft;
392  return TM_ECODE_OK;
393 
394 error_exit:
395  if (aft->buffer != NULL) {
396  MemBufferFree(aft->buffer);
397  }
398  SCFree(aft);
399  return TM_ECODE_FAILED;
400 }
401 
402 static TmEcode JsonStatsLogThreadDeinit(ThreadVars *t, void *data)
403 {
404  JsonStatsLogThread *aft = (JsonStatsLogThread *)data;
405  if (aft == NULL) {
406  return TM_ECODE_OK;
407  }
408 
409  MemBufferFree(aft->buffer);
410 
411  /* clear memory */
412  memset(aft, 0, sizeof(JsonStatsLogThread));
413 
414  SCFree(aft);
415  return TM_ECODE_OK;
416 }
417 
418 static void OutputStatsLogDeinitSub(OutputCtx *output_ctx)
419 {
420  OutputStatsCtx *stats_ctx = output_ctx->data;
421  SCFree(stats_ctx);
422  SCFree(output_ctx);
423 }
424 
425 static OutputInitResult OutputStatsLogInitSub(SCConfNode *conf, OutputCtx *parent_ctx)
426 {
427  OutputInitResult result = { NULL, false };
428  OutputJsonCtx *ajt = parent_ctx->data;
429 
430  if (!StatsEnabled()) {
431  SCLogError("eve.stats: stats are disabled globally: set stats.enabled to true. "
432  "See %s/configuration/suricata-yaml.html#stats",
433  GetDocURL());
434  return result;
435  }
436 
437  OutputStatsCtx *stats_ctx = SCMalloc(sizeof(OutputStatsCtx));
438  if (unlikely(stats_ctx == NULL))
439  return result;
440 
441  if (stats_decoder_events &&
442  strcmp(stats_decoder_events_prefix, "decoder") == 0) {
443  SCLogWarning("eve.stats will not display "
444  "all decoder events correctly. See ticket #2225. Set a prefix in "
445  "stats.decoder-events-prefix.");
446  }
447 
448  stats_ctx->flags = JSON_STATS_TOTALS;
449 
450  if (conf != NULL) {
451  const char *totals = SCConfNodeLookupChildValue(conf, "totals");
452  const char *threads = SCConfNodeLookupChildValue(conf, "threads");
453  const char *deltas = SCConfNodeLookupChildValue(conf, "deltas");
454  const char *zero_counters = SCConfNodeLookupChildValue(conf, "null-values");
455  SCLogDebug("totals %s threads %s deltas %s", totals, threads, deltas);
456 
457  if ((totals != NULL && SCConfValIsFalse(totals)) &&
458  (threads != NULL && SCConfValIsFalse(threads))) {
459  SCFree(stats_ctx);
460  SCLogError("Cannot disable both totals and threads in stats logging");
461  return result;
462  }
463 
464  if (totals != NULL && SCConfValIsFalse(totals)) {
465  stats_ctx->flags &= ~JSON_STATS_TOTALS;
466  }
467  if (threads != NULL && SCConfValIsTrue(threads)) {
468  stats_ctx->flags |= JSON_STATS_THREADS;
469  }
470  if (deltas != NULL && SCConfValIsTrue(deltas)) {
471  stats_ctx->flags |= JSON_STATS_DELTAS;
472  }
473  if (zero_counters != NULL && SCConfValIsFalse(zero_counters)) {
474  stats_ctx->flags |= JSON_STATS_NO_ZEROES;
475  }
476  SCLogDebug("stats_ctx->flags %08x", stats_ctx->flags);
477  }
478 
479  OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
480  if (unlikely(output_ctx == NULL)) {
481  SCFree(stats_ctx);
482  return result;
483  }
484 
485  SCLogDebug("Preparing file context for stats submodule logger");
486  /* prepared by suricata-main */
487  stats_ctx->file_ctx = LogFileEnsureExists(0, ajt->file_ctx);
488  if (!stats_ctx->file_ctx) {
489  SCFree(stats_ctx);
490  SCFree(output_ctx);
491  return result;
492  }
493 
494  output_ctx->data = stats_ctx;
495  output_ctx->DeInit = OutputStatsLogDeinitSub;
496 
497  result.ctx = output_ctx;
498  result.ok = true;
499  return result;
500 }
501 
503  /* register as child of eve-log */
504  OutputRegisterStatsSubModule(LOGGER_JSON_STATS, "eve-log", MODULE_NAME, "eve-log.stats",
505  OutputStatsLogInitSub, JsonStatsLogger, JsonStatsLogThreadInit,
506  JsonStatsLogThreadDeinit);
507 }
508 
509 #ifdef UNITTESTS
510 #include "tests/output-json-stats.c"
511 #endif
tm-threads.h
StatsTable_::ntstats
uint32_t ntstats
Definition: output-stats.h:43
SCConfValIsTrue
int SCConfValIsTrue(const char *val)
Check if a value is true.
Definition: conf.c:551
detect-engine.h
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
DetectEngineDeReference
void DetectEngineDeReference(DetectEngineCtx **de_ctx)
Definition: detect-engine.c:4631
CreateIsoTimeString
void CreateIsoTimeString(const SCTime_t ts, char *str, size_t size)
Definition: util-time.c:209
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
LOGGER_JSON_STATS
@ LOGGER_JSON_STATS
Definition: suricata-common.h:506
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:279
JSON_OUTPUT_BUFFER_SIZE
#define JSON_OUTPUT_BUFFER_SIZE
Definition: output-json.h:56
threads.h
JsonStatsLogThread
struct JsonStatsLogThread_ JsonStatsLogThread
OutputJsonCtx_
Definition: output-json.h:75
LogFileCtx_
Definition: util-logopenfile.h:72
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:932
output-json-stats.c
OutputRegisterStatsSubModule
void OutputRegisterStatsSubModule(LoggerId id, const char *parent_name, const char *name, const char *conf_name, OutputInitSubFunc InitFunc, StatsLogger StatsLogFunc, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit)
Register a stats data output sub-module.
Definition: output.c:606
OutputStatsCtx_::flags
uint8_t flags
Definition: output-json-stats.c:68
DetectEngineGetCurrent
DetectEngineCtx * DetectEngineGetCurrent(void)
Definition: detect-engine.c:3829
SCConfValIsFalse
int SCConfValIsFalse(const char *val)
Check if a value is false.
Definition: conf.c:576
util-privs.h
SCConfNodeLookupChildValue
const char * SCConfNodeLookupChildValue(const SCConfNode *node, const char *name)
Lookup the value of a child configuration node by name.
Definition: conf.c:824
JSON_STATS_TOTALS
#define JSON_STATS_TOTALS
Definition: output-json-stats.h:29
StatsRecord_::pvalue
int64_t pvalue
Definition: output-stats.h:36
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:82
JsonStatsLogRegister
void JsonStatsLogRegister(void)
Definition: output-json-stats.c:502
util-unittest.h
OutputCtx_::data
void * data
Definition: tm-modules.h:91
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:81
OutputCtx_
Definition: tm-modules.h:88
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
OutputEngineInfo_
OutputEngineInfo_
Definition: output-json-stats.c:60
stats_decoder_events_prefix
const char * stats_decoder_events_prefix
Definition: counters.c:102
SigFileLoaderStat_::skipped_sigs_total
int skipped_sigs_total
Definition: detect.h:882
util-debug.h
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:18
OutputInitResult_::ctx
OutputCtx * ctx
Definition: output.h:47
output-json.h
DetectEngineCtx_::last_reload
struct timeval last_reload
Definition: detect.h:1099
JsonStatsLogThread_::buffer
MemBuffer * buffer
Definition: output-json-stats.c:74
util-print.h
SCEnter
#define SCEnter(...)
Definition: util-debug.h:281
StatsRecord_::name
const char * name
Definition: output-stats.h:32
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
SCTIME_FROM_TIMEVAL
#define SCTIME_FROM_TIMEVAL(tv)
Definition: util-time.h:79
pkt-var.h
util-time.h
OutputInitResult_::ok
bool ok
Definition: output.h:48
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:259
ThreadVars_::id
int id
Definition: threadvars.h:87
SigFileLoaderStat_::bad_sigs_total
int bad_sigs_total
Definition: detect.h:881
OutputEngineStatsReloadTime
TmEcode OutputEngineStatsReloadTime(json_t **jdata)
Definition: output-json-stats.c:161
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
conf.h
SCTime_t
Definition: util-time.h:40
TmEcode
TmEcode
Definition: tm-threads-common.h:80
StatsTable_::start_time
time_t start_time
Definition: output-stats.h:44
MemBuffer_
Definition: util-buffer.h:27
JsonStatsLogThread_::file_ctx
LogFileCtx * file_ctx
Definition: output-json-stats.c:73
StatsTable_::stats
StatsRecord * stats
Definition: output-stats.h:40
JsonStatsLogThread_
Definition: output-json-stats.c:71
OutputInitResult_
Definition: output.h:46
DetectEngineCtx_::sig_stat
SigFileLoaderStat sig_stat
Definition: detect.h:1102
JSON_STATS_NO_ZEROES
#define JSON_STATS_NO_ZEROES
Definition: output-json-stats.h:32
flags
uint8_t flags
Definition: decode-gre.h:0
LogFileEnsureExists
LogFileCtx * LogFileEnsureExists(ThreadId thread_id, LogFileCtx *parent_ctx)
LogFileEnsureExists() Ensure a log file context for the thread exists.
Definition: util-logopenfile.c:743
suricata-common.h
OutputCtx_::DeInit
void(* DeInit)(struct OutputCtx_ *)
Definition: tm-modules.h:94
output-json-stats.h
OUTPUT_ENGINE_LAST_RELOAD
@ OUTPUT_ENGINE_LAST_RELOAD
Definition: output-json-stats.c:61
DetectEngineCtx_::next
struct DetectEngineCtx_ * next
Definition: detect.h:1058
OUTPUT_ENGINE_ALL
@ OUTPUT_ENGINE_ALL
Definition: output-json-stats.c:63
MemBufferFree
void MemBufferFree(MemBuffer *buffer)
Definition: util-buffer.c:86
StatsEnabled
bool StatsEnabled(void)
Definition: counters.c:118
JSON_STATS_DELTAS
#define JSON_STATS_DELTAS
Definition: output-json-stats.h:31
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
StatsTable_::tstats
StatsRecord * tstats
Definition: output-stats.h:41
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
threadvars.h
util-validate.h
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:271
SCFree
#define SCFree(p)
Definition: util-mem.h:61
SigFileLoaderStat_::good_sigs_total
int good_sigs_total
Definition: detect.h:880
util-logopenfile.h
util-buffer.h
StatsRecord_::short_name
const char * short_name
Definition: output-stats.h:33
OutputStatsCtx_::file_ctx
LogFileCtx * file_ctx
Definition: output-json-stats.c:67
OutputJsonCtx_::file_ctx
LogFileCtx * file_ctx
Definition: output-json.h:76
OutputJSONBuffer
int OutputJSONBuffer(json_t *js, LogFileCtx *file_ctx, MemBuffer **buffer)
Definition: output-json.c:980
OutputEngineInfo
enum OutputEngineInfo_ OutputEngineInfo
GetDocURL
const char * GetDocURL(void)
Definition: suricata.c:1165
OUTPUT_ENGINE_RULESET
@ OUTPUT_ENGINE_RULESET
Definition: output-json-stats.c:62
OutputEngineStatsRuleset
TmEcode OutputEngineStatsRuleset(json_t **jdata)
Definition: output-json-stats.c:165
JsonStatsLogThread_::statslog_ctx
OutputStatsCtx * statslog_ctx
Definition: output-json-stats.c:72
stats_decoder_events
bool stats_decoder_events
Definition: counters.c:101
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
MODULE_NAME
#define MODULE_NAME
Definition: output-json-stats.c:51
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:285
OutputStatsCtx
struct OutputStatsCtx_ OutputStatsCtx
SCConfNode_
Definition: conf.h:37
DetectEngineCtx_::tenant_id
uint32_t tenant_id
Definition: detect.h:939
SigFileLoaderStat_
Signature loader statistics.
Definition: detect.h:876
StatsTable_::nstats
uint32_t nstats
Definition: output-stats.h:42
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:102
MemBufferCreateNew
MemBuffer * MemBufferCreateNew(uint32_t size)
Definition: util-buffer.c:32
output.h
OutputStatsCtx_
Definition: output-json-stats.c:66