suricata
util-debug.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2020 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 Anoop Saldanha <anoopsaldanha@gmail.com>
22  *
23  * Debug utility functions
24  */
25 
26 #include "suricata-common.h"
27 #include "threads.h"
28 #include "util-debug.h"
29 #include "util-error.h"
30 #include "util-enum.h"
31 #include "util-debug-filters.h"
32 
33 #include "decode.h"
34 #include "detect.h"
35 #include "packet-queue.h"
36 #include "threadvars.h"
37 #include "output.h"
38 
39 #include "tm-queuehandlers.h"
40 #include "tm-queues.h"
41 #include "tm-threads.h"
42 
43 #include "util-unittest.h"
44 #include "util-syslog.h"
45 #include "rust.h"
46 
47 
48 #include "conf.h"
49 
50 /* holds the string-enum mapping for the enums held in the table SCLogLevel */
52  { "Not set", SC_LOG_NOTSET},
53  { "None", SC_LOG_NONE },
54  { "Emergency", SC_LOG_EMERGENCY },
55  { "Alert", SC_LOG_ALERT },
56  { "Critical", SC_LOG_CRITICAL },
57  { "Error", SC_LOG_ERROR },
58  { "Warning", SC_LOG_WARNING },
59  { "Notice", SC_LOG_NOTICE },
60  { "Info", SC_LOG_INFO },
61  { "Perf", SC_LOG_PERF },
62  { "Config", SC_LOG_CONFIG },
63  { "Debug", SC_LOG_DEBUG },
64  { NULL, -1 }
65 };
66 
67 /* holds the string-enum mapping for the enums held in the table SCLogOPIface */
69  { "Console", SC_LOG_OP_IFACE_CONSOLE },
70  { "File", SC_LOG_OP_IFACE_FILE },
71  { "Syslog", SC_LOG_OP_IFACE_SYSLOG },
72  { NULL, -1 }
73 };
74 
75 #if defined (OS_WIN32)
76 /**
77  * \brief Used for synchronous output on WIN32
78  */
79 static SCMutex sc_log_stream_lock;
80 #endif /* OS_WIN32 */
81 
82 /**
83  * \brief Holds the config state for the logging module
84  */
85 static SCLogConfig *sc_log_config = NULL;
86 
87 /**
88  * \brief Returns the full path given a file and configured log dir
89  */
90 static char *SCLogGetLogFilename(const char *);
91 
92 /**
93  * \brief Holds the global log level. Is the same as sc_log_config->log_level
94  */
96 
97 /**
98  * \brief Used to indicate whether the logging module has been init or not
99  */
101 
102 /**
103  * \brief Used to indicate whether the logging module has been cleaned or not
104  */
106 
107 /**
108  * \brief Maps the SC logging level to the syslog logging level
109  *
110  * \param The SC logging level that has to be mapped to the syslog_log_level
111  *
112  * \retval syslog_log_level The mapped syslog_api_log_level, for the logging
113  * module api's internal log_level
114  */
115 static inline int SCLogMapLogLevelToSyslogLevel(int log_level)
116 {
117  int syslog_log_level = 0;
118 
119  switch (log_level) {
120  case SC_LOG_EMERGENCY:
121  syslog_log_level = LOG_EMERG;
122  break;
123  case SC_LOG_ALERT:
124  syslog_log_level = LOG_ALERT;
125  break;
126  case SC_LOG_CRITICAL:
127  syslog_log_level = LOG_CRIT;
128  break;
129  case SC_LOG_ERROR:
130  syslog_log_level = LOG_ERR;
131  break;
132  case SC_LOG_WARNING:
133  syslog_log_level = LOG_WARNING;
134  break;
135  case SC_LOG_NOTICE:
136  syslog_log_level = LOG_NOTICE;
137  break;
138  case SC_LOG_INFO:
139  syslog_log_level = LOG_INFO;
140  break;
141  case SC_LOG_CONFIG:
142  case SC_LOG_DEBUG:
143  case SC_LOG_PERF:
144  syslog_log_level = LOG_DEBUG;
145  break;
146  default:
147  syslog_log_level = LOG_EMERG;
148  break;
149  }
150 
151  return syslog_log_level;
152 }
153 
154 /**
155  * \brief Output function that logs a character string out to a file descriptor
156  *
157  * \param fd Pointer to the file descriptor
158  * \param msg Pointer to the character string that should be logged
159  */
160 static inline void SCLogPrintToStream(FILE *fd, char *msg)
161 {
162  /* Would only happen if the log file failed to re-open during rotation. */
163  if (fd == NULL) {
164  return;
165  }
166 
167 #if defined (OS_WIN32)
168  SCMutexLock(&sc_log_stream_lock);
169 #endif /* OS_WIN32 */
170 
171  if (fprintf(fd, "%s\n", msg) < 0)
172  printf("Error writing to stream using fprintf\n");
173 
174  fflush(fd);
175 
176 #if defined (OS_WIN32)
177  SCMutexUnlock(&sc_log_stream_lock);
178 #endif /* OS_WIN32 */
179 
180  return;
181 }
182 
183 /**
184  * \brief Output function that logs a character string throught the syslog iface
185  *
186  * \param syslog_log_level Holds the syslog_log_level that the message should be
187  * logged as
188  * \param msg Pointer to the char string, that should be logged
189  *
190  * \todo syslog is thread-safe according to POSIX manual and glibc code, but we
191  * we will have to look into non POSIX compliant boxes like freeBSD
192  */
193 static inline void SCLogPrintToSyslog(int syslog_log_level, const char *msg)
194 {
195  //static struct syslog_data data = SYSLOG_DATA_INIT;
196  //syslog_r(syslog_log_level, NULL, "%s", msg);
197 
198  syslog(syslog_log_level, "%s", msg);
199 
200  return;
201 }
202 
203 /**
204  */
205 static int SCLogMessageJSON(struct timeval *tval, char *buffer, size_t buffer_size,
206  SCLogLevel log_level, const char *file,
207  unsigned line, const char *function, SCError error_code,
208  const char *message)
209 {
210  json_t *js = json_object();
211  if (unlikely(js == NULL))
212  goto error;
213  json_t *ejs = json_object();
214  if (unlikely(ejs == NULL))
215  goto error;
216 
217  char timebuf[64];
218  CreateIsoTimeString(tval, timebuf, sizeof(timebuf));
219  json_object_set_new(js, "timestamp", json_string(timebuf));
220 
221  const char *s = SCMapEnumValueToName(log_level, sc_log_level_map);
222  if (s != NULL) {
223  json_object_set_new(js, "log_level", json_string(s));
224  } else {
225  json_object_set_new(js, "log_level", json_string("INVALID"));
226  }
227 
228  json_object_set_new(js, "event_type", json_string("engine"));
229 
230  if (error_code > 0) {
231  json_object_set_new(ejs, "error_code", json_integer(error_code));
232  json_object_set_new(ejs, "error", json_string(SCErrorToString(error_code)));
233  }
234 
235  if (message)
236  json_object_set_new(ejs, "message", json_string(message));
237 
238  if (log_level >= SC_LOG_DEBUG) {
239  if (function)
240  json_object_set_new(ejs, "function", json_string(function));
241 
242  if (file)
243  json_object_set_new(ejs, "file", json_string(file));
244 
245  if (line > 0)
246  json_object_set_new(ejs, "line", json_integer(line));
247  }
248 
249  json_object_set_new(js, "engine", ejs);
250 
251  char *js_s = json_dumps(js,
252  JSON_PRESERVE_ORDER|JSON_COMPACT|JSON_ENSURE_ASCII|
254  snprintf(buffer, buffer_size, "%s", js_s);
255  free(js_s);
256 
257  json_object_del(js, "engine");
258  json_object_clear(js);
259  json_decref(js);
260 
261  return 0;
262 error:
263  return -1;
264 }
265 
266 /**
267  * \brief Adds the global log_format to the outgoing buffer
268  *
269  * \param log_level log_level of the message that has to be logged
270  * \param msg Buffer containing the outgoing message
271  * \param file File_name from where the message originated
272  * \param function Function_name from where the message originated
273  * \param line Line_no from where the messaged originated
274  *
275  * \retval SC_OK on success; else an error code
276  */
277 static SCError SCLogMessageGetBuffer(
278  struct timeval *tval, int color, SCLogOPType type,
279  char *buffer, size_t buffer_size,
280  const char *log_format,
281 
282  const SCLogLevel log_level, const char *file,
283  const unsigned int line, const char *function,
284  const SCError error_code, const char *message)
285 {
286  if (type == SC_LOG_OP_TYPE_JSON)
287  return SCLogMessageJSON(tval, buffer, buffer_size, log_level, file, line, function, error_code, message);
288 
289  char *temp = buffer;
290  const char *s = NULL;
291  struct tm *tms = NULL;
292 
293  const char *redb = "";
294  const char *red = "";
295  const char *yellowb = "";
296  const char *yellow = "";
297  const char *green = "";
298  const char *blue = "";
299  const char *reset = "";
300  if (color) {
301  redb = "\x1b[1;31m";
302  red = "\x1b[31m";
303  yellowb = "\x1b[1;33m";
304  yellow = "\x1b[33m";
305  green = "\x1b[32m";
306  blue = "\x1b[34m";
307  reset = "\x1b[0m";
308  }
309  /* no of characters_written(cw) by snprintf */
310  int cw = 0;
311 
313 
314  /* make a copy of the format string as it will be modified below */
315  char local_format[strlen(log_format) + 1];
316  strlcpy(local_format, log_format, sizeof(local_format));
317  char *temp_fmt = local_format;
318  char *substr = temp_fmt;
319 
320  while ( (temp_fmt = strchr(temp_fmt, SC_LOG_FMT_PREFIX)) ) {
321  if ((temp - buffer) > SC_LOG_MAX_LOG_MSG_LEN) {
322  return SC_OK;
323  }
324  switch(temp_fmt[1]) {
325  case SC_LOG_FMT_TIME:
326  temp_fmt[0] = '\0';
327 
328  struct tm local_tm;
329  tms = SCLocalTime(tval->tv_sec, &local_tm);
330 
331  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
332  "%s%s%d/%d/%04d -- %02d:%02d:%02d%s",
333  substr, green, tms->tm_mday, tms->tm_mon + 1,
334  tms->tm_year + 1900, tms->tm_hour, tms->tm_min,
335  tms->tm_sec, reset);
336  if (cw < 0)
337  return SC_ERR_SPRINTF;
338  temp += cw;
339  temp_fmt++;
340  substr = temp_fmt;
341  substr++;
342  break;
343 
344  case SC_LOG_FMT_PID:
345  temp_fmt[0] = '\0';
346  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
347  "%s%s%u%s", substr, yellow, getpid(), reset);
348  if (cw < 0)
349  return SC_ERR_SPRINTF;
350  temp += cw;
351  temp_fmt++;
352  substr = temp_fmt;
353  substr++;
354  break;
355 
356  case SC_LOG_FMT_TID:
357  temp_fmt[0] = '\0';
358  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
359  "%s%s%lu%s", substr, yellow, SCGetThreadIdLong(), reset);
360  if (cw < 0)
361  return SC_ERR_SPRINTF;
362  temp += cw;
363  temp_fmt++;
364  substr = temp_fmt;
365  substr++;
366  break;
367 
368  case SC_LOG_FMT_TM:
369  temp_fmt[0] = '\0';
370 /* disabled to prevent dead lock:
371  * log or alloc (which calls log on error) can call TmThreadsGetCallingThread
372  * which will lock tv_root_lock. This can happen while we already hold this
373  * lock. */
374 #if 0
376  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - *msg),
377  "%s%s", substr, ((tv != NULL)? tv->name: "UNKNOWN TM"));
378 #endif
379  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
380  "%s%s", substr, "N/A");
381  if (cw < 0)
382  return SC_ERR_SPRINTF;
383  temp += cw;
384  temp_fmt++;
385  substr = temp_fmt;
386  substr++;
387  break;
388 
390  temp_fmt[0] = '\0';
391  s = SCMapEnumValueToName(log_level, sc_log_level_map);
392  if (s != NULL) {
393  if (log_level <= SC_LOG_ERROR)
394  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
395  "%s%s%s%s", substr, redb, s, reset);
396  else if (log_level == SC_LOG_WARNING)
397  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
398  "%s%s%s%s", substr, red, s, reset);
399  else if (log_level == SC_LOG_NOTICE)
400  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
401  "%s%s%s%s", substr, yellowb, s, reset);
402  else
403  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
404  "%s%s%s%s", substr, yellow, s, reset);
405  } else {
406  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
407  "%s%s", substr, "INVALID");
408  }
409  if (cw < 0)
410  return SC_ERR_SPRINTF;
411  temp += cw;
412  temp_fmt++;
413  substr = temp_fmt;
414  substr++;
415  break;
416 
418  temp_fmt[0] = '\0';
419  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
420  "%s%s%s%s", substr, blue, file, reset);
421  if (cw < 0)
422  return SC_ERR_SPRINTF;
423  temp += cw;
424  temp_fmt++;
425  substr = temp_fmt;
426  substr++;
427  break;
428 
429  case SC_LOG_FMT_LINE:
430  temp_fmt[0] = '\0';
431  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
432  "%s%s%u%s", substr, green, line, reset);
433  if (cw < 0)
434  return SC_ERR_SPRINTF;
435  temp += cw;
436  temp_fmt++;
437  substr = temp_fmt;
438  substr++;
439  break;
440 
441  case SC_LOG_FMT_FUNCTION:
442  temp_fmt[0] = '\0';
443  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
444  "%s%s%s%s", substr, green, function, reset);
445  if (cw < 0)
446  return SC_ERR_SPRINTF;
447  temp += cw;
448  temp_fmt++;
449  substr = temp_fmt;
450  substr++;
451  break;
452 
453  }
454  temp_fmt++;
455  }
456  if ((temp - buffer) > SC_LOG_MAX_LOG_MSG_LEN) {
457  return SC_OK;
458  }
459  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), "%s", substr);
460  if (cw < 0) {
461  return SC_ERR_SPRINTF;
462  }
463  temp += cw;
464  if ((temp - buffer) > SC_LOG_MAX_LOG_MSG_LEN) {
465  return SC_OK;
466  }
467 
468  if (error_code != SC_OK) {
469  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
470  "[%sERRCODE%s: %s%s%s(%s%d%s)] - ", yellow, reset, red, SCErrorToString(error_code), reset, yellow, error_code, reset);
471  if (cw < 0) {
472  return SC_ERR_SPRINTF;
473  }
474  temp += cw;
475  if ((temp - buffer) > SC_LOG_MAX_LOG_MSG_LEN) {
476  return SC_OK;
477  }
478  }
479 
480  const char *hi = "";
481  if (error_code > SC_OK)
482  hi = red;
483  else if (log_level <= SC_LOG_NOTICE)
484  hi = yellow;
485  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), "%s%s%s", hi, message, reset);
486  if (cw < 0) {
487  return SC_ERR_SPRINTF;
488  }
489  temp += cw;
490  if ((temp - buffer) > SC_LOG_MAX_LOG_MSG_LEN) {
491  return SC_OK;
492  }
493 
494  if (sc_log_config->op_filter_regex != NULL) {
495  if (pcre2_match(sc_log_config->op_filter_regex, (PCRE2_SPTR8)buffer, strlen(buffer), 0, 0,
496  sc_log_config->op_filter_regex_match, NULL) < 0) {
497  return SC_ERR_LOG_FG_FILTER_MATCH; // bit hacky, but just return !0
498  }
499  }
500 
501  return SC_OK;
502 }
503 
504 /** \internal
505  * \brief try to reopen file
506  * \note no error reporting here, as we're called by SCLogMessage
507  * \retval status 0 ok, -1 error */
508 static int SCLogReopen(SCLogOPIfaceCtx *op_iface_ctx)
509 {
510  if (op_iface_ctx->file == NULL) {
511  return 0;
512  }
513 
514  if (op_iface_ctx->file_d != NULL) {
515  fclose(op_iface_ctx->file_d);
516  }
517  op_iface_ctx->file_d = fopen(op_iface_ctx->file, "a");
518  if (op_iface_ctx->file_d == NULL) {
519  return -1;
520  }
521  return 0;
522 }
523 
524 /**
525  * \brief Adds the global log_format to the outgoing buffer
526  *
527  * \param log_level log_level of the message that has to be logged
528  * \param msg Buffer containing the outgoing message
529  * \param file File_name from where the message originated
530  * \param function Function_name from where the message originated
531  * \param line Line_no from where the messaged originated
532  *
533  * \retval SC_OK on success; else an error code
534  */
535 SCError SCLogMessage(const SCLogLevel log_level, const char *file,
536  const unsigned int line, const char *function,
537  const SCError error_code, const char *message)
538 {
539  char buffer[SC_LOG_MAX_LOG_MSG_LEN] = "";
540  SCLogOPIfaceCtx *op_iface_ctx = NULL;
541 
542  if (sc_log_module_initialized != 1) {
543  printf("Logging module not initialized. Call SCLogInitLogModule() "
544  "first before using the debug API\n");
545  return SC_OK;
546  }
547 
548  /* get ts here so we log the same ts to each output */
549  struct timeval tval;
550  gettimeofday(&tval, NULL);
551 
552  op_iface_ctx = sc_log_config->op_ifaces;
553  while (op_iface_ctx != NULL) {
554  if (log_level != SC_LOG_NOTSET && log_level > op_iface_ctx->log_level) {
555  op_iface_ctx = op_iface_ctx->next;
556  continue;
557  }
558 
559  switch (op_iface_ctx->iface) {
561  if (SCLogMessageGetBuffer(&tval, op_iface_ctx->use_color, op_iface_ctx->type,
562  buffer, sizeof(buffer),
563  op_iface_ctx->log_format ?
564  op_iface_ctx->log_format : sc_log_config->log_format,
565  log_level, file, line, function,
566  error_code, message) == 0)
567  {
568  SCLogPrintToStream((log_level == SC_LOG_ERROR)? stderr: stdout, buffer);
569  }
570  break;
572  if (SCLogMessageGetBuffer(&tval, 0, op_iface_ctx->type, buffer, sizeof(buffer),
573  op_iface_ctx->log_format ?
574  op_iface_ctx->log_format : sc_log_config->log_format,
575  log_level, file, line, function,
576  error_code, message) == 0)
577  {
578  int r = 0;
579  SCMutexLock(&op_iface_ctx->fp_mutex);
580  if (op_iface_ctx->rotation_flag) {
581  r = SCLogReopen(op_iface_ctx);
582  op_iface_ctx->rotation_flag = 0;
583  }
584  SCLogPrintToStream(op_iface_ctx->file_d, buffer);
585  SCMutexUnlock(&op_iface_ctx->fp_mutex);
586 
587  /* report error outside of lock to avoid recursion */
588  if (r == -1) {
589  SCLogError(SC_ERR_FOPEN, "re-opening file \"%s\" failed: %s",
590  op_iface_ctx->file, strerror(errno));
591  }
592  }
593  break;
595  if (SCLogMessageGetBuffer(&tval, 0, op_iface_ctx->type, buffer, sizeof(buffer),
596  op_iface_ctx->log_format ?
597  op_iface_ctx->log_format : sc_log_config->log_format,
598  log_level, file, line, function,
599  error_code, message) == 0)
600  {
601  SCLogPrintToSyslog(SCLogMapLogLevelToSyslogLevel(log_level), buffer);
602  }
603  break;
604  default:
605  break;
606  }
607  op_iface_ctx = op_iface_ctx->next;
608  }
609  return SC_OK;
610 }
611 
612 void SCLog(int x, const char *file, const char *func, const int line,
613  const char *fmt, ...)
614 {
615  if (sc_log_global_log_level >= x &&
617  SCLogMatchFGFilterWL(file, func, line) == 1 ||
618  SCLogMatchFGFilterBL(file, func, line) == 1) &&
620  SCLogMatchFDFilter(func) == 1))
621  {
623  va_list ap;
624  va_start(ap, fmt);
625  vsnprintf(msg, sizeof(msg), fmt, ap);
626  va_end(ap);
627  SCLogMessage(x, file, line, func, SC_OK, msg);
628  }
629 }
630 
631 void SCLogErr(int x, const char *file, const char *func, const int line,
632  const int err, const char *fmt, ...)
633 {
634  if (sc_log_global_log_level >= x &&
636  SCLogMatchFGFilterWL(file, func, line) == 1 ||
637  SCLogMatchFGFilterBL(file, func, line) == 1) &&
639  SCLogMatchFDFilter(func) == 1))
640  {
642  va_list ap;
643  va_start(ap, fmt);
644  vsnprintf(msg, sizeof(msg), fmt, ap);
645  va_end(ap);
646  SCLogMessage(x, file, line, func, err, msg);
647  }
648 }
649 
650 /**
651  * \brief Returns whether debug messages are enabled to be logged or not
652  *
653  * \retval 1 if debug messages are enabled to be logged
654  * \retval 0 if debug messages are not enabled to be logged
655  */
657 {
658 #ifdef DEBUG
660  return 1;
661  else
662  return 0;
663 #else
664  return 0;
665 #endif
666 }
667 
668 /**
669  * \brief Allocates an output buffer for an output interface. Used when we
670  * want the op_interface log_format to override the global_log_format.
671  * Currently not used.
672  *
673  * \retval buffer Pointer to the newly created output_buffer
674  */
676 {
677  SCLogOPBuffer *buffer = NULL;
678  SCLogOPIfaceCtx *op_iface_ctx = NULL;
679  int i = 0;
680 
681  if ( (buffer = SCMalloc(sc_log_config->op_ifaces_cnt *
682  sizeof(SCLogOPBuffer))) == NULL) {
684  "Fatal error encountered in SCLogAllocLogOPBuffer. Exiting...");
685  }
686 
687  op_iface_ctx = sc_log_config->op_ifaces;
688  for (i = 0;
689  i < sc_log_config->op_ifaces_cnt;
690  i++, op_iface_ctx = op_iface_ctx->next) {
691  buffer[i].log_format = op_iface_ctx->log_format;
692  buffer[i].temp = buffer[i].msg;
693  }
694 
695  return buffer;
696 }
697 
698 /*----------------------The logging module initialization code--------------- */
699 
700 /**
701  * \brief Returns a new output_interface_context
702  *
703  * \retval iface_ctx Pointer to a newly allocated output_interface_context
704  * \initonly
705  */
706 static inline SCLogOPIfaceCtx *SCLogAllocLogOPIfaceCtx(void)
707 {
708  SCLogOPIfaceCtx *iface_ctx = NULL;
709 
710  if ( (iface_ctx = SCMalloc(sizeof(SCLogOPIfaceCtx))) == NULL) {
712  "Fatal error encountered in SCLogallocLogOPIfaceCtx. Exiting...");
713  }
714  memset(iface_ctx, 0, sizeof(SCLogOPIfaceCtx));
715 
716  return iface_ctx;
717 }
718 
719 /**
720  * \brief Initializes the file output interface
721  *
722  * \param file Path to the file used for logging purposes
723  * \param log_format Pointer to the log_format for this op interface, that
724  * overrides the global_log_format
725  * \param log_level Override of the global_log_level by this interface
726  *
727  * \retval iface_ctx Pointer to the file output interface context created
728  * \initonly
729  */
730 static inline SCLogOPIfaceCtx *SCLogInitFileOPIface(const char *file,
731  const char *log_format,
732  int log_level,
734 {
735  SCLogOPIfaceCtx *iface_ctx = SCLogAllocLogOPIfaceCtx();
736 
737  if (iface_ctx == NULL) {
739  "Fatal error encountered in SCLogInitFileOPIface. Exiting...");
740  }
741 
742  if (file == NULL) {
743  goto error;
744  }
745 
746  iface_ctx->iface = SC_LOG_OP_IFACE_FILE;
747  iface_ctx->type = type;
748 
749  if ( (iface_ctx->file_d = fopen(file, "a")) == NULL) {
750  printf("Error opening file %s\n", file);
751  goto error;
752  }
753 
754  if ((iface_ctx->file = SCStrdup(file)) == NULL) {
755  goto error;
756  }
757 
758  if (log_format != NULL && (iface_ctx->log_format = SCStrdup(log_format)) == NULL) {
759  goto error;
760  }
761 
762  SCMutexInit(&iface_ctx->fp_mutex, NULL);
764 
765  iface_ctx->log_level = log_level;
766 
767  return iface_ctx;
768 
769 error:
770  if (iface_ctx->file != NULL) {
771  SCFree((char *)iface_ctx->file);
772  iface_ctx->file = NULL;
773  }
774  if (iface_ctx->log_format != NULL) {
775  SCFree((char *)iface_ctx->log_format);
776  iface_ctx->log_format = NULL;
777  }
778  if (iface_ctx->file_d != NULL) {
779  fclose(iface_ctx->file_d);
780  iface_ctx->file_d = NULL;
781  }
782  SCFree(iface_ctx);
783  return NULL;
784 }
785 
786 /**
787  * \brief Initializes the console output interface and deals with possible
788  * env var overrides.
789  *
790  * \param log_format Pointer to the log_format for this op interface, that
791  * overrides the global_log_format
792  * \param log_level Override of the global_log_level by this interface
793  *
794  * \retval iface_ctx Pointer to the console output interface context created
795  * \initonly
796  */
797 static inline SCLogOPIfaceCtx *SCLogInitConsoleOPIface(const char *log_format,
798  SCLogLevel log_level, SCLogOPType type)
799 {
800  SCLogOPIfaceCtx *iface_ctx = SCLogAllocLogOPIfaceCtx();
801 
802  if (iface_ctx == NULL) {
804  "Fatal error encountered in SCLogInitConsoleOPIface. Exiting...");
805  }
806 
807  iface_ctx->iface = SC_LOG_OP_IFACE_CONSOLE;
808  iface_ctx->type = type;
809 
810  /* console log format is overridden by envvars */
811  const char *tmp_log_format = log_format;
812  const char *s = getenv(SC_LOG_ENV_LOG_FORMAT);
813  if (s != NULL) {
814 #if 0
815  printf("Overriding setting for \"console.format\" because of env "
816  "var SC_LOG_FORMAT=\"%s\".\n", s);
817 #endif
818  tmp_log_format = s;
819  }
820 
821  if (tmp_log_format != NULL &&
822  (iface_ctx->log_format = SCStrdup(tmp_log_format)) == NULL) {
823  printf("Error allocating memory\n");
824  exit(EXIT_FAILURE);
825  }
826 
827  /* console log level is overridden by envvars */
828  SCLogLevel tmp_log_level = log_level;
829  s = getenv(SC_LOG_ENV_LOG_LEVEL);
830  if (s != NULL) {
832  if (l > SC_LOG_NOTSET && l < SC_LOG_LEVEL_MAX) {
833 #if 0
834  printf("Overriding setting for \"console.level\" because of env "
835  "var SC_LOG_LEVEL=\"%s\".\n", s);
836 #endif
837  tmp_log_level = l;
838  }
839  }
840  iface_ctx->log_level = tmp_log_level;
841 
842 #ifndef OS_WIN32
843  if (isatty(fileno(stdout)) && isatty(fileno(stderr))) {
844  iface_ctx->use_color = TRUE;
845  }
846 #endif
847 
848  return iface_ctx;
849 }
850 
851 /**
852  * \brief Initializes the syslog output interface
853  *
854  * \param facility The facility code for syslog
855  * \param log_format Pointer to the log_format for this op interface, that
856  * overrides the global_log_format
857  * \param log_level Override of the global_log_level by this interface
858  *
859  * \retval iface_ctx Pointer to the syslog output interface context created
860  */
861 static inline SCLogOPIfaceCtx *SCLogInitSyslogOPIface(int facility,
862  const char *log_format,
863  SCLogLevel log_level,
865 {
866  SCLogOPIfaceCtx *iface_ctx = SCLogAllocLogOPIfaceCtx();
867 
868  if ( iface_ctx == NULL) {
870  "Fatal error encountered in SCLogInitSyslogOPIface. Exiting...");
871  }
872 
873  iface_ctx->iface = SC_LOG_OP_IFACE_SYSLOG;
874  iface_ctx->type = type;
875 
876  if (facility == -1)
877  facility = SC_LOG_DEF_SYSLOG_FACILITY;
878  iface_ctx->facility = facility;
879 
880  if (log_format != NULL &&
881  (iface_ctx->log_format = SCStrdup(log_format)) == NULL) {
882  printf("Error allocating memory\n");
883  exit(EXIT_FAILURE);
884  }
885 
886  iface_ctx->log_level = log_level;
887 
888  openlog(NULL, LOG_NDELAY, iface_ctx->facility);
889 
890  return iface_ctx;
891 }
892 
893 /**
894  * \brief Frees the output_interface context supplied as an argument
895  *
896  * \param iface_ctx Pointer to the op_interface_context to be freed
897  */
898 static inline void SCLogFreeLogOPIfaceCtx(SCLogOPIfaceCtx *iface_ctx)
899 {
900  SCLogOPIfaceCtx *temp = NULL;
901 
902  while (iface_ctx != NULL) {
903  temp = iface_ctx;
904 
905  if (iface_ctx->file_d != NULL) {
906  fclose(iface_ctx->file_d);
907  SCMutexDestroy(&iface_ctx->fp_mutex);
908  }
909 
910  if (iface_ctx->file != NULL)
911  SCFree((void *)iface_ctx->file);
912 
913  if (iface_ctx->log_format != NULL)
914  SCFree((void *)iface_ctx->log_format);
915 
916  if (iface_ctx->iface == SC_LOG_OP_IFACE_SYSLOG) {
917  closelog();
918  }
919 
920  iface_ctx = iface_ctx->next;
921 
922  SCFree(temp);
923  }
924 
925  return;
926 }
927 
928 /**
929  * \brief Internal function used to set the logging module global_log_level
930  * during the initialization phase
931  *
932  * \param sc_lid The initialization data supplied.
933  * \param sc_lc The logging module context which has to be updated.
934  */
935 static inline void SCLogSetLogLevel(SCLogInitData *sc_lid, SCLogConfig *sc_lc)
936 {
937  SCLogLevel log_level = SC_LOG_NOTSET;
938  const char *s = NULL;
939 
940  /* envvar overrides config */
941  s = getenv(SC_LOG_ENV_LOG_LEVEL);
942  if (s != NULL) {
943  log_level = SCMapEnumNameToValue(s, sc_log_level_map);
944  } else if (sc_lid != NULL) {
945  log_level = sc_lid->global_log_level;
946  }
947 
948  /* deal with the global_log_level to be used */
949  if (log_level > SC_LOG_NOTSET && log_level < SC_LOG_LEVEL_MAX)
950  sc_lc->log_level = log_level;
951  else {
953 #ifndef UNITTESTS
954  if (sc_lid != NULL) {
955  printf("Warning: Invalid/No global_log_level assigned by user. Falling "
956  "back on the default_log_level \"%s\"\n",
958  }
959 #endif
960  }
961 
962  /* we also set it to a global var, as it is easier to access it */
964 
965  return;
966 }
967 
969 {
971 }
972 
973 static inline const char *SCLogGetDefaultLogFormat(void)
974 {
975  const char *prog_ver = GetProgramVersion();
976  if (strstr(prog_ver, "RELEASE") != NULL) {
978  }
980 }
981 
982 /**
983  * \brief Internal function used to set the logging module global_log_format
984  * during the initialization phase
985  *
986  * \param sc_lid The initialization data supplied.
987  * \param sc_lc The logging module context which has to be updated.
988  */
989 static inline void SCLogSetLogFormat(SCLogInitData *sc_lid, SCLogConfig *sc_lc)
990 {
991  const char *format = NULL;
992 
993  /* envvar overrides config */
994  format = getenv(SC_LOG_ENV_LOG_FORMAT);
995  if (format == NULL) {
996  if (sc_lid != NULL) {
997  format = sc_lid->global_log_format;
998  }
999  }
1000 
1001  /* deal with the global log format to be used */
1002  if (format == NULL || strlen(format) > SC_LOG_MAX_LOG_FORMAT_LEN) {
1003  format = SCLogGetDefaultLogFormat();
1004 #ifndef UNITTESTS
1005  if (sc_lid != NULL) {
1006  printf("Warning: Invalid/No global_log_format supplied by user or format "
1007  "length exceeded limit of \"%d\" characters. Falling back on "
1008  "default log_format \"%s\"\n", SC_LOG_MAX_LOG_FORMAT_LEN,
1009  format);
1010  }
1011 #endif
1012  }
1013 
1014  if (format != NULL && (sc_lc->log_format = SCStrdup(format)) == NULL) {
1015  printf("Error allocating memory\n");
1016  exit(EXIT_FAILURE);
1017  }
1018 
1019  return;
1020 }
1021 
1022 /**
1023  * \brief Internal function used to set the logging module global_op_ifaces
1024  * during the initialization phase
1025  *
1026  * \param sc_lid The initialization data supplied.
1027  * \param sc_lc The logging module context which has to be updated.
1028  */
1029 static inline void SCLogSetOPIface(SCLogInitData *sc_lid, SCLogConfig *sc_lc)
1030 {
1031  SCLogOPIfaceCtx *op_ifaces_ctx = NULL;
1032  int op_iface = 0;
1033  const char *s = NULL;
1034 
1035  if (sc_lid != NULL && sc_lid->op_ifaces != NULL) {
1036  sc_lc->op_ifaces = sc_lid->op_ifaces;
1037  sc_lid->op_ifaces = NULL;
1038  sc_lc->op_ifaces_cnt = sc_lid->op_ifaces_cnt;
1039  } else {
1040  s = getenv(SC_LOG_ENV_LOG_OP_IFACE);
1041  if (s != NULL) {
1043 
1044  if(op_iface < 0 || op_iface >= SC_LOG_OP_IFACE_MAX) {
1045  op_iface = SC_LOG_DEF_LOG_OP_IFACE;
1046 #ifndef UNITTESTS
1047  printf("Warning: Invalid output interface supplied by user. "
1048  "Falling back on default_output_interface \"%s\"\n",
1050 #endif
1051  }
1052  }
1053  else {
1054  op_iface = SC_LOG_DEF_LOG_OP_IFACE;
1055 #ifndef UNITTESTS
1056  if (sc_lid != NULL) {
1057  printf("Warning: Output_interface not supplied by user. Falling "
1058  "back on default_output_interface \"%s\"\n",
1060  }
1061 #endif
1062  }
1063 
1064  switch (op_iface) {
1066  op_ifaces_ctx = SCLogInitConsoleOPIface(NULL, SC_LOG_LEVEL_MAX,0);
1067  break;
1068  case SC_LOG_OP_IFACE_FILE:
1069  s = getenv(SC_LOG_ENV_LOG_FILE);
1070  if (s == NULL) {
1071  char *str = SCLogGetLogFilename(SC_LOG_DEF_LOG_FILE);
1072  if (str != NULL) {
1073  op_ifaces_ctx = SCLogInitFileOPIface(str, NULL, SC_LOG_LEVEL_MAX,0);
1074  SCFree(str);
1075  }
1076  } else {
1077  op_ifaces_ctx = SCLogInitFileOPIface(s, NULL, SC_LOG_LEVEL_MAX,0);
1078  }
1079  break;
1081  s = getenv(SC_LOG_ENV_LOG_FACILITY);
1082  if (s == NULL)
1084 
1085  op_ifaces_ctx = SCLogInitSyslogOPIface(SCMapEnumNameToValue(s, SCSyslogGetFacilityMap()), NULL, -1,0);
1086  break;
1087  }
1088  sc_lc->op_ifaces = op_ifaces_ctx;
1089  sc_lc->op_ifaces_cnt++;
1090  }
1091  return;
1092 }
1093 
1094 /**
1095  * \brief Internal function used to set the logging module op_filter
1096  * during the initialization phase
1097  *
1098  * \param sc_lid The initialization data supplied.
1099  * \param sc_lc The logging module context which has to be updated.
1100  */
1101 static inline void SCLogSetOPFilter(SCLogInitData *sc_lid, SCLogConfig *sc_lc)
1102 {
1103  const char *filter = NULL;
1104 
1105  int opts = 0;
1106  int en;
1107  PCRE2_SIZE eo = 0;
1108 
1109  /* envvar overrides */
1110  filter = getenv(SC_LOG_ENV_LOG_OP_FILTER);
1111  if (filter == NULL) {
1112  if (sc_lid != NULL) {
1113  filter = sc_lid->op_filter;
1114  }
1115  }
1116 
1117  if (filter != NULL && strcmp(filter, "") != 0) {
1118  sc_lc->op_filter = SCStrdup(filter);
1119  if (sc_lc->op_filter == NULL) {
1120  printf("pcre filter alloc failed\n");
1121  return;
1122  }
1123  sc_lc->op_filter_regex =
1124  pcre2_compile((PCRE2_SPTR8)filter, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
1125  if (sc_lc->op_filter_regex == NULL) {
1126  SCFree(sc_lc->op_filter);
1127  PCRE2_UCHAR errbuffer[256];
1128  pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
1129  printf("pcre2 compile of \"%s\" failed at offset %d : %s\n", filter, (int)eo,
1130  errbuffer);
1131  return;
1132  }
1133  sc_lc->op_filter_regex_match =
1134  pcre2_match_data_create_from_pattern(sc_lc->op_filter_regex, NULL);
1135  }
1136 
1137  return;
1138 }
1139 
1140 /**
1141  * \brief Returns a pointer to a new SCLogInitData. This is a public interface
1142  * intended to be used after the logging paramters are read from the
1143  * conf file
1144  *
1145  * \retval sc_lid Pointer to the newly created SCLogInitData
1146  * \initonly
1147  */
1149 {
1150  SCLogInitData *sc_lid = NULL;
1151 
1152  /* not using SCMalloc here because if it fails we can't log */
1153  if ( (sc_lid = SCMalloc(sizeof(SCLogInitData))) == NULL)
1154  return NULL;
1155 
1156  memset(sc_lid, 0, sizeof(SCLogInitData));
1157 
1158  return sc_lid;
1159 }
1160 
1161 #ifdef UNITTESTS
1162 #ifndef OS_WIN32
1163 /**
1164  * \brief Frees a SCLogInitData
1165  *
1166  * \param sc_lid Pointer to the SCLogInitData to be freed
1167  */
1168 static void SCLogFreeLogInitData(SCLogInitData *sc_lid)
1169 {
1170  if (sc_lid != NULL) {
1171  SCLogFreeLogOPIfaceCtx(sc_lid->op_ifaces);
1172  SCFree(sc_lid);
1173  }
1174 
1175  return;
1176 }
1177 #endif
1178 #endif
1179 
1180 /**
1181  * \brief Frees the logging module context
1182  */
1183 static inline void SCLogFreeLogConfig(SCLogConfig *sc_lc)
1184 {
1185  if (sc_lc != NULL) {
1186  if (sc_lc->startup_message != NULL)
1187  SCFree(sc_lc->startup_message);
1188  if (sc_lc->log_format != NULL)
1189  SCFree(sc_lc->log_format);
1190  if (sc_lc->op_filter != NULL)
1191  SCFree(sc_lc->op_filter);
1192 
1193  if (sc_lc->op_filter_regex != NULL)
1194  pcre2_code_free(sc_lc->op_filter_regex);
1195  if (sc_lc->op_filter_regex_match)
1196  pcre2_match_data_free(sc_lc->op_filter_regex_match);
1197 
1198  SCLogFreeLogOPIfaceCtx(sc_lc->op_ifaces);
1199  SCFree(sc_lc);
1200  }
1201 
1202  return;
1203 }
1204 
1205 /**
1206  * \brief Appends an output_interface to the output_interface list sent in head
1207  *
1208  * \param iface_ctx Pointer to the output_interface that has to be added to head
1209  * \param head Pointer to the output_interface list
1210  */
1212 {
1213  SCLogOPIfaceCtx *temp = NULL, *prev = NULL;
1214  SCLogOPIfaceCtx **head = &sc_lid->op_ifaces;
1215 
1216  if (iface_ctx == NULL) {
1217 #ifdef DEBUG
1218  printf("Argument(s) to SCLogAppendOPIfaceCtx() NULL\n");
1219 #endif
1220  return;
1221  }
1222 
1223  temp = *head;
1224  while (temp != NULL) {
1225  prev = temp;
1226  temp = temp->next;
1227  }
1228 
1229  if (prev == NULL)
1230  *head = iface_ctx;
1231  else
1232  prev->next = iface_ctx;
1233 
1234  sc_lid->op_ifaces_cnt++;
1235 
1236  return;
1237 }
1238 
1239 
1240 /**
1241  * \brief Creates a new output interface based on the arguments sent. The kind
1242  * of output interface to be created is decided by the iface_name arg.
1243  * If iface_name is "file", the arg argument will hold the filename to be
1244  * used for logging purposes. If iface_name is "syslog", the arg
1245  * argument holds the facility code. If iface_name is "console", arg is
1246  * NULL.
1247  *
1248  * \param iface_name Interface name. Can be "console", "file" or "syslog"
1249  * \param log_format Override for the global_log_format
1250  * \param log_level Override for the global_log_level
1251  * \param log_level Parameter required by a particular interface. Explained in
1252  * the function description
1253  *
1254  * \retval iface_ctx Pointer to the newly created output interface
1255  */
1256 SCLogOPIfaceCtx *SCLogInitOPIfaceCtx(const char *iface_name,
1257  const char *log_format,
1258  int log_level, const char *arg)
1259 {
1260  int iface = SCMapEnumNameToValue(iface_name, sc_log_op_iface_map);
1261 
1262  if (log_level < SC_LOG_NONE || log_level > SC_LOG_DEBUG) {
1263 #ifndef UNITTESTS
1264  printf("Warning: Supplied log_level_override for op_interface \"%s\" "
1265  "is invalid. Defaulting to not specifying an override\n",
1266  iface_name);
1267 #endif
1268  log_level = SC_LOG_NOTSET;
1269  }
1270 
1271  switch (iface) {
1273  return SCLogInitConsoleOPIface(log_format, log_level, SC_LOG_OP_TYPE_REGULAR);
1274  case SC_LOG_OP_IFACE_FILE:
1275  return SCLogInitFileOPIface(arg, log_format, log_level, SC_LOG_OP_TYPE_REGULAR);
1277  return SCLogInitSyslogOPIface(SCMapEnumNameToValue(arg, SCSyslogGetFacilityMap()),
1278  log_format, log_level, SC_LOG_OP_TYPE_REGULAR);
1279  default:
1280 #ifdef DEBUG
1281  printf("Output Interface \"%s\" not supported by the logging module",
1282  iface_name);
1283 #endif
1284  return NULL;
1285  }
1286 }
1287 
1288 /**
1289  * \brief Initializes the logging module.
1290  *
1291  * \param sc_lid The initialization data for the logging module. If sc_lid is
1292  * NULL, we would stick to the default configuration for the
1293  * logging subsystem.
1294  * \initonly
1295  */
1297 {
1298  /* De-initialize the logging context, if it has already init by the
1299  * environment variables at the start of the engine */
1301 
1302 #if defined (OS_WIN32)
1303  if (SCMutexInit(&sc_log_stream_lock, NULL) != 0) {
1304  FatalError(SC_ERR_FATAL, "Failed to initialize log mutex.");
1305  }
1306 #endif /* OS_WIN32 */
1307 
1308  /* sc_log_config is a global variable */
1309  if ( (sc_log_config = SCMalloc(sizeof(SCLogConfig))) == NULL) {
1311  "Fatal error encountered in SCLogInitLogModule. Exiting...");
1312  }
1313  memset(sc_log_config, 0, sizeof(SCLogConfig));
1314 
1315  SCLogSetLogLevel(sc_lid, sc_log_config);
1316  SCLogSetLogFormat(sc_lid, sc_log_config);
1317  SCLogSetOPIface(sc_lid, sc_log_config);
1318  SCLogSetOPFilter(sc_lid, sc_log_config);
1319 
1322 
1323  //SCOutputPrint(sc_did->startup_message);
1324 
1325  rs_log_set_level(sc_log_global_log_level);
1326  return;
1327 }
1328 
1329 void SCLogLoadConfig(int daemon, int verbose)
1330 {
1331  ConfNode *outputs;
1332  SCLogInitData *sc_lid;
1333  int have_logging = 0;
1334  int max_level = 0;
1335  SCLogLevel min_level = 0;
1336 
1337  /* If verbose logging was requested, set the minimum as
1338  * SC_LOG_NOTICE plus the extra verbosity. */
1339  if (verbose) {
1340  min_level = SC_LOG_NOTICE + verbose;
1341  }
1342 
1343  outputs = ConfGetNode("logging.outputs");
1344  if (outputs == NULL) {
1345  SCLogDebug("No logging.output configuration section found.");
1346  return;
1347  }
1348 
1349  sc_lid = SCLogAllocLogInitData();
1350  if (sc_lid == NULL) {
1351  SCLogDebug("Could not allocate memory for log init data");
1352  return;
1353  }
1354 
1355  /* Get default log level and format. */
1356  const char *default_log_level_s = NULL;
1357  if (ConfGet("logging.default-log-level", &default_log_level_s) == 1) {
1358  SCLogLevel default_log_level =
1359  SCMapEnumNameToValue(default_log_level_s, sc_log_level_map);
1360  if (default_log_level == -1) {
1361  SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid default log level: %s",
1362  default_log_level_s);
1363  exit(EXIT_FAILURE);
1364  }
1365  sc_lid->global_log_level = MAX(min_level, default_log_level);
1366  }
1367  else {
1368  sc_lid->global_log_level = MAX(min_level, SC_LOG_NOTICE);
1369  }
1370 
1371  if (ConfGet("logging.default-log-format", &sc_lid->global_log_format) != 1)
1372  sc_lid->global_log_format = SCLogGetDefaultLogFormat();
1373 
1374  (void)ConfGet("logging.default-output-filter", &sc_lid->op_filter);
1375 
1376  ConfNode *seq_node, *output;
1377  TAILQ_FOREACH(seq_node, &outputs->head, next) {
1378  SCLogLevel level = sc_lid->global_log_level;
1379  SCLogOPIfaceCtx *op_iface_ctx = NULL;
1380  const char *format;
1381  const char *level_s;
1382 
1383  output = ConfNodeLookupChild(seq_node, seq_node->val);
1384  if (output == NULL)
1385  continue;
1386 
1387  /* By default an output is enabled. */
1388  const char *enabled = ConfNodeLookupChildValue(output, "enabled");
1389  if (enabled != NULL && ConfValIsFalse(enabled))
1390  continue;
1391 
1393  const char *type_s = ConfNodeLookupChildValue(output, "type");
1394  if (type_s != NULL) {
1395  if (strcmp(type_s, "regular") == 0)
1397  else if (strcmp(type_s, "json") == 0) {
1399  }
1400  }
1401 
1402  /* if available use the log format setting for this output,
1403  * otherwise fall back to the global setting. */
1404  format = ConfNodeLookupChildValue(output, "format");
1405  if (format == NULL)
1406  format = sc_lid->global_log_format;
1407 
1408  level_s = ConfNodeLookupChildValue(output, "level");
1409  if (level_s != NULL) {
1410  level = SCMapEnumNameToValue(level_s, sc_log_level_map);
1411  if (level == -1) {
1412  SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid log level: %s",
1413  level_s);
1414  exit(EXIT_FAILURE);
1415  }
1416  max_level = MAX(max_level, level);
1417  }
1418 
1419  /* Increase the level of extra verbosity was requested. */
1420  level = MAX(min_level, level);
1421 
1422  if (strcmp(output->name, "console") == 0) {
1423  op_iface_ctx = SCLogInitConsoleOPIface(format, level, type);
1424  }
1425  else if (strcmp(output->name, "file") == 0) {
1426  const char *filename = ConfNodeLookupChildValue(output, "filename");
1427  if (filename == NULL) {
1429  "Logging to file requires a filename");
1430  }
1431  char *path = NULL;
1432  if (!(PathIsAbsolute(filename))) {
1433  path = SCLogGetLogFilename(filename);
1434  } else {
1435  path = SCStrdup(filename);
1436  }
1437  if (path == NULL)
1438  FatalError(SC_ERR_FATAL, "failed to setup output to file");
1439  have_logging = 1;
1440  op_iface_ctx = SCLogInitFileOPIface(path, format, level, type);
1441  SCFree(path);
1442  }
1443  else if (strcmp(output->name, "syslog") == 0) {
1444  int facility = SC_LOG_DEF_SYSLOG_FACILITY;
1445  const char *facility_s = ConfNodeLookupChildValue(output,
1446  "facility");
1447  if (facility_s != NULL) {
1448  facility = SCMapEnumNameToValue(facility_s, SCSyslogGetFacilityMap());
1449  if (facility == -1) {
1450  SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid syslog "
1451  "facility: \"%s\", now using \"%s\" as syslog "
1452  "facility", facility_s, SC_LOG_DEF_SYSLOG_FACILITY_STR);
1453  facility = SC_LOG_DEF_SYSLOG_FACILITY;
1454  }
1455  }
1456  SCLogDebug("Initializing syslog logging with format \"%s\"", format);
1457  have_logging = 1;
1458  op_iface_ctx = SCLogInitSyslogOPIface(facility, format, level, type);
1459  }
1460  else {
1461  SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid logging method: %s, "
1462  "ignoring", output->name);
1463  }
1464  if (op_iface_ctx != NULL) {
1465  SCLogAppendOPIfaceCtx(op_iface_ctx, sc_lid);
1466  }
1467  }
1468 
1469  if (daemon && (have_logging == 0)) {
1471  "NO logging compatible with daemon mode selected,"
1472  " suricata won't be able to log. Please update "
1473  " 'logging.outputs' in the YAML.");
1474  }
1475 
1476  /* Set the global log level to that of the max level used. */
1477  sc_lid->global_log_level = MAX(sc_lid->global_log_level, max_level);
1478  SCLogInitLogModule(sc_lid);
1479 
1480  SCLogDebug("sc_log_global_log_level: %d", sc_log_global_log_level);
1481  SCLogDebug("sc_lc->log_format: %s", sc_log_config->log_format);
1482  SCLogDebug("SCLogSetOPFilter: filter: %s", sc_log_config->op_filter);
1483 
1484  if (sc_lid != NULL)
1485  SCFree(sc_lid);
1486 }
1487 
1488 /**
1489  * \brief Returns a full file path given a filename uses log dir specified in
1490  * conf or DEFAULT_LOG_DIR
1491  *
1492  * \param filearg The relative filename for which we want a full path include
1493  * log directory
1494  *
1495  * \retval log_filename The fullpath of the logfile to open
1496  */
1497 static char *SCLogGetLogFilename(const char *filearg)
1498 {
1499  const char *log_dir = ConfigGetLogDirectory();
1500  char *log_filename = SCMalloc(PATH_MAX);
1501  if (unlikely(log_filename == NULL))
1502  return NULL;
1503  snprintf(log_filename, PATH_MAX, "%s/%s", log_dir, filearg);
1504  return log_filename;
1505 }
1506 
1507 /**
1508  * \brief De-Initializes the logging module
1509  */
1511 {
1512  SCLogFreeLogConfig(sc_log_config);
1513 
1514  /* reset the global logging_module variables */
1518  sc_log_config = NULL;
1519 
1520  /* de-init the FD filters */
1522  /* de-init the FG filters */
1524 
1525 #if defined (OS_WIN32)
1526  SCMutexDestroy(&sc_log_stream_lock);
1527 #endif /* OS_WIN32 */
1528 
1529  return;
1530 }
1531 
1532 //------------------------------------Unit_Tests--------------------------------
1533 
1534 /* The logging engine should be tested to the maximum extent possible, since
1535  * logging code would be used throughout the codebase, and hence we can't afford
1536  * to have a single bug here(not that you can afford to have a bug
1537  * elsewhere ;) ). Please report a bug, if you get a slightest hint of a bug
1538  * from the logging module.
1539  */
1540 
1541 #ifdef UNITTESTS
1542 
1543 static int SCLogTestInit01(void)
1544 {
1545 #ifndef OS_WIN32
1546  /* unset any environment variables set for the logging module */
1550 
1551  SCLogInitLogModule(NULL);
1552 
1553  FAIL_IF_NULL(sc_log_config);
1554 
1555  FAIL_IF_NOT(SC_LOG_DEF_LOG_LEVEL == sc_log_config->log_level);
1556  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1557  SC_LOG_DEF_LOG_OP_IFACE == sc_log_config->op_ifaces->iface);
1558  FAIL_IF_NOT(sc_log_config->log_format != NULL &&
1559  strcmp(SCLogGetDefaultLogFormat(), sc_log_config->log_format) == 0);
1560 
1562 
1563  setenv(SC_LOG_ENV_LOG_LEVEL, "Debug", 1);
1564  setenv(SC_LOG_ENV_LOG_OP_IFACE, "Console", 1);
1565  setenv(SC_LOG_ENV_LOG_FORMAT, "%n- %l", 1);
1566 
1567  SCLogInitLogModule(NULL);
1568 
1569  FAIL_IF_NOT(SC_LOG_DEBUG == sc_log_config->log_level);
1570  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1571  SC_LOG_OP_IFACE_CONSOLE == sc_log_config->op_ifaces->iface);
1572  FAIL_IF_NOT(sc_log_config->log_format != NULL &&
1573  !strcmp("%n- %l", sc_log_config->log_format));
1574 
1578 
1580 #endif
1581  PASS;
1582 }
1583 
1584 static int SCLogTestInit02(void)
1585 {
1586 #ifndef OS_WIN32
1587  SCLogInitData *sc_lid = NULL;
1588  SCLogOPIfaceCtx *sc_iface_ctx = NULL;
1589  char *logfile = SCLogGetLogFilename("boo.txt");
1590  sc_lid = SCLogAllocLogInitData();
1591  FAIL_IF_NULL(sc_lid);
1592  sc_lid->startup_message = "Test02";
1593  sc_lid->global_log_level = SC_LOG_DEBUG;
1594  sc_lid->op_filter = "boo";
1595  sc_iface_ctx = SCLogInitOPIfaceCtx("file", "%m - %d", SC_LOG_ALERT,
1596  logfile);
1597  SCLogAppendOPIfaceCtx(sc_iface_ctx, sc_lid);
1598  sc_iface_ctx = SCLogInitOPIfaceCtx("console", NULL, SC_LOG_ERROR,
1599  NULL);
1600  SCLogAppendOPIfaceCtx(sc_iface_ctx, sc_lid);
1601 
1602  SCLogInitLogModule(sc_lid);
1603 
1604  FAIL_IF_NULL(sc_log_config);
1605 
1606  FAIL_IF_NOT(SC_LOG_DEBUG == sc_log_config->log_level);
1607  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1608  SC_LOG_OP_IFACE_FILE == sc_log_config->op_ifaces->iface);
1609  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1610  sc_log_config->op_ifaces->next != NULL &&
1611  SC_LOG_OP_IFACE_CONSOLE == sc_log_config->op_ifaces->next->iface);
1612  FAIL_IF_NOT(sc_log_config->log_format != NULL &&
1613  strcmp(SCLogGetDefaultLogFormat(), sc_log_config->log_format) == 0);
1614  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1615  sc_log_config->op_ifaces->log_format != NULL &&
1616  strcmp("%m - %d", sc_log_config->op_ifaces->log_format) == 0);
1617  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1618  sc_log_config->op_ifaces->next != NULL &&
1619  sc_log_config->op_ifaces->next->log_format == NULL);
1620 
1621  SCLogFreeLogInitData(sc_lid);
1623 
1624  sc_lid = SCLogAllocLogInitData();
1625  FAIL_IF_NULL(sc_lid);
1626  sc_lid->startup_message = "Test02";
1627  sc_lid->global_log_level = SC_LOG_DEBUG;
1628  sc_lid->op_filter = "boo";
1629  sc_lid->global_log_format = "kaboo";
1630 
1631  SCLogInitLogModule(sc_lid);
1632 
1633  FAIL_IF_NULL(sc_log_config);
1634 
1635  FAIL_IF_NOT(SC_LOG_DEBUG == sc_log_config->log_level);
1636  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1637  SC_LOG_OP_IFACE_CONSOLE == sc_log_config->op_ifaces->iface);
1638  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1639  sc_log_config->op_ifaces->next == NULL);
1640  FAIL_IF_NOT(sc_log_config->log_format != NULL &&
1641  strcmp("kaboo", sc_log_config->log_format) == 0);
1642  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1643  sc_log_config->op_ifaces->log_format == NULL);
1644  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1645  sc_log_config->op_ifaces->next == NULL);
1646 
1647  SCLogFreeLogInitData(sc_lid);
1649  SCFree(logfile);
1650 #endif
1651  PASS;
1652 }
1653 
1654 static int SCLogTestInit03(void)
1655 {
1656  SCLogInitLogModule(NULL);
1657 
1658  SCLogAddFGFilterBL(NULL, "bamboo", -1);
1659  SCLogAddFGFilterBL(NULL, "soo", -1);
1660  SCLogAddFGFilterBL(NULL, "dummy", -1);
1661 
1663 
1664  SCLogAddFGFilterBL(NULL, "dummy1", -1);
1665  SCLogAddFGFilterBL(NULL, "dummy2", -1);
1666 
1668 
1670 
1671  PASS;
1672 }
1673 
1674 static int SCLogTestInit04(void)
1675 {
1676  SCLogInitLogModule(NULL);
1677 
1678  SCLogAddFDFilter("bamboo");
1679  SCLogAddFDFilter("soo");
1680  SCLogAddFDFilter("foo");
1681  SCLogAddFDFilter("roo");
1682 
1684 
1685  SCLogAddFDFilter("loo");
1686  SCLogAddFDFilter("soo");
1687 
1689 
1690  SCLogRemoveFDFilter("bamboo");
1691  SCLogRemoveFDFilter("soo");
1692  SCLogRemoveFDFilter("foo");
1693  SCLogRemoveFDFilter("noo");
1694 
1696 
1698 
1699  PASS;
1700 }
1701 
1702 static int SCLogTestInit05(void)
1703 {
1704  char str[4096];
1705  memset(str, 'A', sizeof(str));
1706  SCLogInfo("%s", str);
1707 
1708  PASS;
1709 }
1710 
1711 #endif /* UNITTESTS */
1712 
1714 {
1715 
1716 #ifdef UNITTESTS
1717 
1718  UtRegisterTest("SCLogTestInit01", SCLogTestInit01);
1719  UtRegisterTest("SCLogTestInit02", SCLogTestInit02);
1720  UtRegisterTest("SCLogTestInit03", SCLogTestInit03);
1721  UtRegisterTest("SCLogTestInit04", SCLogTestInit04);
1722  UtRegisterTest("SCLogTestInit05", SCLogTestInit05);
1723 
1724 #endif /* UNITTESTS */
1725 
1726  return;
1727 }
SC_LOG_DEF_LOG_FORMAT_REL
#define SC_LOG_DEF_LOG_FORMAT_REL
Definition: util-debug.h:82
tm-threads.h
SC_LOG_DEF_SYSLOG_FACILITY
#define SC_LOG_DEF_SYSLOG_FACILITY
Definition: util-debug.h:102
SCLogConfig_::op_ifaces
SCLogOPIfaceCtx * op_ifaces
Definition: util-debug.h:183
SCLogMatchFGFilterBL
int SCLogMatchFGFilterBL(const char *file, const char *function, int line)
Checks if there is a match for the incoming log_message with any of the FG filters....
Definition: util-debug-filters.c:309
SC_LOG_DEF_SYSLOG_FACILITY_STR
#define SC_LOG_DEF_SYSLOG_FACILITY_STR
Definition: util-debug.h:101
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
SCLogConfig_::op_filter_regex_match
pcre2_match_data * op_filter_regex_match
Definition: util-debug.h:180
SC_ERR_MISSING_CONFIG_PARAM
@ SC_ERR_MISSING_CONFIG_PARAM
Definition: util-error.h:148
SCLogInitLogModule
void SCLogInitLogModule(SCLogInitData *sc_lid)
Initializes the logging module.
Definition: util-debug.c:1296
ThreadVars_::name
char name[16]
Definition: threadvars.h:65
syslog
#define syslog(__pri, __fmt, __param)
Definition: win32-syslog.h:78
SCLogOPIfaceCtx_::log_level
SCLogLevel log_level
Definition: util-debug.h:135
SCLogLoadConfig
void SCLogLoadConfig(int daemon, int verbose)
Definition: util-debug.c:1329
CreateIsoTimeString
void CreateIsoTimeString(const struct timeval *ts, char *str, size_t size)
Definition: util-time.c:213
sc_log_level_map
SCEnumCharMap sc_log_level_map[]
Definition: util-debug.c:51
SCLogOPIfaceCtx_::facility
int facility
Definition: util-debug.h:132
SC_LOG_DEBUG
@ SC_LOG_DEBUG
Definition: util-debug.h:62
sc_log_fg_filters_present
int sc_log_fg_filters_present
Definition: util-debug-filters.c:33
ConfNode_::val
char * val
Definition: conf.h:34
unsetenv
void unsetenv(const char *name)
SC_LOG_OP_TYPE_REGULAR
@ SC_LOG_OP_TYPE_REGULAR
Definition: util-debug.h:77
SC_LOG_CONFIG
@ SC_LOG_CONFIG
Definition: util-debug.h:61
SCLogAllocLogOPBuffer
SCLogOPBuffer * SCLogAllocLogOPBuffer(void)
Allocates an output buffer for an output interface. Used when we want the op_interface log_format to ...
Definition: util-debug.c:675
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
SC_LOG_NOTSET
@ SC_LOG_NOTSET
Definition: util-debug.h:51
SC_LOG_FMT_PREFIX
#define SC_LOG_FMT_PREFIX
Definition: util-debug.h:199
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
TmThreadsGetCallingThread
ThreadVars * TmThreadsGetCallingThread(void)
Returns the TV for the calling thread.
Definition: tm-threads.c:2027
SC_LOG_FMT_FILE_NAME
#define SC_LOG_FMT_FILE_NAME
Definition: util-debug.h:194
SC_ERR_LOG_FG_FILTER_MATCH
@ SC_ERR_LOG_FG_FILTER_MATCH
Definition: util-error.h:39
SCLogInitData_::global_log_format
const char * global_log_format
Definition: util-debug.h:158
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
SC_LOG_OP_TYPE_JSON
@ SC_LOG_OP_TYPE_JSON
Definition: util-debug.h:78
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
SCLogOPBuffer_
Structure to be used when log_level override support would be provided by the logging module.
Definition: util-debug.h:108
SCLogOPIfaceCtx_::fp_mutex
SCMutex fp_mutex
Definition: util-debug.h:141
SC_LOG_ENV_LOG_OP_IFACE
#define SC_LOG_ENV_LOG_OP_IFACE
Definition: util-debug.h:39
ConfGetNode
ConfNode * ConfGetNode(const char *name)
Get a ConfNode by name.
Definition: conf.c:175
threads.h
SCLogConfig_::op_filter
char * op_filter
Definition: util-debug.h:177
util-syslog.h
SC_LOG_ENV_LOG_FACILITY
#define SC_LOG_ENV_LOG_FACILITY
Definition: util-debug.h:41
SCLogDeInitLogModule
void SCLogDeInitLogModule(void)
De-Initializes the logging module.
Definition: util-debug.c:1510
packet-queue.h
LOG_DEBUG
#define LOG_DEBUG
Definition: win32-syslog.h:46
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:253
sc_log_module_initialized
int sc_log_module_initialized
Used to indicate whether the logging module has been init or not.
Definition: util-debug.c:100
SC_LOG_NOTICE
@ SC_LOG_NOTICE
Definition: util-debug.h:58
SCMutexLock
#define SCMutexLock(mut)
Definition: threads-debug.h:117
SC_LOG_DEF_LOG_OP_IFACE
#define SC_LOG_DEF_LOG_OP_IFACE
Definition: util-debug.h:95
rust.h
SCLogOPIfaceCtx_::log_format
const char * log_format
Definition: util-debug.h:138
SCLogInitData_
Structure containing init data, that would be passed to SCInitDebugModule()
Definition: util-debug.h:150
JSON_ESCAPE_SLASH
#define JSON_ESCAPE_SLASH
Definition: suricata-common.h:258
SC_LOG_FMT_LOG_LEVEL
#define SC_LOG_FMT_LOG_LEVEL
Definition: util-debug.h:193
SCLogOPType
SCLogOPType
Definition: util-debug.h:76
MAX
#define MAX(x, y)
Definition: suricata-common.h:372
SCErrorToString
const char * SCErrorToString(SCError err)
Maps the error code, to its string equivalent.
Definition: util-error.c:40
SCLogMatchFDFilter
int SCLogMatchFDFilter(const char *function)
Checks if there is a match for the incoming log_message with any of the FD filters.
Definition: util-debug-filters.c:476
util-unittest.h
SC_LOG_LEVEL_MAX
@ SC_LOG_LEVEL_MAX
Definition: util-debug.h:63
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression to true.
Definition: util-unittest.h:82
SCLog
void SCLog(int x, const char *file, const char *func, const int line, const char *fmt,...)
Definition: util-debug.c:612
closelog
#define closelog()
Definition: win32-syslog.h:75
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
SCLogReleaseFGFilters
void SCLogReleaseFGFilters(void)
Definition: util-debug-filters.c:356
SCLogOPIfaceCtx_
The output interface context for the logging module.
Definition: util-debug.h:117
OutputRegisterFileRotationFlag
void OutputRegisterFileRotationFlag(int *flag)
Register a flag for file rotation notification.
Definition: output.c:830
ConfGet
int ConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition: conf.c:330
SC_LOG_INFO
@ SC_LOG_INFO
Definition: util-debug.h:59
SC_LOG_ERROR
@ SC_LOG_ERROR
Definition: util-debug.h:56
SC_LOG_ENV_LOG_LEVEL
#define SC_LOG_ENV_LOG_LEVEL
ENV vars that can be used to set the properties for the logging module.
Definition: util-debug.h:38
decode.h
util-debug.h
type
uint8_t type
Definition: decode-icmpv4.h:0
SCLogReleaseFDFilters
void SCLogReleaseFDFilters(void)
Releases all the FD filters added to the logging module.
Definition: util-debug-filters.c:722
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
util-error.h
SCLogPrintFGFilters
int SCLogPrintFGFilters()
Prints the FG filters(both WL and BL). Used for debugging purposes.
Definition: util-debug-filters.c:408
SCLogConfig_::op_filter_regex
pcre2_code * op_filter_regex
Definition: util-debug.h:179
SCLogOPIfaceCtx_::use_color
int16_t use_color
Definition: util-debug.h:120
SCSyslogGetFacilityMap
SCEnumCharMap * SCSyslogGetFacilityMap(void)
returns the syslog facility enum map
Definition: util-syslog.c:57
SCMutexUnlock
#define SCMutexUnlock(mut)
Definition: threads-debug.h:119
SCLogInitOPIfaceCtx
SCLogOPIfaceCtx * SCLogInitOPIfaceCtx(const char *iface_name, const char *log_format, int log_level, const char *arg)
Creates a new output interface based on the arguments sent. The kind of output interface to be create...
Definition: util-debug.c:1256
SCLogRegisterTests
void SCLogRegisterTests()
Definition: util-debug.c:1713
SCLogConfig_::op_ifaces_cnt
uint8_t op_ifaces_cnt
Definition: util-debug.h:185
LOG_NOTICE
#define LOG_NOTICE
Definition: win32-syslog.h:44
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
SCLogConfig_::log_level
SCLogLevel log_level
Definition: util-debug.h:174
SC_LOG_OP_IFACE_MAX
@ SC_LOG_OP_IFACE_MAX
Definition: util-debug.h:73
SCLogOPIfaceCtx_::iface
SCLogOPIface iface
Definition: util-debug.h:118
SC_ERR_INVALID_ARGUMENT
@ SC_ERR_INVALID_ARGUMENT
Definition: util-error.h:43
GetProgramVersion
const char * GetProgramVersion(void)
get string with program version
Definition: suricata.c:1042
TRUE
#define TRUE
Definition: suricata-common.h:33
SCLogOPBuffer_::log_format
const char * log_format
Definition: util-debug.h:111
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:277
SCLogOPIfaceCtx_::file
const char * file
Definition: util-debug.h:124
SC_LOG_ENV_LOG_FILE
#define SC_LOG_ENV_LOG_FILE
Definition: util-debug.h:40
SC_ERR_FOPEN
@ SC_ERR_FOPEN
Definition: util-error.h:74
SC_ERR_SPRINTF
@ SC_ERR_SPRINTF
Definition: util-error.h:42
SCLocalTime
struct tm * SCLocalTime(time_t timep, struct tm *result)
Definition: util-time.c:270
SCLogMatchFGFilterWL
int SCLogMatchFGFilterWL(const char *file, const char *function, int line)
Checks if there is a match for the incoming log_message with any of the FG filters....
Definition: util-debug-filters.c:291
sc_log_module_cleaned
int sc_log_module_cleaned
Used to indicate whether the logging module has been cleaned or not.
Definition: util-debug.c:105
conf.h
SCLogConfig_::startup_message
char * startup_message
Definition: util-debug.h:173
SCLogOPBuffer_::msg
char msg[SC_LOG_MAX_LOG_MSG_LEN]
Definition: util-debug.h:109
SCLogInitData_::global_log_level
SCLogLevel global_log_level
Definition: util-debug.h:155
SC_OK
@ SC_OK
Definition: util-error.h:30
SC_LOG_DEF_LOG_FILE
#define SC_LOG_DEF_LOG_FILE
Definition: util-debug.h:98
SC_LOG_OP_IFACE_FILE
@ SC_LOG_OP_IFACE_FILE
Definition: util-debug.h:71
LOG_ALERT
#define LOG_ALERT
Definition: win32-syslog.h:40
setenv
void setenv(const char *name, const char *value, int overwrite)
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:217
SCLogMessage
SCError SCLogMessage(const SCLogLevel log_level, const char *file, const unsigned int line, const char *function, const SCError error_code, const char *message)
Adds the global log_format to the outgoing buffer.
Definition: util-debug.c:535
SCLogLevel
SCLogLevel
The various log levels NOTE: when adding new level, don't forget to update SCLogMapLogLevelToSyslogLe...
Definition: util-debug.h:50
SCMutexInit
#define SCMutexInit(mut, mutattrs)
Definition: threads-debug.h:116
LOG_EMERG
#define LOG_EMERG
Definition: win32-syslog.h:39
SC_LOG_WARNING
@ SC_LOG_WARNING
Definition: util-debug.h:57
SCLogInitData_::op_filter
const char * op_filter
Definition: util-debug.h:161
SC_LOG_MAX_LOG_FORMAT_LEN
#define SC_LOG_MAX_LOG_FORMAT_LEN
Definition: util-debug.h:89
SCGetThreadIdLong
#define SCGetThreadIdLong(...)
Definition: threads.h:257
sc_log_op_iface_map
SCEnumCharMap sc_log_op_iface_map[]
Definition: util-debug.c:68
SC_LOG_ALERT
@ SC_LOG_ALERT
Definition: util-debug.h:54
ConfNodeLookupChild
ConfNode * ConfNodeLookupChild(const ConfNode *node, const char *name)
Lookup a child configuration node by name.
Definition: conf.c:814
tm-queuehandlers.h
SC_LOG_CRITICAL
@ SC_LOG_CRITICAL
Definition: util-debug.h:55
SCMapEnumValueToName
const char * SCMapEnumValueToName(int enum_value, SCEnumCharMap *table)
Maps an enum value to a string name, from the supplied table.
Definition: util-enum.c:68
SCLogPrintFDFilters
int SCLogPrintFDFilters(void)
Prints the FG filters(both WL and BL). Used for debugging purposes.
Definition: util-debug-filters.c:811
SCMapEnumNameToValue
int SCMapEnumNameToValue(const char *enum_name, SCEnumCharMap *table)
Maps a string name to an enum value from the supplied table. Please specify the last element of any m...
Definition: util-enum.c:40
suricata-common.h
tm-queues.h
SC_LOG_DEF_LOG_LEVEL
#define SC_LOG_DEF_LOG_LEVEL
Definition: util-debug.h:92
SCEnumCharMap_
Definition: util-enum.h:27
SC_LOG_ENV_LOG_OP_FILTER
#define SC_LOG_ENV_LOG_OP_FILTER
Definition: util-debug.h:43
SCLogConfig_::log_format
char * log_format
Definition: util-debug.h:175
ConfNode_::name
char * name
Definition: conf.h:33
SCLogOPIfaceCtx_::next
struct SCLogOPIfaceCtx_ * next
Definition: util-debug.h:143
SCError
SCError
Definition: util-error.h:29
SC_LOG_ENV_LOG_FORMAT
#define SC_LOG_ENV_LOG_FORMAT
Definition: util-debug.h:42
PathIsAbsolute
int PathIsAbsolute(const char *path)
Check if a path is absolute.
Definition: util-path.c:45
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
SC_LOG_PERF
@ SC_LOG_PERF
Definition: util-debug.h:60
SCLogConfig_
Holds the config state used by the logging api.
Definition: util-debug.h:172
SCLogInitData_::op_ifaces_cnt
uint8_t op_ifaces_cnt
Definition: util-debug.h:166
SCLogOPIfaceCtx_::rotation_flag
int rotation_flag
Definition: util-debug.h:129
SC_LOG_DEF_LOG_FORMAT_DEV
#define SC_LOG_DEF_LOG_FORMAT_DEV
Definition: util-debug.h:83
sc_log_fd_filters_present
int sc_log_fd_filters_present
Definition: util-debug-filters.c:36
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
FatalError
#define FatalError(x,...)
Definition: util-debug.h:532
LOG_WARNING
#define LOG_WARNING
Definition: win32-syslog.h:43
SCLogErr
void SCLogErr(int x, const char *file, const char *func, const int line, const int err, const char *fmt,...)
Definition: util-debug.c:631
SC_LOG_OP_IFACE_SYSLOG
@ SC_LOG_OP_IFACE_SYSLOG
Definition: util-debug.h:72
SCLogAllocLogInitData
SCLogInitData * SCLogAllocLogInitData(void)
Returns a pointer to a new SCLogInitData. This is a public interface intended to be used after the lo...
Definition: util-debug.c:1148
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:29
threadvars.h
LOG_CRIT
#define LOG_CRIT
Definition: win32-syslog.h:41
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
str
#define str(s)
Definition: suricata-common.h:268
ConfigGetLogDirectory
const char * ConfigGetLogDirectory()
Definition: util-conf.c:35
head
Flow * head
Definition: flow-hash.h:1
SCLogWarning
#define SCLogWarning(err_code,...)
Macro used to log WARNING messages.
Definition: util-debug.h:244
SCFree
#define SCFree(p)
Definition: util-mem.h:61
ConfNode_
Definition: conf.h:32
SC_LOG_MAX_LOG_MSG_LEN
#define SC_LOG_MAX_LOG_MSG_LEN
Definition: util-debug.h:86
SC_ERR_FATAL
@ SC_ERR_FATAL
Definition: util-error.h:203
SCLogOPBuffer_::temp
char * temp
Definition: util-debug.h:110
SC_LOG_FMT_FUNCTION
#define SC_LOG_FMT_FUNCTION
Definition: util-debug.h:196
SC_LOG_FMT_PID
#define SC_LOG_FMT_PID
Definition: util-debug.h:190
ConfValIsFalse
int ConfValIsFalse(const char *val)
Check if a value is false.
Definition: conf.c:590
SCLogRemoveFDFilter
int SCLogRemoveFDFilter(const char *function)
Removes a Function-Dependent(FD) filter.
Definition: util-debug-filters.c:751
SC_LOG_NONE
@ SC_LOG_NONE
Definition: util-debug.h:52
sc_log_global_log_level
SCLogLevel sc_log_global_log_level
Holds the global log level. Is the same as sc_log_config->log_level.
Definition: util-debug.c:95
SCLogAddFGFilterBL
int SCLogAddFGFilterBL(const char *file, const char *function, int line)
Adds a Blacklist(BL) fine-grained(FG) filter. A FG filter BL filter allows messages that don't match ...
Definition: util-debug-filters.c:351
SC_LOG_FMT_TID
#define SC_LOG_FMT_TID
Definition: util-debug.h:191
SCLogOPIfaceCtx_::file_d
FILE * file_d
Definition: util-debug.h:126
util-debug-filters.h
SCLogAppendOPIfaceCtx
void SCLogAppendOPIfaceCtx(SCLogOPIfaceCtx *iface_ctx, SCLogInitData *sc_lid)
Appends an output_interface to the output_interface list sent in head.
Definition: util-debug.c:1211
SC_LOG_FMT_TIME
#define SC_LOG_FMT_TIME
Definition: util-debug.h:189
SCLogInitData_::startup_message
const char * startup_message
Definition: util-debug.h:152
SCLogAddFDFilter
int SCLogAddFDFilter(const char *function)
Adds a Function-Dependent(FD) filter.
Definition: util-debug-filters.c:662
SCLogOPIfaceCtx_::type
int16_t type
Definition: util-debug.h:121
msg
const char * msg
Definition: app-layer-htp.c:539
openlog
#define openlog(__ident, __option, __facility)
Definition: win32-syslog.h:76
util-enum.h
SCMutexDestroy
#define SCMutexDestroy
Definition: threads-debug.h:120
SC_LOG_FMT_LINE
#define SC_LOG_FMT_LINE
Definition: util-debug.h:195
SCLogInitData_::op_ifaces
SCLogOPIfaceCtx * op_ifaces
Definition: util-debug.h:164
SCLogGetLogLevel
SCLogLevel SCLogGetLogLevel(void)
Definition: util-debug.c:968
SC_LOG_OP_IFACE_CONSOLE
@ SC_LOG_OP_IFACE_CONSOLE
Definition: util-debug.h:70
SCMutex
#define SCMutex
Definition: threads-debug.h:114
SCLogDebugEnabled
int SCLogDebugEnabled(void)
Returns whether debug messages are enabled to be logged or not.
Definition: util-debug.c:656
output.h
LOG_INFO
#define LOG_INFO
Definition: win32-syslog.h:45
SC_LOG_EMERGENCY
@ SC_LOG_EMERGENCY
Definition: util-debug.h:53
LOG_ERR
#define LOG_ERR
Definition: win32-syslog.h:42
ConfNodeLookupChildValue
const char * ConfNodeLookupChildValue(const ConfNode *node, const char *name)
Lookup the value of a child configuration node by name.
Definition: conf.c:842
SC_LOG_FMT_TM
#define SC_LOG_FMT_TM
Definition: util-debug.h:192