suricata
output-stats.c
Go to the documentation of this file.
1 /* Copyright (C) 2014-2022 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 Victor Julien <victor@inliniac.net>
22  *
23  * Stats Logger Output registration functions
24  */
25 
26 #include "suricata-common.h"
27 #include "output.h"
28 #include "output-stats.h"
29 #include "util-validate.h"
30 
31 /** per thread data for this module, contains a list of per thread
32  * data for the packet loggers. */
36 
37 /* logger instance, a module + a output ctx,
38  * it's perfectly valid that have multiple instances of the same
39  * log module (e.g. http.log) with different output ctx'. */
40 typedef struct OutputStatsLogger_ {
44  const char *name;
49 
50 static OutputStatsLogger *list = NULL;
51 
56 {
57  OutputStatsLogger *op = SCCalloc(1, sizeof(*op));
58  if (op == NULL)
59  return -1;
60 
61  op->LogFunc = LogFunc;
62  op->output_ctx = output_ctx;
63  op->name = name;
64  op->ThreadInit = ThreadInit;
67 
68  if (list == NULL)
69  list = op;
70  else {
71  OutputStatsLogger *t = list;
72  while (t->next)
73  t = t->next;
74  t->next = op;
75  }
76 
77  SCLogDebug("OutputRegisterStatsLogger happy");
78  return 0;
79 }
80 
81 TmEcode OutputStatsLog(ThreadVars *tv, void *thread_data, StatsTable *st)
82 {
83  DEBUG_VALIDATE_BUG_ON(thread_data == NULL);
84  DEBUG_VALIDATE_BUG_ON(list == NULL);
85 
86  OutputStatsLoggerThreadData *op_thread_data = (OutputStatsLoggerThreadData *)thread_data;
87  OutputStatsLogger *logger = list;
88  OutputLoggerThreadStore *store = op_thread_data->store;
89 
90  DEBUG_VALIDATE_BUG_ON(logger == NULL && store != NULL);
91  DEBUG_VALIDATE_BUG_ON(logger != NULL && store == NULL);
92  DEBUG_VALIDATE_BUG_ON(logger == NULL && store == NULL);
93 
94  while (logger && store) {
95  DEBUG_VALIDATE_BUG_ON(logger->LogFunc == NULL);
96 
97  logger->LogFunc(tv, store->thread_data, st);
98 
99  logger = logger->next;
100  store = store->next;
101 
102  DEBUG_VALIDATE_BUG_ON(logger == NULL && store != NULL);
103  DEBUG_VALIDATE_BUG_ON(logger != NULL && store == NULL);
104  }
105 
106  return TM_ECODE_OK;
107 }
108 
109 /** \brief thread init for the tx logger
110  * This will run the thread init functions for the individual registered
111  * loggers */
112 static TmEcode OutputStatsLogThreadInit(ThreadVars *tv, const void *initdata, void **data)
113 {
114  OutputStatsLoggerThreadData *td = SCCalloc(1, sizeof(*td));
115  if (td == NULL)
116  return TM_ECODE_FAILED;
117 
118  *data = (void *)td;
119 
120  SCLogDebug("OutputStatsLogThreadInit happy (*data %p)", *data);
121 
122  OutputStatsLogger *logger = list;
123  while (logger) {
124  if (logger->ThreadInit) {
125  void *retptr = NULL;
126  if (logger->ThreadInit(tv, (void *)logger->output_ctx, &retptr) == TM_ECODE_OK) {
127  OutputLoggerThreadStore *ts = SCCalloc(1, sizeof(*ts));
128  /* todo */ BUG_ON(ts == NULL);
129 
130  /* store thread handle */
131  ts->thread_data = retptr;
132 
133  if (td->store == NULL) {
134  td->store = ts;
135  } else {
136  OutputLoggerThreadStore *tmp = td->store;
137  while (tmp->next != NULL)
138  tmp = tmp->next;
139  tmp->next = ts;
140  }
141 
142  SCLogDebug("%s is now set up", logger->name);
143  }
144  }
145 
146  logger = logger->next;
147  }
148 
149  SCLogDebug("OutputStatsLogThreadInit happy (*data %p)", *data);
150  return TM_ECODE_OK;
151 }
152 
153 static TmEcode OutputStatsLogThreadDeinit(ThreadVars *tv, void *thread_data)
154 {
155  OutputStatsLoggerThreadData *op_thread_data = (OutputStatsLoggerThreadData *)thread_data;
156  OutputLoggerThreadStore *store = op_thread_data->store;
157  OutputStatsLogger *logger = list;
158 
159  while (logger && store) {
160  if (logger->ThreadDeinit) {
161  logger->ThreadDeinit(tv, store->thread_data);
162  }
163  OutputLoggerThreadStore *next_store = store->next;
164  SCFree(store);
165  store = next_store;
166  logger = logger->next;
167  }
168 
169  SCFree(op_thread_data);
170  return TM_ECODE_OK;
171 }
172 
173 static void OutputStatsLogExitPrintStats(ThreadVars *tv, void *thread_data)
174 {
175  OutputStatsLoggerThreadData *op_thread_data = (OutputStatsLoggerThreadData *)thread_data;
176  OutputLoggerThreadStore *store = op_thread_data->store;
177  OutputStatsLogger *logger = list;
178 
179  while (logger && store) {
180  if (logger->ThreadExitPrintStats) {
181  logger->ThreadExitPrintStats(tv, store->thread_data);
182  }
183 
184  logger = logger->next;
185  store = store->next;
186  }
187 }
188 
190 {
191  tmm_modules[TMM_STATSLOGGER].name = "__stats_logger__";
192  tmm_modules[TMM_STATSLOGGER].ThreadInit = OutputStatsLogThreadInit;
193  tmm_modules[TMM_STATSLOGGER].ThreadExitPrintStats = OutputStatsLogExitPrintStats;
194  tmm_modules[TMM_STATSLOGGER].ThreadDeinit = OutputStatsLogThreadDeinit;
196 }
197 
199 {
200  if (list != NULL)
201  return 1;
202  return 0;
203 }
204 
206 {
207  OutputStatsLogger *logger = list;
208  while (logger) {
209  OutputStatsLogger *next_logger = logger->next;
210  SCFree(logger);
211  logger = next_logger;
212  }
213  list = NULL;
214 }
TmModule_::cap_flags
uint8_t cap_flags
Definition: tm-modules.h:74
ts
uint64_t ts
Definition: source-erf-file.c:55
OutputLoggerThreadStore_
Definition: output.h:33
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
OutputStatsLogger_::ThreadExitPrintStats
ThreadExitPrintStatsFunc ThreadExitPrintStats
Definition: output-stats.c:47
TMM_STATSLOGGER
@ TMM_STATSLOGGER
Definition: tm-threads-common.h:65
OutputRegisterStatsLogger
int OutputRegisterStatsLogger(const char *name, StatsLogger LogFunc, OutputCtx *output_ctx, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, ThreadExitPrintStatsFunc ThreadExitPrintStats)
Definition: output-stats.c:52
OutputLoggerThreadStore_::next
struct OutputLoggerThreadStore_ * next
Definition: output.h:35
TmModuleStatsLoggerRegister
void TmModuleStatsLoggerRegister(void)
Definition: output-stats.c:189
OutputStatsShutdown
void OutputStatsShutdown(void)
Definition: output-stats.c:205
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:85
OutputStatsLogger
struct OutputStatsLogger_ OutputStatsLogger
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:84
OutputCtx_
Definition: tm-modules.h:85
TmModule_::ThreadDeinit
TmEcode(* ThreadDeinit)(ThreadVars *, void *)
Definition: tm-modules.h:50
OutputStatsLogger_::ThreadDeinit
ThreadDeinitFunc ThreadDeinit
Definition: output-stats.c:46
OutputLoggerThreadStore_::thread_data
void * thread_data
Definition: output.h:34
OutputStatsLoggerThreadData_::store
OutputLoggerThreadStore * store
Definition: output-stats.c:34
OutputStatsLogger_::ThreadInit
ThreadInitFunc ThreadInit
Definition: output-stats.c:45
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
ThreadInitFunc
TmEcode(* ThreadInitFunc)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:40
OutputStatsLogger_
Definition: output-stats.c:40
OutputStatsLoggerThreadData_
Definition: output-stats.c:33
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:300
StatsTable_
Definition: output-stats.h:39
tmm_modules
TmModule tmm_modules[TMM_SIZE]
Definition: tm-modules.c:33
OutputStatsLogger_::name
const char * name
Definition: output-stats.c:44
OutputStatsLogger_::output_ctx
OutputCtx * output_ctx
Definition: output-stats.c:42
TmEcode
TmEcode
Definition: tm-threads-common.h:83
TmModule_::name
const char * name
Definition: tm-modules.h:45
OutputStatsLogger_::next
struct OutputStatsLogger_ * next
Definition: output-stats.c:43
suricata-common.h
OutputStatsLogger_::LogFunc
StatsLogger LogFunc
Definition: output-stats.c:41
ThreadExitPrintStatsFunc
void(* ThreadExitPrintStatsFunc)(ThreadVars *, void *)
Definition: tm-modules.h:42
OutputStatsLoggerThreadData
struct OutputStatsLoggerThreadData_ OutputStatsLoggerThreadData
TmModule_::ThreadInit
TmEcode(* ThreadInit)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:48
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
TmModule_::ThreadExitPrintStats
void(* ThreadExitPrintStats)(ThreadVars *, void *)
Definition: tm-modules.h:49
util-validate.h
OutputStatsLoggersRegistered
int OutputStatsLoggersRegistered(void)
Definition: output-stats.c:198
SCFree
#define SCFree(p)
Definition: util-mem.h:61
StatsLogger
int(* StatsLogger)(ThreadVars *, void *thread_data, const StatsTable *)
Definition: output-stats.h:50
output-stats.h
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:102
OutputStatsLog
TmEcode OutputStatsLog(ThreadVars *tv, void *thread_data, StatsTable *st)
Definition: output-stats.c:81
output.h
ThreadDeinitFunc
TmEcode(* ThreadDeinitFunc)(ThreadVars *, void *)
Definition: tm-modules.h:41