/src/suricata7/src/output.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2007-2021 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 OISF, Jason Ish <jason.ish@oisf.net> |
22 | | * \author Endace Technology Limited, Jason Ish <jason.ish@endace.com> |
23 | | * |
24 | | * The root logging output for all non-application logging. |
25 | | * |
26 | | * The loggers are made up of a hierarchy of loggers. At the top we |
27 | | * have the root logger which is the main entry point to |
28 | | * logging. Under the root there exists parent loggers that are the |
29 | | * entry point for specific types of loggers such as packet logger, |
30 | | * transaction loggers, etc. Each parent logger may have 0 or more |
31 | | * loggers that actual handle the job of producing output to something |
32 | | * like a file. |
33 | | */ |
34 | | |
35 | | #include "suricata-common.h" |
36 | | #include "flow.h" |
37 | | #include "conf.h" |
38 | | #include "tm-threads.h" |
39 | | #include "util-error.h" |
40 | | #include "util-debug.h" |
41 | | #include "output.h" |
42 | | |
43 | | #include "alert-fastlog.h" |
44 | | #include "alert-debuglog.h" |
45 | | #include "alert-syslog.h" |
46 | | #include "output-json.h" |
47 | | #include "output-json-alert.h" |
48 | | #include "output-json-anomaly.h" |
49 | | #include "output-json-flow.h" |
50 | | #include "output-json-netflow.h" |
51 | | #include "log-cf-common.h" |
52 | | #include "output-json-drop.h" |
53 | | #include "output-eve-stream.h" |
54 | | #include "log-httplog.h" |
55 | | #include "output-json-http.h" |
56 | | #include "output-json-dns.h" |
57 | | #include "output-json-modbus.h" |
58 | | #include "log-tlslog.h" |
59 | | #include "log-tlsstore.h" |
60 | | #include "output-json-tls.h" |
61 | | #include "output-json-ssh.h" |
62 | | #include "log-pcap.h" |
63 | | #include "output-json-file.h" |
64 | | #include "output-json-smtp.h" |
65 | | #include "output-json-stats.h" |
66 | | #include "log-tcp-data.h" |
67 | | #include "log-stats.h" |
68 | | #include "output-json-nfs.h" |
69 | | #include "output-json-ftp.h" |
70 | | #include "output-json-tftp.h" |
71 | | #include "output-json-smb.h" |
72 | | #include "output-json-ike.h" |
73 | | #include "output-json-krb5.h" |
74 | | #include "output-json-quic.h" |
75 | | #include "output-json-dhcp.h" |
76 | | #include "output-json-snmp.h" |
77 | | #include "output-json-sip.h" |
78 | | #include "output-json-rfb.h" |
79 | | #include "output-json-mqtt.h" |
80 | | #include "output-json-pgsql.h" |
81 | | #include "output-json-template.h" |
82 | | #include "output-json-rdp.h" |
83 | | #include "output-json-http2.h" |
84 | | #include "output-lua.h" |
85 | | #include "output-json-dnp3.h" |
86 | | #include "output-json-metadata.h" |
87 | | #include "output-json-dcerpc.h" |
88 | | #include "output-json-frame.h" |
89 | | #include "output-json-bittorrent-dht.h" |
90 | | #include "output-filestore.h" |
91 | | |
92 | | typedef struct RootLogger_ { |
93 | | OutputLogFunc LogFunc; |
94 | | ThreadInitFunc ThreadInit; |
95 | | ThreadDeinitFunc ThreadDeinit; |
96 | | ThreadExitPrintStatsFunc ThreadExitPrintStats; |
97 | | OutputGetActiveCountFunc ActiveCntFunc; |
98 | | |
99 | | TAILQ_ENTRY(RootLogger_) entries; |
100 | | } RootLogger; |
101 | | |
102 | | /* List of registered root loggers. These are registered at start up and |
103 | | * are independent of configuration. Later we will build a list of active |
104 | | * loggers based on configuration. */ |
105 | | static TAILQ_HEAD(, RootLogger_) registered_loggers = |
106 | | TAILQ_HEAD_INITIALIZER(registered_loggers); |
107 | | |
108 | | /* List of active root loggers. This means that at least one logger is enabled |
109 | | * for each root logger type in the config. */ |
110 | | static TAILQ_HEAD(, RootLogger_) active_loggers = |
111 | | TAILQ_HEAD_INITIALIZER(active_loggers); |
112 | | |
113 | | typedef struct LoggerThreadStoreNode_ { |
114 | | void *thread_data; |
115 | | TAILQ_ENTRY(LoggerThreadStoreNode_) entries; |
116 | | } LoggerThreadStoreNode; |
117 | | |
118 | | typedef TAILQ_HEAD(LoggerThreadStore_, LoggerThreadStoreNode_) LoggerThreadStore; |
119 | | |
120 | | /** |
121 | | * The list of all registered (known) output modules. |
122 | | */ |
123 | | OutputModuleList output_modules = TAILQ_HEAD_INITIALIZER(output_modules); |
124 | | |
125 | | /** |
126 | | * Registry of flags to be updated on file rotation notification. |
127 | | */ |
128 | | typedef struct OutputFileRolloverFlag_ { |
129 | | int *flag; |
130 | | |
131 | | TAILQ_ENTRY(OutputFileRolloverFlag_) entries; |
132 | | } OutputFileRolloverFlag; |
133 | | |
134 | | TAILQ_HEAD(, OutputFileRolloverFlag_) output_file_rotation_flags = |
135 | | TAILQ_HEAD_INITIALIZER(output_file_rotation_flags); |
136 | | |
137 | | void OutputRegisterRootLoggers(void); |
138 | | void OutputRegisterLoggers(void); |
139 | | |
140 | | /** |
141 | | * \brief Register an output module. |
142 | | * |
143 | | * This function will register an output module so it can be |
144 | | * configured with the configuration file. |
145 | | * |
146 | | * \retval Returns 0 on success, -1 on failure. |
147 | | */ |
148 | | void OutputRegisterModule(const char *name, const char *conf_name, |
149 | | OutputInitFunc InitFunc) |
150 | 109 | { |
151 | 109 | OutputModule *module = SCCalloc(1, sizeof(*module)); |
152 | 109 | if (unlikely(module == NULL)) |
153 | 0 | goto error; |
154 | | |
155 | 109 | module->name = name; |
156 | 109 | module->conf_name = conf_name; |
157 | 109 | module->InitFunc = InitFunc; |
158 | 109 | TAILQ_INSERT_TAIL(&output_modules, module, entries); |
159 | | |
160 | 109 | SCLogDebug("Output module \"%s\" registered.", name); |
161 | | |
162 | 109 | return; |
163 | | |
164 | 0 | error: |
165 | 0 | FatalError("Fatal error encountered in OutputRegisterModule. Exiting..."); |
166 | 0 | } |
167 | | |
168 | | /** |
169 | | * \brief Register a packet output module. |
170 | | * |
171 | | * This function will register an output module so it can be |
172 | | * configured with the configuration file. |
173 | | * |
174 | | * \retval Returns 0 on success, -1 on failure. |
175 | | */ |
176 | | void OutputRegisterPacketModule(LoggerId id, const char *name, |
177 | | const char *conf_name, OutputInitFunc InitFunc, |
178 | | PacketLogger PacketLogFunc, PacketLogCondition PacketConditionFunc, |
179 | | ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, |
180 | | ThreadExitPrintStatsFunc ThreadExitPrintStats) |
181 | 284 | { |
182 | 284 | if (unlikely(PacketLogFunc == NULL || PacketConditionFunc == NULL)) { |
183 | 0 | goto error; |
184 | 0 | } |
185 | | |
186 | 284 | OutputModule *module = SCCalloc(1, sizeof(*module)); |
187 | 284 | if (unlikely(module == NULL)) { |
188 | 0 | goto error; |
189 | 0 | } |
190 | | |
191 | 284 | module->logger_id = id; |
192 | 284 | module->name = name; |
193 | 284 | module->conf_name = conf_name; |
194 | 284 | module->InitFunc = InitFunc; |
195 | 284 | module->PacketLogFunc = PacketLogFunc; |
196 | 284 | module->PacketConditionFunc = PacketConditionFunc; |
197 | 284 | module->ThreadInit = ThreadInit; |
198 | 284 | module->ThreadDeinit = ThreadDeinit; |
199 | 284 | module->ThreadExitPrintStats = ThreadExitPrintStats; |
200 | 284 | TAILQ_INSERT_TAIL(&output_modules, module, entries); |
201 | | |
202 | 284 | SCLogDebug("Packet logger \"%s\" registered.", name); |
203 | 284 | return; |
204 | 0 | error: |
205 | 0 | FatalError("Fatal error encountered. Exiting..."); |
206 | 0 | } |
207 | | |
208 | | /** |
209 | | * \brief Register a packet output sub-module. |
210 | | * |
211 | | * This function will register an output module so it can be |
212 | | * configured with the configuration file. |
213 | | * |
214 | | * \retval Returns 0 on success, -1 on failure. |
215 | | */ |
216 | | void OutputRegisterPacketSubModule(LoggerId id, const char *parent_name, |
217 | | const char *name, const char *conf_name, OutputInitSubFunc InitFunc, |
218 | | PacketLogger PacketLogFunc, PacketLogCondition PacketConditionFunc, |
219 | | ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, |
220 | | ThreadExitPrintStatsFunc ThreadExitPrintStats) |
221 | 535 | { |
222 | 535 | if (unlikely(PacketLogFunc == NULL || PacketConditionFunc == NULL)) { |
223 | 0 | goto error; |
224 | 0 | } |
225 | | |
226 | 535 | OutputModule *module = SCCalloc(1, sizeof(*module)); |
227 | 535 | if (unlikely(module == NULL)) { |
228 | 0 | goto error; |
229 | 0 | } |
230 | | |
231 | 535 | module->logger_id = id; |
232 | 535 | module->name = name; |
233 | 535 | module->conf_name = conf_name; |
234 | 535 | module->parent_name = parent_name; |
235 | 535 | module->InitSubFunc = InitFunc; |
236 | 535 | module->PacketLogFunc = PacketLogFunc; |
237 | 535 | module->PacketConditionFunc = PacketConditionFunc; |
238 | 535 | module->ThreadInit = ThreadInit; |
239 | 535 | module->ThreadDeinit = ThreadDeinit; |
240 | 535 | module->ThreadExitPrintStats = ThreadExitPrintStats; |
241 | 535 | TAILQ_INSERT_TAIL(&output_modules, module, entries); |
242 | | |
243 | 535 | SCLogDebug("Packet logger \"%s\" registered.", name); |
244 | 535 | return; |
245 | 0 | error: |
246 | 0 | FatalError("Fatal error encountered. Exiting..."); |
247 | 0 | } |
248 | | |
249 | | /** |
250 | | * \brief Wrapper function for tx output modules. |
251 | | * |
252 | | * This function will register an output module so it can be |
253 | | * configured with the configuration file. |
254 | | * |
255 | | * \retval Returns 0 on success, -1 on failure. |
256 | | */ |
257 | | static void OutputRegisterTxModuleWrapper(LoggerId id, const char *name, |
258 | | const char *conf_name, OutputInitFunc InitFunc, AppProto alproto, |
259 | | TxLogger TxLogFunc, int tc_log_progress, int ts_log_progress, |
260 | | TxLoggerCondition TxLogCondition, ThreadInitFunc ThreadInit, |
261 | | ThreadDeinitFunc ThreadDeinit, |
262 | | ThreadExitPrintStatsFunc ThreadExitPrintStats) |
263 | 251 | { |
264 | 251 | if (unlikely(TxLogFunc == NULL)) { |
265 | 0 | goto error; |
266 | 0 | } |
267 | | |
268 | 251 | OutputModule *module = SCCalloc(1, sizeof(*module)); |
269 | 251 | if (unlikely(module == NULL)) { |
270 | 0 | goto error; |
271 | 0 | } |
272 | | |
273 | 251 | module->logger_id = id; |
274 | 251 | module->name = name; |
275 | 251 | module->conf_name = conf_name; |
276 | 251 | module->InitFunc = InitFunc; |
277 | 251 | module->TxLogFunc = TxLogFunc; |
278 | 251 | module->TxLogCondition = TxLogCondition; |
279 | 251 | module->alproto = alproto; |
280 | 251 | module->tc_log_progress = tc_log_progress; |
281 | 251 | module->ts_log_progress = ts_log_progress; |
282 | 251 | module->ThreadInit = ThreadInit; |
283 | 251 | module->ThreadDeinit = ThreadDeinit; |
284 | 251 | module->ThreadExitPrintStats = ThreadExitPrintStats; |
285 | 251 | TAILQ_INSERT_TAIL(&output_modules, module, entries); |
286 | | |
287 | 251 | SCLogDebug("Tx logger \"%s\" registered.", name); |
288 | 251 | return; |
289 | 0 | error: |
290 | 0 | FatalError("Fatal error encountered. Exiting..."); |
291 | 0 | } |
292 | | |
293 | | static void OutputRegisterTxSubModuleWrapper(LoggerId id, const char *parent_name, |
294 | | const char *name, const char *conf_name, OutputInitSubFunc InitFunc, |
295 | | AppProto alproto, TxLogger TxLogFunc, int tc_log_progress, |
296 | | int ts_log_progress, TxLoggerCondition TxLogCondition, |
297 | | ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, |
298 | | ThreadExitPrintStatsFunc ThreadExitPrintStats) |
299 | 2.10k | { |
300 | 2.10k | if (unlikely(TxLogFunc == NULL)) { |
301 | 0 | goto error; |
302 | 0 | } |
303 | | |
304 | 2.10k | OutputModule *module = SCCalloc(1, sizeof(*module)); |
305 | 2.10k | if (unlikely(module == NULL)) { |
306 | 0 | goto error; |
307 | 0 | } |
308 | | |
309 | 2.10k | module->logger_id = id; |
310 | 2.10k | module->name = name; |
311 | 2.10k | module->conf_name = conf_name; |
312 | 2.10k | module->parent_name = parent_name; |
313 | 2.10k | module->InitSubFunc = InitFunc; |
314 | 2.10k | module->TxLogFunc = TxLogFunc; |
315 | 2.10k | module->TxLogCondition = TxLogCondition; |
316 | 2.10k | module->alproto = alproto; |
317 | 2.10k | module->tc_log_progress = tc_log_progress; |
318 | 2.10k | module->ts_log_progress = ts_log_progress; |
319 | 2.10k | module->ThreadInit = ThreadInit; |
320 | 2.10k | module->ThreadDeinit = ThreadDeinit; |
321 | 2.10k | module->ThreadExitPrintStats = ThreadExitPrintStats; |
322 | 2.10k | TAILQ_INSERT_TAIL(&output_modules, module, entries); |
323 | | |
324 | 2.10k | SCLogDebug("Tx logger for alproto %d \"%s\" registered.", alproto, name); |
325 | 2.10k | return; |
326 | 0 | error: |
327 | 0 | FatalError("Fatal error encountered. Exiting..."); |
328 | 0 | } |
329 | | |
330 | | /** |
331 | | * \brief Register a tx output module with condition. |
332 | | * |
333 | | * This function will register an output module so it can be |
334 | | * configured with the configuration file. |
335 | | * |
336 | | * \retval Returns 0 on success, -1 on failure. |
337 | | */ |
338 | | void OutputRegisterTxModuleWithCondition(LoggerId id, const char *name, |
339 | | const char *conf_name, OutputInitFunc InitFunc, AppProto alproto, |
340 | | TxLogger TxLogFunc, TxLoggerCondition TxLogCondition, |
341 | | ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, |
342 | | ThreadExitPrintStatsFunc ThreadExitPrintStats) |
343 | 109 | { |
344 | 109 | OutputRegisterTxModuleWrapper(id, name, conf_name, InitFunc, alproto, |
345 | 109 | TxLogFunc, -1, -1, TxLogCondition, ThreadInit, ThreadDeinit, |
346 | 109 | ThreadExitPrintStats); |
347 | 109 | } |
348 | | |
349 | | void OutputRegisterTxSubModuleWithCondition(LoggerId id, |
350 | | const char *parent_name, const char *name, const char *conf_name, |
351 | | OutputInitSubFunc InitFunc, AppProto alproto, TxLogger TxLogFunc, |
352 | | TxLoggerCondition TxLogCondition, ThreadInitFunc ThreadInit, |
353 | | ThreadDeinitFunc ThreadDeinit, |
354 | | ThreadExitPrintStatsFunc ThreadExitPrintStats) |
355 | 71 | { |
356 | 71 | OutputRegisterTxSubModuleWrapper(id, parent_name, name, conf_name, InitFunc, |
357 | 71 | alproto, TxLogFunc, -1, -1, TxLogCondition, ThreadInit, ThreadDeinit, |
358 | 71 | ThreadExitPrintStats); |
359 | 71 | } |
360 | | |
361 | | /** |
362 | | * \brief Register a tx output module with progress. |
363 | | * |
364 | | * This function will register an output module so it can be |
365 | | * configured with the configuration file. |
366 | | * |
367 | | * \retval Returns 0 on success, -1 on failure. |
368 | | */ |
369 | | void OutputRegisterTxModuleWithProgress(LoggerId id, const char *name, |
370 | | const char *conf_name, OutputInitFunc InitFunc, AppProto alproto, |
371 | | TxLogger TxLogFunc, int tc_log_progress, int ts_log_progress, |
372 | | ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, |
373 | | ThreadExitPrintStatsFunc ThreadExitPrintStats) |
374 | 71 | { |
375 | 71 | OutputRegisterTxModuleWrapper(id, name, conf_name, InitFunc, alproto, |
376 | 71 | TxLogFunc, tc_log_progress, ts_log_progress, NULL, ThreadInit, |
377 | 71 | ThreadDeinit, ThreadExitPrintStats); |
378 | 71 | } |
379 | | |
380 | | void OutputRegisterTxSubModuleWithProgress(LoggerId id, const char *parent_name, |
381 | | const char *name, const char *conf_name, OutputInitSubFunc InitFunc, |
382 | | AppProto alproto, TxLogger TxLogFunc, int tc_log_progress, |
383 | | int ts_log_progress, ThreadInitFunc ThreadInit, |
384 | | ThreadDeinitFunc ThreadDeinit, |
385 | | ThreadExitPrintStatsFunc ThreadExitPrintStats) |
386 | 142 | { |
387 | 142 | OutputRegisterTxSubModuleWrapper(id, parent_name, name, conf_name, InitFunc, |
388 | 142 | alproto, TxLogFunc, tc_log_progress, ts_log_progress, NULL, ThreadInit, |
389 | 142 | ThreadDeinit, ThreadExitPrintStats); |
390 | 142 | } |
391 | | |
392 | | /** |
393 | | * \brief Register a tx output module. |
394 | | * |
395 | | * This function will register an output module so it can be |
396 | | * configured with the configuration file. |
397 | | * |
398 | | * \retval Returns 0 on success, -1 on failure. |
399 | | */ |
400 | | void OutputRegisterTxModule(LoggerId id, const char *name, |
401 | | const char *conf_name, OutputInitFunc InitFunc, AppProto alproto, |
402 | | TxLogger TxLogFunc, ThreadInitFunc ThreadInit, |
403 | | ThreadDeinitFunc ThreadDeinit, |
404 | | ThreadExitPrintStatsFunc ThreadExitPrintStats) |
405 | 71 | { |
406 | 71 | OutputRegisterTxModuleWrapper(id, name, conf_name, InitFunc, alproto, |
407 | 71 | TxLogFunc, -1, -1, NULL, ThreadInit, ThreadDeinit, |
408 | 71 | ThreadExitPrintStats); |
409 | 71 | } |
410 | | |
411 | | void OutputRegisterTxSubModule(LoggerId id, const char *parent_name, |
412 | | const char *name, const char *conf_name, |
413 | | OutputInitSubFunc InitFunc, AppProto alproto, TxLogger TxLogFunc, |
414 | | ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, |
415 | | ThreadExitPrintStatsFunc ThreadExitPrintStats) |
416 | 1.89k | { |
417 | 1.89k | OutputRegisterTxSubModuleWrapper(id, parent_name, name, conf_name, |
418 | 1.89k | InitFunc, alproto, TxLogFunc, -1, -1, NULL, ThreadInit, ThreadDeinit, |
419 | 1.89k | ThreadExitPrintStats); |
420 | 1.89k | } |
421 | | |
422 | | /** |
423 | | * \brief Register a file output module. |
424 | | * |
425 | | * This function will register an output module so it can be |
426 | | * configured with the configuration file. |
427 | | * |
428 | | * \retval Returns 0 on success, -1 on failure. |
429 | | */ |
430 | | void OutputRegisterFileModule(LoggerId id, const char *name, |
431 | | const char *conf_name, OutputInitFunc InitFunc, FileLogger FileLogFunc, |
432 | | ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, |
433 | | ThreadExitPrintStatsFunc ThreadExitPrintStats) |
434 | 0 | { |
435 | 0 | if (unlikely(FileLogFunc == NULL)) { |
436 | 0 | goto error; |
437 | 0 | } |
438 | | |
439 | 0 | OutputModule *module = SCCalloc(1, sizeof(*module)); |
440 | 0 | if (unlikely(module == NULL)) { |
441 | 0 | goto error; |
442 | 0 | } |
443 | | |
444 | 0 | module->logger_id = id; |
445 | 0 | module->name = name; |
446 | 0 | module->conf_name = conf_name; |
447 | 0 | module->InitFunc = InitFunc; |
448 | 0 | module->FileLogFunc = FileLogFunc; |
449 | 0 | module->ThreadInit = ThreadInit; |
450 | 0 | module->ThreadDeinit = ThreadDeinit; |
451 | 0 | module->ThreadExitPrintStats = ThreadExitPrintStats; |
452 | 0 | TAILQ_INSERT_TAIL(&output_modules, module, entries); |
453 | |
|
454 | 0 | SCLogDebug("File logger \"%s\" registered.", name); |
455 | 0 | return; |
456 | 0 | error: |
457 | 0 | FatalError("Fatal error encountered. Exiting..."); |
458 | 0 | } |
459 | | |
460 | | /** |
461 | | * \brief Register a file output sub-module. |
462 | | * |
463 | | * This function will register an output module so it can be |
464 | | * configured with the configuration file. |
465 | | * |
466 | | * \retval Returns 0 on success, -1 on failure. |
467 | | */ |
468 | | void OutputRegisterFileSubModule(LoggerId id, const char *parent_name, |
469 | | const char *name, const char *conf_name, OutputInitSubFunc InitFunc, |
470 | | FileLogger FileLogFunc, ThreadInitFunc ThreadInit, |
471 | | ThreadDeinitFunc ThreadDeinit, |
472 | | ThreadExitPrintStatsFunc ThreadExitPrintStats) |
473 | 71 | { |
474 | 71 | if (unlikely(FileLogFunc == NULL)) { |
475 | 0 | goto error; |
476 | 0 | } |
477 | | |
478 | 71 | OutputModule *module = SCCalloc(1, sizeof(*module)); |
479 | 71 | if (unlikely(module == NULL)) { |
480 | 0 | goto error; |
481 | 0 | } |
482 | | |
483 | 71 | module->logger_id = id; |
484 | 71 | module->name = name; |
485 | 71 | module->conf_name = conf_name; |
486 | 71 | module->parent_name = parent_name; |
487 | 71 | module->InitSubFunc = InitFunc; |
488 | 71 | module->FileLogFunc = FileLogFunc; |
489 | 71 | module->ThreadInit = ThreadInit; |
490 | 71 | module->ThreadDeinit = ThreadDeinit; |
491 | 71 | module->ThreadExitPrintStats = ThreadExitPrintStats; |
492 | 71 | TAILQ_INSERT_TAIL(&output_modules, module, entries); |
493 | | |
494 | 71 | SCLogDebug("File logger \"%s\" registered.", name); |
495 | 71 | return; |
496 | 0 | error: |
497 | 0 | FatalError("Fatal error encountered. Exiting..."); |
498 | 0 | } |
499 | | |
500 | | /** |
501 | | * \brief Register a file data output module. |
502 | | * |
503 | | * This function will register an output module so it can be |
504 | | * configured with the configuration file. |
505 | | * |
506 | | * \retval Returns 0 on success, -1 on failure. |
507 | | */ |
508 | | void OutputRegisterFiledataModule(LoggerId id, const char *name, |
509 | | const char *conf_name, OutputInitFunc InitFunc, |
510 | | FiledataLogger FiledataLogFunc, ThreadInitFunc ThreadInit, |
511 | | ThreadDeinitFunc ThreadDeinit, |
512 | | ThreadExitPrintStatsFunc ThreadExitPrintStats) |
513 | 71 | { |
514 | 71 | if (unlikely(FiledataLogFunc == NULL)) { |
515 | 0 | goto error; |
516 | 0 | } |
517 | | |
518 | 71 | OutputModule *module = SCCalloc(1, sizeof(*module)); |
519 | 71 | if (unlikely(module == NULL)) { |
520 | 0 | goto error; |
521 | 0 | } |
522 | | |
523 | 71 | module->logger_id = id; |
524 | 71 | module->name = name; |
525 | 71 | module->conf_name = conf_name; |
526 | 71 | module->InitFunc = InitFunc; |
527 | 71 | module->FiledataLogFunc = FiledataLogFunc; |
528 | 71 | module->ThreadInit = ThreadInit; |
529 | 71 | module->ThreadDeinit = ThreadDeinit; |
530 | 71 | module->ThreadExitPrintStats = ThreadExitPrintStats; |
531 | 71 | TAILQ_INSERT_TAIL(&output_modules, module, entries); |
532 | | |
533 | 71 | SCLogDebug("Filedata logger \"%s\" registered.", name); |
534 | 71 | return; |
535 | 0 | error: |
536 | 0 | FatalError("Fatal error encountered. Exiting..."); |
537 | 0 | } |
538 | | |
539 | | /** |
540 | | * \brief Register a file data output sub-module. |
541 | | * |
542 | | * This function will register an output module so it can be |
543 | | * configured with the configuration file. |
544 | | * |
545 | | * \retval Returns 0 on success, -1 on failure. |
546 | | */ |
547 | | void OutputRegisterFiledataSubModule(LoggerId id, const char *parent_name, |
548 | | const char *name, const char *conf_name, OutputInitSubFunc InitFunc, |
549 | | FiledataLogger FiledataLogFunc, ThreadInitFunc ThreadInit, |
550 | | ThreadDeinitFunc ThreadDeinit, |
551 | | ThreadExitPrintStatsFunc ThreadExitPrintStats) |
552 | 0 | { |
553 | 0 | if (unlikely(FiledataLogFunc == NULL)) { |
554 | 0 | goto error; |
555 | 0 | } |
556 | | |
557 | 0 | OutputModule *module = SCCalloc(1, sizeof(*module)); |
558 | 0 | if (unlikely(module == NULL)) { |
559 | 0 | goto error; |
560 | 0 | } |
561 | | |
562 | 0 | module->logger_id = id; |
563 | 0 | module->name = name; |
564 | 0 | module->conf_name = conf_name; |
565 | 0 | module->parent_name = parent_name; |
566 | 0 | module->InitSubFunc = InitFunc; |
567 | 0 | module->FiledataLogFunc = FiledataLogFunc; |
568 | 0 | module->ThreadInit = ThreadInit; |
569 | 0 | module->ThreadDeinit = ThreadDeinit; |
570 | 0 | module->ThreadExitPrintStats = ThreadExitPrintStats; |
571 | 0 | TAILQ_INSERT_TAIL(&output_modules, module, entries); |
572 | |
|
573 | 0 | SCLogDebug("Filedata logger \"%s\" registered.", name); |
574 | 0 | return; |
575 | 0 | error: |
576 | 0 | FatalError("Fatal error encountered. Exiting..."); |
577 | 0 | } |
578 | | |
579 | | /** |
580 | | * \brief Register a flow output sub-module. |
581 | | * |
582 | | * This function will register an output module so it can be |
583 | | * configured with the configuration file. |
584 | | * |
585 | | * \retval Returns 0 on success, -1 on failure. |
586 | | */ |
587 | | void OutputRegisterFlowSubModule(LoggerId id, const char *parent_name, |
588 | | const char *name, const char *conf_name, OutputInitSubFunc InitFunc, |
589 | | FlowLogger FlowLogFunc, ThreadInitFunc ThreadInit, |
590 | | ThreadDeinitFunc ThreadDeinit, |
591 | | ThreadExitPrintStatsFunc ThreadExitPrintStats) |
592 | 142 | { |
593 | 142 | if (unlikely(FlowLogFunc == NULL)) { |
594 | 0 | goto error; |
595 | 0 | } |
596 | | |
597 | 142 | OutputModule *module = SCCalloc(1, sizeof(*module)); |
598 | 142 | if (unlikely(module == NULL)) { |
599 | 0 | goto error; |
600 | 0 | } |
601 | | |
602 | 142 | module->logger_id = id; |
603 | 142 | module->name = name; |
604 | 142 | module->conf_name = conf_name; |
605 | 142 | module->parent_name = parent_name; |
606 | 142 | module->InitSubFunc = InitFunc; |
607 | 142 | module->FlowLogFunc = FlowLogFunc; |
608 | 142 | module->ThreadInit = ThreadInit; |
609 | 142 | module->ThreadDeinit = ThreadDeinit; |
610 | 142 | module->ThreadExitPrintStats = ThreadExitPrintStats; |
611 | 142 | TAILQ_INSERT_TAIL(&output_modules, module, entries); |
612 | | |
613 | 142 | SCLogDebug("Flow logger \"%s\" registered.", name); |
614 | 142 | return; |
615 | 0 | error: |
616 | 0 | FatalError("Fatal error encountered. Exiting..."); |
617 | 0 | } |
618 | | |
619 | | /** |
620 | | * \brief Register a streaming data output module. |
621 | | * |
622 | | * This function will register an output module so it can be |
623 | | * configured with the configuration file. |
624 | | * |
625 | | * \retval Returns 0 on success, -1 on failure. |
626 | | */ |
627 | | void OutputRegisterStreamingModule(LoggerId id, const char *name, |
628 | | const char *conf_name, OutputInitFunc InitFunc, |
629 | | StreamingLogger StreamingLogFunc, |
630 | | enum OutputStreamingType stream_type, ThreadInitFunc ThreadInit, |
631 | | ThreadDeinitFunc ThreadDeinit, |
632 | | ThreadExitPrintStatsFunc ThreadExitPrintStats) |
633 | 142 | { |
634 | 142 | if (unlikely(StreamingLogFunc == NULL)) { |
635 | 0 | goto error; |
636 | 0 | } |
637 | | |
638 | 142 | OutputModule *module = SCCalloc(1, sizeof(*module)); |
639 | 142 | if (unlikely(module == NULL)) { |
640 | 0 | goto error; |
641 | 0 | } |
642 | | |
643 | 142 | module->logger_id = id; |
644 | 142 | module->name = name; |
645 | 142 | module->conf_name = conf_name; |
646 | 142 | module->InitFunc = InitFunc; |
647 | 142 | module->StreamingLogFunc = StreamingLogFunc; |
648 | 142 | module->stream_type = stream_type; |
649 | 142 | module->ThreadInit = ThreadInit; |
650 | 142 | module->ThreadDeinit = ThreadDeinit; |
651 | 142 | module->ThreadExitPrintStats = ThreadExitPrintStats; |
652 | 142 | TAILQ_INSERT_TAIL(&output_modules, module, entries); |
653 | | |
654 | 142 | SCLogDebug("Streaming logger \"%s\" registered.", name); |
655 | 142 | return; |
656 | 0 | error: |
657 | 0 | FatalError("Fatal error encountered. Exiting..."); |
658 | 0 | } |
659 | | |
660 | | /** |
661 | | * \brief Register a streaming data output sub-module. |
662 | | * |
663 | | * This function will register an output module so it can be |
664 | | * configured with the configuration file. |
665 | | * |
666 | | * \retval Returns 0 on success, -1 on failure. |
667 | | */ |
668 | | void OutputRegisterStreamingSubModule(LoggerId id, const char *parent_name, |
669 | | const char *name, const char *conf_name, OutputInitSubFunc InitFunc, |
670 | | StreamingLogger StreamingLogFunc, enum OutputStreamingType stream_type, |
671 | | ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, |
672 | | ThreadExitPrintStatsFunc ThreadExitPrintStats) |
673 | 0 | { |
674 | 0 | if (unlikely(StreamingLogFunc == NULL)) { |
675 | 0 | goto error; |
676 | 0 | } |
677 | | |
678 | 0 | OutputModule *module = SCCalloc(1, sizeof(*module)); |
679 | 0 | if (unlikely(module == NULL)) { |
680 | 0 | goto error; |
681 | 0 | } |
682 | | |
683 | 0 | module->logger_id = id; |
684 | 0 | module->name = name; |
685 | 0 | module->conf_name = conf_name; |
686 | 0 | module->parent_name = parent_name; |
687 | 0 | module->InitSubFunc = InitFunc; |
688 | 0 | module->StreamingLogFunc = StreamingLogFunc; |
689 | 0 | module->stream_type = stream_type; |
690 | 0 | module->ThreadInit = ThreadInit; |
691 | 0 | module->ThreadDeinit = ThreadDeinit; |
692 | 0 | module->ThreadExitPrintStats = ThreadExitPrintStats; |
693 | 0 | TAILQ_INSERT_TAIL(&output_modules, module, entries); |
694 | |
|
695 | 0 | SCLogDebug("Streaming logger \"%s\" registered.", name); |
696 | 0 | return; |
697 | 0 | error: |
698 | 0 | FatalError("Fatal error encountered. Exiting..."); |
699 | 0 | } |
700 | | |
701 | | /** |
702 | | * \brief Register a stats data output module. |
703 | | * |
704 | | * This function will register an output module so it can be |
705 | | * configured with the configuration file. |
706 | | * |
707 | | * \retval Returns 0 on success, -1 on failure. |
708 | | */ |
709 | | void OutputRegisterStatsModule(LoggerId id, const char *name, |
710 | | const char *conf_name, OutputInitFunc InitFunc, StatsLogger StatsLogFunc, |
711 | | ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, |
712 | | ThreadExitPrintStatsFunc ThreadExitPrintStats) |
713 | 71 | { |
714 | 71 | if (unlikely(StatsLogFunc == NULL)) { |
715 | 0 | goto error; |
716 | 0 | } |
717 | | |
718 | 71 | OutputModule *module = SCCalloc(1, sizeof(*module)); |
719 | 71 | if (unlikely(module == NULL)) { |
720 | 0 | goto error; |
721 | 0 | } |
722 | | |
723 | 71 | module->logger_id = id; |
724 | 71 | module->name = name; |
725 | 71 | module->conf_name = conf_name; |
726 | 71 | module->InitFunc = InitFunc; |
727 | 71 | module->StatsLogFunc = StatsLogFunc; |
728 | 71 | module->ThreadInit = ThreadInit; |
729 | 71 | module->ThreadDeinit = ThreadDeinit; |
730 | 71 | module->ThreadExitPrintStats = ThreadExitPrintStats; |
731 | 71 | TAILQ_INSERT_TAIL(&output_modules, module, entries); |
732 | | |
733 | 71 | SCLogDebug("Stats logger \"%s\" registered.", name); |
734 | 71 | return; |
735 | 0 | error: |
736 | 0 | FatalError("Fatal error encountered. Exiting..."); |
737 | 0 | } |
738 | | |
739 | | /** |
740 | | * \brief Register a stats data output sub-module. |
741 | | * |
742 | | * This function will register an output module so it can be |
743 | | * configured with the configuration file. |
744 | | * |
745 | | * \retval Returns 0 on success, -1 on failure. |
746 | | */ |
747 | | void OutputRegisterStatsSubModule(LoggerId id, const char *parent_name, |
748 | | const char *name, const char *conf_name, OutputInitSubFunc InitFunc, |
749 | | StatsLogger StatsLogFunc, ThreadInitFunc ThreadInit, |
750 | | ThreadDeinitFunc ThreadDeinit, |
751 | | ThreadExitPrintStatsFunc ThreadExitPrintStats) |
752 | 71 | { |
753 | 71 | if (unlikely(StatsLogFunc == NULL)) { |
754 | 0 | goto error; |
755 | 0 | } |
756 | | |
757 | 71 | OutputModule *module = SCCalloc(1, sizeof(*module)); |
758 | 71 | if (unlikely(module == NULL)) { |
759 | 0 | goto error; |
760 | 0 | } |
761 | | |
762 | 71 | module->logger_id = id; |
763 | 71 | module->name = name; |
764 | 71 | module->conf_name = conf_name; |
765 | 71 | module->parent_name = parent_name; |
766 | 71 | module->InitSubFunc = InitFunc; |
767 | 71 | module->StatsLogFunc = StatsLogFunc; |
768 | 71 | module->ThreadInit = ThreadInit; |
769 | 71 | module->ThreadDeinit = ThreadDeinit; |
770 | 71 | module->ThreadExitPrintStats = ThreadExitPrintStats; |
771 | 71 | TAILQ_INSERT_TAIL(&output_modules, module, entries); |
772 | | |
773 | 71 | SCLogDebug("Stats logger \"%s\" registered.", name); |
774 | 71 | return; |
775 | 0 | error: |
776 | 0 | FatalError("Fatal error encountered. Exiting..."); |
777 | 0 | } |
778 | | |
779 | | /** |
780 | | * \brief Get an output module by name. |
781 | | * |
782 | | * \retval The OutputModule with the given name or NULL if no output module |
783 | | * with the given name is registered. |
784 | | */ |
785 | | OutputModule *OutputGetModuleByConfName(const char *conf_name) |
786 | 4 | { |
787 | 4 | OutputModule *module; |
788 | | |
789 | 54 | TAILQ_FOREACH(module, &output_modules, entries) { |
790 | 54 | if (strcmp(module->conf_name, conf_name) == 0) |
791 | 4 | return module; |
792 | 54 | } |
793 | | |
794 | 0 | return NULL; |
795 | 4 | } |
796 | | |
797 | | /** |
798 | | * \brief Deregister all modules. Useful for a memory clean exit. |
799 | | */ |
800 | | void OutputDeregisterAll(void) |
801 | 0 | { |
802 | 0 | OutputModule *module; |
803 | |
|
804 | 0 | while ((module = TAILQ_FIRST(&output_modules))) { |
805 | 0 | TAILQ_REMOVE(&output_modules, module, entries); |
806 | 0 | SCFree(module); |
807 | 0 | } |
808 | 0 | } |
809 | | |
810 | | static int drop_loggers = 0; |
811 | | |
812 | | int OutputDropLoggerEnable(void) |
813 | 0 | { |
814 | 0 | if (drop_loggers) |
815 | 0 | return -1; |
816 | 0 | drop_loggers++; |
817 | 0 | return 0; |
818 | 0 | } |
819 | | |
820 | | void OutputDropLoggerDisable(void) |
821 | 0 | { |
822 | 0 | if (drop_loggers) |
823 | 0 | drop_loggers--; |
824 | 0 | } |
825 | | |
826 | | /** |
827 | | * \brief Register a flag for file rotation notification. |
828 | | * |
829 | | * \param flag A pointer that will be set to 1 when file rotation is |
830 | | * requested. |
831 | | */ |
832 | | void OutputRegisterFileRotationFlag(int *flag) |
833 | 96 | { |
834 | 96 | OutputFileRolloverFlag *flag_entry = SCCalloc(1, sizeof(*flag_entry)); |
835 | 96 | if (unlikely(flag_entry == NULL)) { |
836 | 0 | SCLogError("Failed to allocate memory to register file rotation flag"); |
837 | 0 | return; |
838 | 0 | } |
839 | 96 | flag_entry->flag = flag; |
840 | 96 | TAILQ_INSERT_TAIL(&output_file_rotation_flags, flag_entry, entries); |
841 | 96 | } |
842 | | |
843 | | /** |
844 | | * \brief Unregister a file rotation flag. |
845 | | * |
846 | | * Note that it is safe to call this function with a flag that may not |
847 | | * have been registered, in which case this function won't do |
848 | | * anything. |
849 | | * |
850 | | * \param flag A pointer that has been previously registered for file |
851 | | * rotation notifications. |
852 | | */ |
853 | | void OutputUnregisterFileRotationFlag(int *flag) |
854 | 0 | { |
855 | 0 | OutputFileRolloverFlag *entry, *next; |
856 | 0 | for (entry = TAILQ_FIRST(&output_file_rotation_flags); entry != NULL; |
857 | 0 | entry = next) { |
858 | 0 | next = TAILQ_NEXT(entry, entries); |
859 | 0 | if (entry->flag == flag) { |
860 | 0 | TAILQ_REMOVE(&output_file_rotation_flags, entry, entries); |
861 | 0 | SCFree(entry); |
862 | 0 | break; |
863 | 0 | } |
864 | 0 | } |
865 | 0 | } |
866 | | |
867 | | /** |
868 | | * \brief Notifies all registered file rotation notification flags. |
869 | | */ |
870 | 0 | void OutputNotifyFileRotation(void) { |
871 | 0 | OutputFileRolloverFlag *flag; |
872 | 0 | TAILQ_FOREACH(flag, &output_file_rotation_flags, entries) { |
873 | 0 | *(flag->flag) = 1; |
874 | 0 | } |
875 | 0 | } |
876 | | |
877 | | TmEcode OutputLoggerLog(ThreadVars *tv, Packet *p, void *thread_data) |
878 | 18.7M | { |
879 | 18.7M | LoggerThreadStore *thread_store = (LoggerThreadStore *)thread_data; |
880 | 18.7M | RootLogger *logger = TAILQ_FIRST(&active_loggers); |
881 | 18.7M | LoggerThreadStoreNode *thread_store_node = TAILQ_FIRST(thread_store); |
882 | 56.2M | while (logger && thread_store_node) { |
883 | 37.5M | logger->LogFunc(tv, p, thread_store_node->thread_data); |
884 | | |
885 | 37.5M | logger = TAILQ_NEXT(logger, entries); |
886 | 37.5M | thread_store_node = TAILQ_NEXT(thread_store_node, entries); |
887 | 37.5M | } |
888 | 18.7M | return TM_ECODE_OK; |
889 | 18.7M | } |
890 | | |
891 | | TmEcode OutputLoggerThreadInit(ThreadVars *tv, const void *initdata, void **data) |
892 | 4 | { |
893 | 4 | LoggerThreadStore *thread_store = SCCalloc(1, sizeof(*thread_store)); |
894 | 4 | if (thread_store == NULL) { |
895 | 0 | return TM_ECODE_FAILED; |
896 | 0 | } |
897 | 4 | TAILQ_INIT(thread_store); |
898 | 4 | *data = (void *)thread_store; |
899 | | |
900 | 4 | RootLogger *logger; |
901 | 8 | TAILQ_FOREACH(logger, &active_loggers, entries) { |
902 | | |
903 | 8 | void *child_thread_data = NULL; |
904 | 8 | if (logger->ThreadInit != NULL) { |
905 | 8 | if (logger->ThreadInit(tv, initdata, &child_thread_data) == TM_ECODE_OK) { |
906 | 8 | LoggerThreadStoreNode *thread_store_node = |
907 | 8 | SCCalloc(1, sizeof(*thread_store_node)); |
908 | 8 | if (thread_store_node == NULL) { |
909 | | /* Undo everything, calling de-init will take care |
910 | | * of that. */ |
911 | 0 | OutputLoggerThreadDeinit(tv, thread_store); |
912 | 0 | return TM_ECODE_FAILED; |
913 | 0 | } |
914 | 8 | thread_store_node->thread_data = child_thread_data; |
915 | 8 | TAILQ_INSERT_TAIL(thread_store, thread_store_node, entries); |
916 | 8 | } |
917 | 8 | } |
918 | 8 | } |
919 | 4 | return TM_ECODE_OK; |
920 | 4 | } |
921 | | |
922 | | TmEcode OutputLoggerThreadDeinit(ThreadVars *tv, void *thread_data) |
923 | 0 | { |
924 | 0 | if (thread_data == NULL) |
925 | 0 | return TM_ECODE_FAILED; |
926 | | |
927 | 0 | LoggerThreadStore *thread_store = (LoggerThreadStore *)thread_data; |
928 | 0 | RootLogger *logger = TAILQ_FIRST(&active_loggers); |
929 | 0 | LoggerThreadStoreNode *thread_store_node = TAILQ_FIRST(thread_store); |
930 | 0 | while (logger && thread_store_node) { |
931 | 0 | if (logger->ThreadDeinit != NULL) { |
932 | 0 | logger->ThreadDeinit(tv, thread_store_node->thread_data); |
933 | 0 | } |
934 | 0 | logger = TAILQ_NEXT(logger, entries); |
935 | 0 | thread_store_node = TAILQ_NEXT(thread_store_node, entries); |
936 | 0 | } |
937 | | |
938 | | /* Free the thread store. */ |
939 | 0 | while ((thread_store_node = TAILQ_FIRST(thread_store)) != NULL) { |
940 | 0 | TAILQ_REMOVE(thread_store, thread_store_node, entries); |
941 | 0 | SCFree(thread_store_node); |
942 | 0 | } |
943 | 0 | SCFree(thread_store); |
944 | |
|
945 | 0 | return TM_ECODE_OK; |
946 | 0 | } |
947 | | |
948 | | void OutputLoggerExitPrintStats(ThreadVars *tv, void *thread_data) |
949 | 0 | { |
950 | 0 | LoggerThreadStore *thread_store = (LoggerThreadStore *)thread_data; |
951 | 0 | RootLogger *logger = TAILQ_FIRST(&active_loggers); |
952 | 0 | LoggerThreadStoreNode *thread_store_node = TAILQ_FIRST(thread_store); |
953 | 0 | while (logger && thread_store_node) { |
954 | 0 | if (logger->ThreadExitPrintStats != NULL) { |
955 | 0 | logger->ThreadExitPrintStats(tv, thread_store_node->thread_data); |
956 | 0 | } |
957 | 0 | logger = TAILQ_NEXT(logger, entries); |
958 | 0 | thread_store_node = TAILQ_NEXT(thread_store_node, entries); |
959 | 0 | } |
960 | 0 | } |
961 | | |
962 | | void OutputRegisterRootLogger(ThreadInitFunc ThreadInit, |
963 | | ThreadDeinitFunc ThreadDeinit, |
964 | | ThreadExitPrintStatsFunc ThreadExitPrintStats, |
965 | | OutputLogFunc LogFunc, OutputGetActiveCountFunc ActiveCntFunc) |
966 | 213 | { |
967 | 213 | BUG_ON(LogFunc == NULL); |
968 | | |
969 | 213 | RootLogger *logger = SCCalloc(1, sizeof(*logger)); |
970 | 213 | if (logger == NULL) { |
971 | 0 | FatalError("failed to alloc root logger"); |
972 | 0 | } |
973 | 213 | logger->ThreadInit = ThreadInit; |
974 | 213 | logger->ThreadDeinit = ThreadDeinit; |
975 | 213 | logger->ThreadExitPrintStats = ThreadExitPrintStats; |
976 | 213 | logger->LogFunc = LogFunc; |
977 | 213 | logger->ActiveCntFunc = ActiveCntFunc; |
978 | 213 | TAILQ_INSERT_TAIL(®istered_loggers, logger, entries); |
979 | 213 | } |
980 | | |
981 | | static void OutputRegisterActiveLogger(RootLogger *reg) |
982 | 8 | { |
983 | 8 | RootLogger *logger = SCCalloc(1, sizeof(*logger)); |
984 | 8 | if (logger == NULL) { |
985 | 0 | FatalError("failed to alloc root logger"); |
986 | 0 | } |
987 | 8 | logger->ThreadInit = reg->ThreadInit; |
988 | 8 | logger->ThreadDeinit = reg->ThreadDeinit; |
989 | 8 | logger->ThreadExitPrintStats = reg->ThreadExitPrintStats; |
990 | 8 | logger->LogFunc = reg->LogFunc; |
991 | 8 | logger->ActiveCntFunc = reg->ActiveCntFunc; |
992 | 8 | TAILQ_INSERT_TAIL(&active_loggers, logger, entries); |
993 | 8 | } |
994 | | |
995 | | void OutputSetupActiveLoggers(void) |
996 | 4 | { |
997 | 4 | RootLogger *logger = TAILQ_FIRST(®istered_loggers); |
998 | 16 | while (logger) { |
999 | 12 | uint32_t cnt = logger->ActiveCntFunc(); |
1000 | 12 | if (cnt) { |
1001 | 8 | OutputRegisterActiveLogger(logger); |
1002 | 8 | } |
1003 | | |
1004 | 12 | logger = TAILQ_NEXT(logger, entries); |
1005 | 12 | } |
1006 | 4 | } |
1007 | | |
1008 | | void OutputClearActiveLoggers(void) |
1009 | 0 | { |
1010 | 0 | RootLogger *logger; |
1011 | 0 | while ((logger = TAILQ_FIRST(&active_loggers)) != NULL) { |
1012 | 0 | TAILQ_REMOVE(&active_loggers, logger, entries); |
1013 | 0 | SCFree(logger); |
1014 | 0 | } |
1015 | 0 | } |
1016 | | |
1017 | | void TmModuleLoggerRegister(void) |
1018 | 71 | { |
1019 | 71 | OutputRegisterRootLoggers(); |
1020 | 71 | OutputRegisterLoggers(); |
1021 | 71 | } |
1022 | | |
1023 | | /** |
1024 | | * \brief Register all root loggers. |
1025 | | */ |
1026 | | void OutputRegisterRootLoggers(void) |
1027 | 33 | { |
1028 | 33 | OutputPacketLoggerRegister(); |
1029 | 33 | OutputFiledataLoggerRegister(); |
1030 | 33 | OutputFileLoggerRegister(); |
1031 | 33 | OutputTxLoggerRegister(); |
1032 | 33 | OutputStreamingLoggerRegister(); |
1033 | 33 | } |
1034 | | |
1035 | | /** |
1036 | | * \brief Register all non-root logging modules. |
1037 | | */ |
1038 | | void OutputRegisterLoggers(void) |
1039 | 33 | { |
1040 | | /* custom format log*/ |
1041 | 33 | LogCustomFormatRegister(); |
1042 | | |
1043 | 33 | LuaLogRegister(); |
1044 | | /* fast log */ |
1045 | 33 | AlertFastLogRegister(); |
1046 | | /* debug log */ |
1047 | 33 | AlertDebugLogRegister(); |
1048 | | /* syslog log */ |
1049 | 33 | AlertSyslogRegister(); |
1050 | 33 | JsonDropLogRegister(); |
1051 | 33 | EveStreamLogRegister(); |
1052 | | /* json log */ |
1053 | 33 | OutputJsonRegister(); |
1054 | | /* email logs */ |
1055 | 33 | JsonSmtpLogRegister(); |
1056 | | /* http log */ |
1057 | 33 | LogHttpLogRegister(); |
1058 | 33 | JsonHttpLogRegister(); |
1059 | 33 | JsonHttp2LogRegister(); |
1060 | | /* tls log */ |
1061 | 33 | LogTlsLogRegister(); |
1062 | 33 | JsonTlsLogRegister(); |
1063 | 33 | LogTlsStoreRegister(); |
1064 | | /* ssh */ |
1065 | 33 | JsonSshLogRegister(); |
1066 | | /* pcap log */ |
1067 | 33 | PcapLogRegister(); |
1068 | | /* file log */ |
1069 | 33 | JsonFileLogRegister(); |
1070 | 33 | OutputFilestoreRegister(); |
1071 | | /* dns */ |
1072 | 33 | JsonDnsLogRegister(); |
1073 | | /* modbus */ |
1074 | 33 | JsonModbusLogRegister(); |
1075 | | /* tcp streaming data */ |
1076 | 33 | LogTcpDataLogRegister(); |
1077 | | /* log stats */ |
1078 | 33 | LogStatsLogRegister(); |
1079 | | |
1080 | 33 | JsonAlertLogRegister(); |
1081 | 33 | JsonAnomalyLogRegister(); |
1082 | | /* flow/netflow */ |
1083 | 33 | JsonFlowLogRegister(); |
1084 | 33 | JsonNetFlowLogRegister(); |
1085 | | /* json stats */ |
1086 | 33 | JsonStatsLogRegister(); |
1087 | | |
1088 | | /* DNP3. */ |
1089 | 33 | JsonDNP3LogRegister(); |
1090 | 33 | JsonMetadataLogRegister(); |
1091 | | |
1092 | | /* NFS JSON logger. */ |
1093 | 33 | JsonNFSLogRegister(); |
1094 | | /* TFTP JSON logger. */ |
1095 | 33 | JsonTFTPLogRegister(); |
1096 | | /* FTP JSON logger. */ |
1097 | 33 | JsonFTPLogRegister(); |
1098 | | /* SMB JSON logger. */ |
1099 | 33 | JsonSMBLogRegister(); |
1100 | | /* IKE JSON logger. */ |
1101 | 33 | JsonIKELogRegister(); |
1102 | | /* KRB5 JSON logger. */ |
1103 | 33 | JsonKRB5LogRegister(); |
1104 | | /* QUIC JSON logger. */ |
1105 | 33 | JsonQuicLogRegister(); |
1106 | | /* DHCP JSON logger. */ |
1107 | 33 | JsonDHCPLogRegister(); |
1108 | | /* SNMP JSON logger. */ |
1109 | 33 | JsonSNMPLogRegister(); |
1110 | | /* SIP JSON logger. */ |
1111 | 33 | JsonSIPLogRegister(); |
1112 | | /* RFB JSON logger. */ |
1113 | 33 | JsonRFBLogRegister(); |
1114 | | /* MQTT JSON logger. */ |
1115 | 33 | JsonMQTTLogRegister(); |
1116 | | /* Pgsql JSON logger. */ |
1117 | 33 | JsonPgsqlLogRegister(); |
1118 | | /* Template JSON logger. */ |
1119 | 33 | JsonTemplateLogRegister(); |
1120 | | /* RDP JSON logger. */ |
1121 | 33 | JsonRdpLogRegister(); |
1122 | | /* DCERPC JSON logger. */ |
1123 | 33 | JsonDCERPCLogRegister(); |
1124 | | /* app layer frames */ |
1125 | 33 | JsonFrameLogRegister(); |
1126 | | /* BitTorrent DHT JSON logger */ |
1127 | 33 | JsonBitTorrentDHTLogRegister(); |
1128 | 33 | } |