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