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 #define MAX_SUBSTRINGS 30
496  int ov[MAX_SUBSTRINGS];
497 
498  if (pcre_exec(sc_log_config->op_filter_regex,
499  sc_log_config->op_filter_regex_study,
500  buffer, strlen(buffer), 0, 0, ov, MAX_SUBSTRINGS) < 0)
501  {
502  return SC_ERR_LOG_FG_FILTER_MATCH; // bit hacky, but just return !0
503  }
504 #undef MAX_SUBSTRINGS
505  }
506 
507  return SC_OK;
508 }
509 
510 /** \internal
511  * \brief try to reopen file
512  * \note no error reporting here, as we're called by SCLogMessage
513  * \retval status 0 ok, -1 error */
514 static int SCLogReopen(SCLogOPIfaceCtx *op_iface_ctx)
515 {
516  if (op_iface_ctx->file == NULL) {
517  return 0;
518  }
519 
520  if (op_iface_ctx->file_d != NULL) {
521  fclose(op_iface_ctx->file_d);
522  }
523  op_iface_ctx->file_d = fopen(op_iface_ctx->file, "a");
524  if (op_iface_ctx->file_d == NULL) {
525  return -1;
526  }
527  return 0;
528 }
529 
530 /**
531  * \brief Adds the global log_format to the outgoing buffer
532  *
533  * \param log_level log_level of the message that has to be logged
534  * \param msg Buffer containing the outgoing message
535  * \param file File_name from where the message originated
536  * \param function Function_name from where the message originated
537  * \param line Line_no from where the messaged originated
538  *
539  * \retval SC_OK on success; else an error code
540  */
541 SCError SCLogMessage(const SCLogLevel log_level, const char *file,
542  const unsigned int line, const char *function,
543  const SCError error_code, const char *message)
544 {
545  char buffer[SC_LOG_MAX_LOG_MSG_LEN] = "";
546  SCLogOPIfaceCtx *op_iface_ctx = NULL;
547 
548  if (sc_log_module_initialized != 1) {
549  printf("Logging module not initialized. Call SCLogInitLogModule() "
550  "first before using the debug API\n");
551  return SC_OK;
552  }
553 
554  /* get ts here so we log the same ts to each output */
555  struct timeval tval;
556  gettimeofday(&tval, NULL);
557 
558  op_iface_ctx = sc_log_config->op_ifaces;
559  while (op_iface_ctx != NULL) {
560  if (log_level != SC_LOG_NOTSET && log_level > op_iface_ctx->log_level) {
561  op_iface_ctx = op_iface_ctx->next;
562  continue;
563  }
564 
565  switch (op_iface_ctx->iface) {
567  if (SCLogMessageGetBuffer(&tval, op_iface_ctx->use_color, op_iface_ctx->type,
568  buffer, sizeof(buffer),
569  op_iface_ctx->log_format ?
570  op_iface_ctx->log_format : sc_log_config->log_format,
571  log_level, file, line, function,
572  error_code, message) == 0)
573  {
574  SCLogPrintToStream((log_level == SC_LOG_ERROR)? stderr: stdout, buffer);
575  }
576  break;
578  if (SCLogMessageGetBuffer(&tval, 0, op_iface_ctx->type, buffer, sizeof(buffer),
579  op_iface_ctx->log_format ?
580  op_iface_ctx->log_format : sc_log_config->log_format,
581  log_level, file, line, function,
582  error_code, message) == 0)
583  {
584  int r = 0;
585  SCMutexLock(&op_iface_ctx->fp_mutex);
586  if (op_iface_ctx->rotation_flag) {
587  r = SCLogReopen(op_iface_ctx);
588  op_iface_ctx->rotation_flag = 0;
589  }
590  SCLogPrintToStream(op_iface_ctx->file_d, buffer);
591  SCMutexUnlock(&op_iface_ctx->fp_mutex);
592 
593  /* report error outside of lock to avoid recursion */
594  if (r == -1) {
595  SCLogError(SC_ERR_FOPEN, "re-opening file \"%s\" failed: %s",
596  op_iface_ctx->file, strerror(errno));
597  }
598  }
599  break;
601  if (SCLogMessageGetBuffer(&tval, 0, op_iface_ctx->type, buffer, sizeof(buffer),
602  op_iface_ctx->log_format ?
603  op_iface_ctx->log_format : sc_log_config->log_format,
604  log_level, file, line, function,
605  error_code, message) == 0)
606  {
607  SCLogPrintToSyslog(SCLogMapLogLevelToSyslogLevel(log_level), buffer);
608  }
609  break;
610  default:
611  break;
612  }
613  op_iface_ctx = op_iface_ctx->next;
614  }
615  return SC_OK;
616 }
617 
618 void SCLog(int x, const char *file, const char *func, const int line,
619  const char *fmt, ...)
620 {
621  if (sc_log_global_log_level >= x &&
623  SCLogMatchFGFilterWL(file, func, line) == 1 ||
624  SCLogMatchFGFilterBL(file, func, line) == 1) &&
626  SCLogMatchFDFilter(func) == 1))
627  {
629  va_list ap;
630  va_start(ap, fmt);
631  vsnprintf(msg, sizeof(msg), fmt, ap);
632  va_end(ap);
633  SCLogMessage(x, file, line, func, SC_OK, msg);
634  }
635 }
636 
637 void SCLogErr(int x, const char *file, const char *func, const int line,
638  const int err, const char *fmt, ...)
639 {
640  if (sc_log_global_log_level >= x &&
642  SCLogMatchFGFilterWL(file, func, line) == 1 ||
643  SCLogMatchFGFilterBL(file, func, line) == 1) &&
645  SCLogMatchFDFilter(func) == 1))
646  {
648  va_list ap;
649  va_start(ap, fmt);
650  vsnprintf(msg, sizeof(msg), fmt, ap);
651  va_end(ap);
652  SCLogMessage(x, file, line, func, err, msg);
653  }
654 }
655 
656 /**
657  * \brief Returns whether debug messages are enabled to be logged or not
658  *
659  * \retval 1 if debug messages are enabled to be logged
660  * \retval 0 if debug messages are not enabled to be logged
661  */
663 {
664 #ifdef DEBUG
666  return 1;
667  else
668  return 0;
669 #else
670  return 0;
671 #endif
672 }
673 
674 /**
675  * \brief Allocates an output buffer for an output interface. Used when we
676  * want the op_interface log_format to override the global_log_format.
677  * Currently not used.
678  *
679  * \retval buffer Pointer to the newly created output_buffer
680  */
682 {
683  SCLogOPBuffer *buffer = NULL;
684  SCLogOPIfaceCtx *op_iface_ctx = NULL;
685  int i = 0;
686 
687  if ( (buffer = SCMalloc(sc_log_config->op_ifaces_cnt *
688  sizeof(SCLogOPBuffer))) == NULL) {
689  SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogAllocLogOPBuffer. Exiting...");
690  exit(EXIT_FAILURE);
691  }
692 
693  op_iface_ctx = sc_log_config->op_ifaces;
694  for (i = 0;
695  i < sc_log_config->op_ifaces_cnt;
696  i++, op_iface_ctx = op_iface_ctx->next) {
697  buffer[i].log_format = op_iface_ctx->log_format;
698  buffer[i].temp = buffer[i].msg;
699  }
700 
701  return buffer;
702 }
703 
704 /*----------------------The logging module initialization code--------------- */
705 
706 /**
707  * \brief Returns a new output_interface_context
708  *
709  * \retval iface_ctx Pointer to a newly allocated output_interface_context
710  * \initonly
711  */
712 static inline SCLogOPIfaceCtx *SCLogAllocLogOPIfaceCtx(void)
713 {
714  SCLogOPIfaceCtx *iface_ctx = NULL;
715 
716  if ( (iface_ctx = SCMalloc(sizeof(SCLogOPIfaceCtx))) == NULL) {
717  SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogallocLogOPIfaceCtx. Exiting...");
718  exit(EXIT_FAILURE);
719  }
720  memset(iface_ctx, 0, sizeof(SCLogOPIfaceCtx));
721 
722  return iface_ctx;
723 }
724 
725 /**
726  * \brief Initializes the file output interface
727  *
728  * \param file Path to the file used for logging purposes
729  * \param log_format Pointer to the log_format for this op interface, that
730  * overrides the global_log_format
731  * \param log_level Override of the global_log_level by this interface
732  *
733  * \retval iface_ctx Pointer to the file output interface context created
734  * \initonly
735  */
736 static inline SCLogOPIfaceCtx *SCLogInitFileOPIface(const char *file,
737  const char *log_format,
738  int log_level,
740 {
741  SCLogOPIfaceCtx *iface_ctx = SCLogAllocLogOPIfaceCtx();
742 
743  if (iface_ctx == NULL) {
744  SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogInitFileOPIface. Exiting...");
745  exit(EXIT_FAILURE);
746  }
747 
748  if (file == NULL) {
749  goto error;
750  }
751 
752  iface_ctx->iface = SC_LOG_OP_IFACE_FILE;
753  iface_ctx->type = type;
754 
755  if ( (iface_ctx->file_d = fopen(file, "a")) == NULL) {
756  printf("Error opening file %s\n", file);
757  goto error;
758  }
759 
760  if ((iface_ctx->file = SCStrdup(file)) == NULL) {
761  goto error;
762  }
763 
764  if (log_format != NULL && (iface_ctx->log_format = SCStrdup(log_format)) == NULL) {
765  goto error;
766  }
767 
768  SCMutexInit(&iface_ctx->fp_mutex, NULL);
770 
771  iface_ctx->log_level = log_level;
772 
773  return iface_ctx;
774 
775 error:
776  if (iface_ctx->file != NULL) {
777  SCFree((char *)iface_ctx->file);
778  iface_ctx->file = NULL;
779  }
780  if (iface_ctx->log_format != NULL) {
781  SCFree((char *)iface_ctx->log_format);
782  iface_ctx->log_format = NULL;
783  }
784  if (iface_ctx->file_d != NULL) {
785  fclose(iface_ctx->file_d);
786  iface_ctx->file_d = NULL;
787  }
788  SCFree(iface_ctx);
789  return NULL;
790 }
791 
792 /**
793  * \brief Initializes the console output interface and deals with possible
794  * env var overrides.
795  *
796  * \param log_format Pointer to the log_format for this op interface, that
797  * overrides the global_log_format
798  * \param log_level Override of the global_log_level by this interface
799  *
800  * \retval iface_ctx Pointer to the console output interface context created
801  * \initonly
802  */
803 static inline SCLogOPIfaceCtx *SCLogInitConsoleOPIface(const char *log_format,
804  SCLogLevel log_level, SCLogOPType type)
805 {
806  SCLogOPIfaceCtx *iface_ctx = SCLogAllocLogOPIfaceCtx();
807 
808  if (iface_ctx == NULL) {
809  SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogInitConsoleOPIface. Exiting...");
810  exit(EXIT_FAILURE);
811  }
812 
813  iface_ctx->iface = SC_LOG_OP_IFACE_CONSOLE;
814  iface_ctx->type = type;
815 
816  /* console log format is overridden by envvars */
817  const char *tmp_log_format = log_format;
818  const char *s = getenv(SC_LOG_ENV_LOG_FORMAT);
819  if (s != NULL) {
820 #if 0
821  printf("Overriding setting for \"console.format\" because of env "
822  "var SC_LOG_FORMAT=\"%s\".\n", s);
823 #endif
824  tmp_log_format = s;
825  }
826 
827  if (tmp_log_format != NULL &&
828  (iface_ctx->log_format = SCStrdup(tmp_log_format)) == NULL) {
829  printf("Error allocating memory\n");
830  exit(EXIT_FAILURE);
831  }
832 
833  /* console log level is overridden by envvars */
834  SCLogLevel tmp_log_level = log_level;
835  s = getenv(SC_LOG_ENV_LOG_LEVEL);
836  if (s != NULL) {
838  if (l > SC_LOG_NOTSET && l < SC_LOG_LEVEL_MAX) {
839 #if 0
840  printf("Overriding setting for \"console.level\" because of env "
841  "var SC_LOG_LEVEL=\"%s\".\n", s);
842 #endif
843  tmp_log_level = l;
844  }
845  }
846  iface_ctx->log_level = tmp_log_level;
847 
848 #ifndef OS_WIN32
849  if (isatty(fileno(stdout)) && isatty(fileno(stderr))) {
850  iface_ctx->use_color = TRUE;
851  }
852 #endif
853 
854  return iface_ctx;
855 }
856 
857 /**
858  * \brief Initializes the syslog output interface
859  *
860  * \param facility The facility code for syslog
861  * \param log_format Pointer to the log_format for this op interface, that
862  * overrides the global_log_format
863  * \param log_level Override of the global_log_level by this interface
864  *
865  * \retval iface_ctx Pointer to the syslog output interface context created
866  */
867 static inline SCLogOPIfaceCtx *SCLogInitSyslogOPIface(int facility,
868  const char *log_format,
869  SCLogLevel log_level,
871 {
872  SCLogOPIfaceCtx *iface_ctx = SCLogAllocLogOPIfaceCtx();
873 
874  if ( iface_ctx == NULL) {
875  SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogInitSyslogOPIface. Exiting...");
876  exit(EXIT_FAILURE);
877  }
878 
879  iface_ctx->iface = SC_LOG_OP_IFACE_SYSLOG;
880  iface_ctx->type = type;
881 
882  if (facility == -1)
883  facility = SC_LOG_DEF_SYSLOG_FACILITY;
884  iface_ctx->facility = facility;
885 
886  if (log_format != NULL &&
887  (iface_ctx->log_format = SCStrdup(log_format)) == NULL) {
888  printf("Error allocating memory\n");
889  exit(EXIT_FAILURE);
890  }
891 
892  iface_ctx->log_level = log_level;
893 
894  openlog(NULL, LOG_NDELAY, iface_ctx->facility);
895 
896  return iface_ctx;
897 }
898 
899 /**
900  * \brief Frees the output_interface context supplied as an argument
901  *
902  * \param iface_ctx Pointer to the op_interface_context to be freed
903  */
904 static inline void SCLogFreeLogOPIfaceCtx(SCLogOPIfaceCtx *iface_ctx)
905 {
906  SCLogOPIfaceCtx *temp = NULL;
907 
908  while (iface_ctx != NULL) {
909  temp = iface_ctx;
910 
911  if (iface_ctx->file_d != NULL) {
912  fclose(iface_ctx->file_d);
913  SCMutexDestroy(&iface_ctx->fp_mutex);
914  }
915 
916  if (iface_ctx->file != NULL)
917  SCFree((void *)iface_ctx->file);
918 
919  if (iface_ctx->log_format != NULL)
920  SCFree((void *)iface_ctx->log_format);
921 
922  if (iface_ctx->iface == SC_LOG_OP_IFACE_SYSLOG) {
923  closelog();
924  }
925 
926  iface_ctx = iface_ctx->next;
927 
928  SCFree(temp);
929  }
930 
931  return;
932 }
933 
934 /**
935  * \brief Internal function used to set the logging module global_log_level
936  * during the initialization phase
937  *
938  * \param sc_lid The initialization data supplied.
939  * \param sc_lc The logging module context which has to be updated.
940  */
941 static inline void SCLogSetLogLevel(SCLogInitData *sc_lid, SCLogConfig *sc_lc)
942 {
943  SCLogLevel log_level = SC_LOG_NOTSET;
944  const char *s = NULL;
945 
946  /* envvar overrides config */
947  s = getenv(SC_LOG_ENV_LOG_LEVEL);
948  if (s != NULL) {
949  log_level = SCMapEnumNameToValue(s, sc_log_level_map);
950  } else if (sc_lid != NULL) {
951  log_level = sc_lid->global_log_level;
952  }
953 
954  /* deal with the global_log_level to be used */
955  if (log_level > SC_LOG_NOTSET && log_level < SC_LOG_LEVEL_MAX)
956  sc_lc->log_level = log_level;
957  else {
959 #ifndef UNITTESTS
960  if (sc_lid != NULL) {
961  printf("Warning: Invalid/No global_log_level assigned by user. Falling "
962  "back on the default_log_level \"%s\"\n",
964  }
965 #endif
966  }
967 
968  /* we also set it to a global var, as it is easier to access it */
970 
971  return;
972 }
973 
974 static inline const char *SCLogGetDefaultLogFormat(void)
975 {
976  const char *prog_ver = GetProgramVersion();
977  if (strstr(prog_ver, "RELEASE") != NULL) {
979  }
981 }
982 
983 /**
984  * \brief Internal function used to set the logging module global_log_format
985  * during the initialization phase
986  *
987  * \param sc_lid The initialization data supplied.
988  * \param sc_lc The logging module context which has to be updated.
989  */
990 static inline void SCLogSetLogFormat(SCLogInitData *sc_lid, SCLogConfig *sc_lc)
991 {
992  const char *format = NULL;
993 
994  /* envvar overrides config */
995  format = getenv(SC_LOG_ENV_LOG_FORMAT);
996  if (format == NULL) {
997  if (sc_lid != NULL) {
998  format = sc_lid->global_log_format;
999  }
1000  }
1001 
1002  /* deal with the global log format to be used */
1003  if (format == NULL || strlen(format) > SC_LOG_MAX_LOG_FORMAT_LEN) {
1004  format = SCLogGetDefaultLogFormat();
1005 #ifndef UNITTESTS
1006  if (sc_lid != NULL) {
1007  printf("Warning: Invalid/No global_log_format supplied by user or format "
1008  "length exceeded limit of \"%d\" characters. Falling back on "
1009  "default log_format \"%s\"\n", SC_LOG_MAX_LOG_FORMAT_LEN,
1010  format);
1011  }
1012 #endif
1013  }
1014 
1015  if (format != NULL && (sc_lc->log_format = SCStrdup(format)) == NULL) {
1016  printf("Error allocating memory\n");
1017  exit(EXIT_FAILURE);
1018  }
1019 
1020  return;
1021 }
1022 
1023 /**
1024  * \brief Internal function used to set the logging module global_op_ifaces
1025  * during the initialization phase
1026  *
1027  * \param sc_lid The initialization data supplied.
1028  * \param sc_lc The logging module context which has to be updated.
1029  */
1030 static inline void SCLogSetOPIface(SCLogInitData *sc_lid, SCLogConfig *sc_lc)
1031 {
1032  SCLogOPIfaceCtx *op_ifaces_ctx = NULL;
1033  int op_iface = 0;
1034  const char *s = NULL;
1035 
1036  if (sc_lid != NULL && sc_lid->op_ifaces != NULL) {
1037  sc_lc->op_ifaces = sc_lid->op_ifaces;
1038  sc_lid->op_ifaces = NULL;
1039  sc_lc->op_ifaces_cnt = sc_lid->op_ifaces_cnt;
1040  } else {
1041  s = getenv(SC_LOG_ENV_LOG_OP_IFACE);
1042  if (s != NULL) {
1044 
1045  if(op_iface < 0 || op_iface >= SC_LOG_OP_IFACE_MAX) {
1046  op_iface = SC_LOG_DEF_LOG_OP_IFACE;
1047 #ifndef UNITTESTS
1048  printf("Warning: Invalid output interface supplied by user. "
1049  "Falling back on default_output_interface \"%s\"\n",
1051 #endif
1052  }
1053  }
1054  else {
1055  op_iface = SC_LOG_DEF_LOG_OP_IFACE;
1056 #ifndef UNITTESTS
1057  if (sc_lid != NULL) {
1058  printf("Warning: Output_interface not supplied by user. Falling "
1059  "back on default_output_interface \"%s\"\n",
1061  }
1062 #endif
1063  }
1064 
1065  switch (op_iface) {
1067  op_ifaces_ctx = SCLogInitConsoleOPIface(NULL, SC_LOG_LEVEL_MAX,0);
1068  break;
1069  case SC_LOG_OP_IFACE_FILE:
1070  s = getenv(SC_LOG_ENV_LOG_FILE);
1071  if (s == NULL) {
1072  char *str = SCLogGetLogFilename(SC_LOG_DEF_LOG_FILE);
1073  if (str != NULL) {
1074  op_ifaces_ctx = SCLogInitFileOPIface(str, NULL, SC_LOG_LEVEL_MAX,0);
1075  SCFree(str);
1076  }
1077  } else {
1078  op_ifaces_ctx = SCLogInitFileOPIface(s, NULL, SC_LOG_LEVEL_MAX,0);
1079  }
1080  break;
1082  s = getenv(SC_LOG_ENV_LOG_FACILITY);
1083  if (s == NULL)
1085 
1086  op_ifaces_ctx = SCLogInitSyslogOPIface(SCMapEnumNameToValue(s, SCSyslogGetFacilityMap()), NULL, -1,0);
1087  break;
1088  }
1089  sc_lc->op_ifaces = op_ifaces_ctx;
1090  sc_lc->op_ifaces_cnt++;
1091  }
1092  return;
1093 }
1094 
1095 /**
1096  * \brief Internal function used to set the logging module op_filter
1097  * during the initialization phase
1098  *
1099  * \param sc_lid The initialization data supplied.
1100  * \param sc_lc The logging module context which has to be updated.
1101  */
1102 static inline void SCLogSetOPFilter(SCLogInitData *sc_lid, SCLogConfig *sc_lc)
1103 {
1104  const char *filter = NULL;
1105 
1106  int opts = 0;
1107  const char *ep;
1108  int eo = 0;
1109 
1110  /* envvar overrides */
1111  filter = getenv(SC_LOG_ENV_LOG_OP_FILTER);
1112  if (filter == NULL) {
1113  if (sc_lid != NULL) {
1114  filter = sc_lid->op_filter;
1115  }
1116  }
1117 
1118  if (filter != NULL && strcmp(filter, "") != 0) {
1119  sc_lc->op_filter = SCStrdup(filter);
1120  if (sc_lc->op_filter == NULL) {
1121  printf("pcre filter alloc failed\n");
1122  return;
1123  }
1124  sc_lc->op_filter_regex = pcre_compile(filter, opts, &ep, &eo, NULL);
1125  if (sc_lc->op_filter_regex == NULL) {
1126  SCFree(sc_lc->op_filter);
1127  printf("pcre compile of \"%s\" failed at offset %d : %s\n", filter,
1128  eo, ep);
1129  return;
1130  }
1131 
1132  sc_lc->op_filter_regex_study = pcre_study(sc_lc->op_filter_regex, 0,
1133  &ep);
1134  if (ep != NULL) {
1135  printf("pcre study failed: %s\n", ep);
1136  return;
1137  }
1138  }
1139 
1140  return;
1141 }
1142 
1143 /**
1144  * \brief Returns a pointer to a new SCLogInitData. This is a public interface
1145  * intended to be used after the logging paramters are read from the
1146  * conf file
1147  *
1148  * \retval sc_lid Pointer to the newly created SCLogInitData
1149  * \initonly
1150  */
1152 {
1153  SCLogInitData *sc_lid = NULL;
1154 
1155  /* not using SCMalloc here because if it fails we can't log */
1156  if ( (sc_lid = SCMalloc(sizeof(SCLogInitData))) == NULL)
1157  return NULL;
1158 
1159  memset(sc_lid, 0, sizeof(SCLogInitData));
1160 
1161  return sc_lid;
1162 }
1163 
1164 #ifdef UNITTESTS
1165 #ifndef OS_WIN32
1166 /**
1167  * \brief Frees a SCLogInitData
1168  *
1169  * \param sc_lid Pointer to the SCLogInitData to be freed
1170  */
1171 static void SCLogFreeLogInitData(SCLogInitData *sc_lid)
1172 {
1173  if (sc_lid != NULL) {
1174  SCLogFreeLogOPIfaceCtx(sc_lid->op_ifaces);
1175  SCFree(sc_lid);
1176  }
1177 
1178  return;
1179 }
1180 #endif
1181 #endif
1182 
1183 /**
1184  * \brief Frees the logging module context
1185  */
1186 static inline void SCLogFreeLogConfig(SCLogConfig *sc_lc)
1187 {
1188  if (sc_lc != NULL) {
1189  if (sc_lc->startup_message != NULL)
1190  SCFree(sc_lc->startup_message);
1191  if (sc_lc->log_format != NULL)
1192  SCFree(sc_lc->log_format);
1193  if (sc_lc->op_filter != NULL)
1194  SCFree(sc_lc->op_filter);
1195 
1196  if (sc_lc->op_filter_regex != NULL)
1197  pcre_free(sc_lc->op_filter_regex);
1198  if (sc_lc->op_filter_regex_study)
1200 
1201  SCLogFreeLogOPIfaceCtx(sc_lc->op_ifaces);
1202  SCFree(sc_lc);
1203  }
1204 
1205  return;
1206 }
1207 
1208 /**
1209  * \brief Appends an output_interface to the output_interface list sent in head
1210  *
1211  * \param iface_ctx Pointer to the output_interface that has to be added to head
1212  * \param head Pointer to the output_interface list
1213  */
1215 {
1216  SCLogOPIfaceCtx *temp = NULL, *prev = NULL;
1217  SCLogOPIfaceCtx **head = &sc_lid->op_ifaces;
1218 
1219  if (iface_ctx == NULL) {
1220 #ifdef DEBUG
1221  printf("Argument(s) to SCLogAppendOPIfaceCtx() NULL\n");
1222 #endif
1223  return;
1224  }
1225 
1226  temp = *head;
1227  while (temp != NULL) {
1228  prev = temp;
1229  temp = temp->next;
1230  }
1231 
1232  if (prev == NULL)
1233  *head = iface_ctx;
1234  else
1235  prev->next = iface_ctx;
1236 
1237  sc_lid->op_ifaces_cnt++;
1238 
1239  return;
1240 }
1241 
1242 
1243 /**
1244  * \brief Creates a new output interface based on the arguments sent. The kind
1245  * of output interface to be created is decided by the iface_name arg.
1246  * If iface_name is "file", the arg argument will hold the filename to be
1247  * used for logging purposes. If iface_name is "syslog", the arg
1248  * argument holds the facility code. If iface_name is "console", arg is
1249  * NULL.
1250  *
1251  * \param iface_name Interface name. Can be "console", "file" or "syslog"
1252  * \param log_format Override for the global_log_format
1253  * \param log_level Override for the global_log_level
1254  * \param log_level Parameter required by a particular interface. Explained in
1255  * the function description
1256  *
1257  * \retval iface_ctx Pointer to the newly created output interface
1258  */
1259 SCLogOPIfaceCtx *SCLogInitOPIfaceCtx(const char *iface_name,
1260  const char *log_format,
1261  int log_level, const char *arg)
1262 {
1263  int iface = SCMapEnumNameToValue(iface_name, sc_log_op_iface_map);
1264 
1265  if (log_level < SC_LOG_NONE || log_level > SC_LOG_DEBUG) {
1266 #ifndef UNITTESTS
1267  printf("Warning: Supplied log_level_override for op_interface \"%s\" "
1268  "is invalid. Defaulting to not specifying an override\n",
1269  iface_name);
1270 #endif
1271  log_level = SC_LOG_NOTSET;
1272  }
1273 
1274  switch (iface) {
1276  return SCLogInitConsoleOPIface(log_format, log_level, SC_LOG_OP_TYPE_REGULAR);
1277  case SC_LOG_OP_IFACE_FILE:
1278  return SCLogInitFileOPIface(arg, log_format, log_level, SC_LOG_OP_TYPE_REGULAR);
1280  return SCLogInitSyslogOPIface(SCMapEnumNameToValue(arg, SCSyslogGetFacilityMap()),
1281  log_format, log_level, SC_LOG_OP_TYPE_REGULAR);
1282  default:
1283 #ifdef DEBUG
1284  printf("Output Interface \"%s\" not supported by the logging module",
1285  iface_name);
1286 #endif
1287  return NULL;
1288  }
1289 }
1290 
1291 /**
1292  * \brief Initializes the logging module.
1293  *
1294  * \param sc_lid The initialization data for the logging module. If sc_lid is
1295  * NULL, we would stick to the default configuration for the
1296  * logging subsystem.
1297  * \initonly
1298  */
1300 {
1301  /* De-initialize the logging context, if it has already init by the
1302  * environment variables at the start of the engine */
1304 
1305 #if defined (OS_WIN32)
1306  if (SCMutexInit(&sc_log_stream_lock, NULL) != 0) {
1307  SCLogError(SC_ERR_MUTEX, "Failed to initialize log mutex.");
1308  exit(EXIT_FAILURE);
1309  }
1310 #endif /* OS_WIN32 */
1311 
1312  /* sc_log_config is a global variable */
1313  if ( (sc_log_config = SCMalloc(sizeof(SCLogConfig))) == NULL) {
1314  SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogInitLogModule. Exiting...");
1315  exit(EXIT_FAILURE);
1316  }
1317  memset(sc_log_config, 0, sizeof(SCLogConfig));
1318 
1319  SCLogSetLogLevel(sc_lid, sc_log_config);
1320  SCLogSetLogFormat(sc_lid, sc_log_config);
1321  SCLogSetOPIface(sc_lid, sc_log_config);
1322  SCLogSetOPFilter(sc_lid, sc_log_config);
1323 
1326 
1327  //SCOutputPrint(sc_did->startup_message);
1328 
1329  rs_log_set_level(sc_log_global_log_level);
1330  return;
1331 }
1332 
1333 void SCLogLoadConfig(int daemon, int verbose)
1334 {
1335  ConfNode *outputs;
1336  SCLogInitData *sc_lid;
1337  int have_logging = 0;
1338  int max_level = 0;
1339  SCLogLevel min_level = 0;
1340 
1341  /* If verbose logging was requested, set the minimum as
1342  * SC_LOG_NOTICE plus the extra verbosity. */
1343  if (verbose) {
1344  min_level = SC_LOG_NOTICE + verbose;
1345  }
1346 
1347  outputs = ConfGetNode("logging.outputs");
1348  if (outputs == NULL) {
1349  SCLogDebug("No logging.output configuration section found.");
1350  return;
1351  }
1352 
1353  sc_lid = SCLogAllocLogInitData();
1354  if (sc_lid == NULL) {
1355  SCLogDebug("Could not allocate memory for log init data");
1356  return;
1357  }
1358 
1359  /* Get default log level and format. */
1360  const char *default_log_level_s = NULL;
1361  if (ConfGet("logging.default-log-level", &default_log_level_s) == 1) {
1362  SCLogLevel default_log_level =
1363  SCMapEnumNameToValue(default_log_level_s, sc_log_level_map);
1364  if (default_log_level == -1) {
1365  SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid default log level: %s",
1366  default_log_level_s);
1367  exit(EXIT_FAILURE);
1368  }
1369  sc_lid->global_log_level = MAX(min_level, default_log_level);
1370  }
1371  else {
1372  sc_lid->global_log_level = MAX(min_level, SC_LOG_NOTICE);
1373  }
1374 
1375  if (ConfGet("logging.default-log-format", &sc_lid->global_log_format) != 1)
1376  sc_lid->global_log_format = SCLogGetDefaultLogFormat();
1377 
1378  (void)ConfGet("logging.default-output-filter", &sc_lid->op_filter);
1379 
1380  ConfNode *seq_node, *output;
1381  TAILQ_FOREACH(seq_node, &outputs->head, next) {
1382  SCLogLevel level = sc_lid->global_log_level;
1383  SCLogOPIfaceCtx *op_iface_ctx = NULL;
1384  const char *format;
1385  const char *level_s;
1386 
1387  output = ConfNodeLookupChild(seq_node, seq_node->val);
1388  if (output == NULL)
1389  continue;
1390 
1391  /* By default an output is enabled. */
1392  const char *enabled = ConfNodeLookupChildValue(output, "enabled");
1393  if (enabled != NULL && ConfValIsFalse(enabled))
1394  continue;
1395 
1397  const char *type_s = ConfNodeLookupChildValue(output, "type");
1398  if (type_s != NULL) {
1399  if (strcmp(type_s, "regular") == 0)
1401  else if (strcmp(type_s, "json") == 0) {
1403  }
1404  }
1405 
1406  /* if available use the log format setting for this output,
1407  * otherwise fall back to the global setting. */
1408  format = ConfNodeLookupChildValue(output, "format");
1409  if (format == NULL)
1410  format = sc_lid->global_log_format;
1411 
1412  level_s = ConfNodeLookupChildValue(output, "level");
1413  if (level_s != NULL) {
1414  level = SCMapEnumNameToValue(level_s, sc_log_level_map);
1415  if (level == -1) {
1416  SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid log level: %s",
1417  level_s);
1418  exit(EXIT_FAILURE);
1419  }
1420  max_level = MAX(max_level, level);
1421  }
1422 
1423  /* Increase the level of extra verbosity was requested. */
1424  level = MAX(min_level, level);
1425 
1426  if (strcmp(output->name, "console") == 0) {
1427  op_iface_ctx = SCLogInitConsoleOPIface(format, level, type);
1428  }
1429  else if (strcmp(output->name, "file") == 0) {
1430  const char *filename = ConfNodeLookupChildValue(output, "filename");
1431  if (filename == NULL) {
1433  "Logging to file requires a filename");
1434  exit(EXIT_FAILURE);
1435  }
1436  char *path = NULL;
1437  if (!(PathIsAbsolute(filename))) {
1438  path = SCLogGetLogFilename(filename);
1439  } else {
1440  path = SCStrdup(filename);
1441  }
1442  if (path == NULL)
1443  FatalError(SC_ERR_FATAL, "failed to setup output to file");
1444  have_logging = 1;
1445  op_iface_ctx = SCLogInitFileOPIface(path, format, level, type);
1446  SCFree(path);
1447  }
1448  else if (strcmp(output->name, "syslog") == 0) {
1449  int facility = SC_LOG_DEF_SYSLOG_FACILITY;
1450  const char *facility_s = ConfNodeLookupChildValue(output,
1451  "facility");
1452  if (facility_s != NULL) {
1453  facility = SCMapEnumNameToValue(facility_s, SCSyslogGetFacilityMap());
1454  if (facility == -1) {
1455  SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid syslog "
1456  "facility: \"%s\", now using \"%s\" as syslog "
1457  "facility", facility_s, SC_LOG_DEF_SYSLOG_FACILITY_STR);
1458  facility = SC_LOG_DEF_SYSLOG_FACILITY;
1459  }
1460  }
1461  SCLogDebug("Initializing syslog logging with format \"%s\"", format);
1462  have_logging = 1;
1463  op_iface_ctx = SCLogInitSyslogOPIface(facility, format, level, type);
1464  }
1465  else {
1466  SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid logging method: %s, "
1467  "ignoring", output->name);
1468  }
1469  if (op_iface_ctx != NULL) {
1470  SCLogAppendOPIfaceCtx(op_iface_ctx, sc_lid);
1471  }
1472  }
1473 
1474  if (daemon && (have_logging == 0)) {
1476  "NO logging compatible with daemon mode selected,"
1477  " suricata won't be able to log. Please update "
1478  " 'logging.outputs' in the YAML.");
1479  }
1480 
1481  /* Set the global log level to that of the max level used. */
1482  sc_lid->global_log_level = MAX(sc_lid->global_log_level, max_level);
1483  SCLogInitLogModule(sc_lid);
1484 
1485  SCLogDebug("sc_log_global_log_level: %d", sc_log_global_log_level);
1486  SCLogDebug("sc_lc->log_format: %s", sc_log_config->log_format);
1487  SCLogDebug("SCLogSetOPFilter: filter: %s", sc_log_config->op_filter);
1488 
1489  if (sc_lid != NULL)
1490  SCFree(sc_lid);
1491 }
1492 
1493 /**
1494  * \brief Returns a full file path given a filename uses log dir specified in
1495  * conf or DEFAULT_LOG_DIR
1496  *
1497  * \param filearg The relative filename for which we want a full path include
1498  * log directory
1499  *
1500  * \retval log_filename The fullpath of the logfile to open
1501  */
1502 static char *SCLogGetLogFilename(const char *filearg)
1503 {
1504  const char *log_dir = ConfigGetLogDirectory();
1505  char *log_filename = SCMalloc(PATH_MAX);
1506  if (unlikely(log_filename == NULL))
1507  return NULL;
1508  snprintf(log_filename, PATH_MAX, "%s/%s", log_dir, filearg);
1509  return log_filename;
1510 }
1511 
1512 /**
1513  * \brief De-Initializes the logging module
1514  */
1516 {
1517  SCLogFreeLogConfig(sc_log_config);
1518 
1519  /* reset the global logging_module variables */
1523  sc_log_config = NULL;
1524 
1525  /* de-init the FD filters */
1527  /* de-init the FG filters */
1529 
1530 #if defined (OS_WIN32)
1531  SCMutexDestroy(&sc_log_stream_lock);
1532 #endif /* OS_WIN32 */
1533 
1534  return;
1535 }
1536 
1537 //------------------------------------Unit_Tests--------------------------------
1538 
1539 /* The logging engine should be tested to the maximum extent possible, since
1540  * logging code would be used throughout the codebase, and hence we can't afford
1541  * to have a single bug here(not that you can afford to have a bug
1542  * elsewhere ;) ). Please report a bug, if you get a slightest hint of a bug
1543  * from the logging module.
1544  */
1545 
1546 #ifdef UNITTESTS
1547 
1548 static int SCLogTestInit01(void)
1549 {
1550 #ifndef OS_WIN32
1551  /* unset any environment variables set for the logging module */
1555 
1556  SCLogInitLogModule(NULL);
1557 
1558  FAIL_IF_NULL(sc_log_config);
1559 
1560  FAIL_IF_NOT(SC_LOG_DEF_LOG_LEVEL == sc_log_config->log_level);
1561  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1562  SC_LOG_DEF_LOG_OP_IFACE == sc_log_config->op_ifaces->iface);
1563  FAIL_IF_NOT(sc_log_config->log_format != NULL &&
1564  strcmp(SCLogGetDefaultLogFormat(), sc_log_config->log_format) == 0);
1565 
1567 
1568  setenv(SC_LOG_ENV_LOG_LEVEL, "Debug", 1);
1569  setenv(SC_LOG_ENV_LOG_OP_IFACE, "Console", 1);
1570  setenv(SC_LOG_ENV_LOG_FORMAT, "%n- %l", 1);
1571 
1572  SCLogInitLogModule(NULL);
1573 
1574  FAIL_IF_NOT(SC_LOG_DEBUG == sc_log_config->log_level);
1575  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1576  SC_LOG_OP_IFACE_CONSOLE == sc_log_config->op_ifaces->iface);
1577  FAIL_IF_NOT(sc_log_config->log_format != NULL &&
1578  !strcmp("%n- %l", sc_log_config->log_format));
1579 
1583 
1585 #endif
1586  PASS;
1587 }
1588 
1589 static int SCLogTestInit02(void)
1590 {
1591 #ifndef OS_WIN32
1592  SCLogInitData *sc_lid = NULL;
1593  SCLogOPIfaceCtx *sc_iface_ctx = NULL;
1594  char *logfile = SCLogGetLogFilename("boo.txt");
1595  sc_lid = SCLogAllocLogInitData();
1596  FAIL_IF_NULL(sc_lid);
1597  sc_lid->startup_message = "Test02";
1598  sc_lid->global_log_level = SC_LOG_DEBUG;
1599  sc_lid->op_filter = "boo";
1600  sc_iface_ctx = SCLogInitOPIfaceCtx("file", "%m - %d", SC_LOG_ALERT,
1601  logfile);
1602  SCLogAppendOPIfaceCtx(sc_iface_ctx, sc_lid);
1603  sc_iface_ctx = SCLogInitOPIfaceCtx("console", NULL, SC_LOG_ERROR,
1604  NULL);
1605  SCLogAppendOPIfaceCtx(sc_iface_ctx, sc_lid);
1606 
1607  SCLogInitLogModule(sc_lid);
1608 
1609  FAIL_IF_NULL(sc_log_config);
1610 
1611  FAIL_IF_NOT(SC_LOG_DEBUG == sc_log_config->log_level);
1612  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1613  SC_LOG_OP_IFACE_FILE == sc_log_config->op_ifaces->iface);
1614  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1615  sc_log_config->op_ifaces->next != NULL &&
1616  SC_LOG_OP_IFACE_CONSOLE == sc_log_config->op_ifaces->next->iface);
1617  FAIL_IF_NOT(sc_log_config->log_format != NULL &&
1618  strcmp(SCLogGetDefaultLogFormat(), sc_log_config->log_format) == 0);
1619  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1620  sc_log_config->op_ifaces->log_format != NULL &&
1621  strcmp("%m - %d", sc_log_config->op_ifaces->log_format) == 0);
1622  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1623  sc_log_config->op_ifaces->next != NULL &&
1624  sc_log_config->op_ifaces->next->log_format == NULL);
1625 
1626  SCLogFreeLogInitData(sc_lid);
1628 
1629  sc_lid = SCLogAllocLogInitData();
1630  FAIL_IF_NULL(sc_lid);
1631  sc_lid->startup_message = "Test02";
1632  sc_lid->global_log_level = SC_LOG_DEBUG;
1633  sc_lid->op_filter = "boo";
1634  sc_lid->global_log_format = "kaboo";
1635 
1636  SCLogInitLogModule(sc_lid);
1637 
1638  FAIL_IF_NULL(sc_log_config);
1639 
1640  FAIL_IF_NOT(SC_LOG_DEBUG == sc_log_config->log_level);
1641  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1642  SC_LOG_OP_IFACE_CONSOLE == sc_log_config->op_ifaces->iface);
1643  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1644  sc_log_config->op_ifaces->next == NULL);
1645  FAIL_IF_NOT(sc_log_config->log_format != NULL &&
1646  strcmp("kaboo", sc_log_config->log_format) == 0);
1647  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1648  sc_log_config->op_ifaces->log_format == NULL);
1649  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1650  sc_log_config->op_ifaces->next == NULL);
1651 
1652  SCLogFreeLogInitData(sc_lid);
1654  SCFree(logfile);
1655 #endif
1656  PASS;
1657 }
1658 
1659 static int SCLogTestInit03(void)
1660 {
1661  SCLogInitLogModule(NULL);
1662 
1663  SCLogAddFGFilterBL(NULL, "bamboo", -1);
1664  SCLogAddFGFilterBL(NULL, "soo", -1);
1665  SCLogAddFGFilterBL(NULL, "dummy", -1);
1666 
1668 
1669  SCLogAddFGFilterBL(NULL, "dummy1", -1);
1670  SCLogAddFGFilterBL(NULL, "dummy2", -1);
1671 
1673 
1675 
1676  PASS;
1677 }
1678 
1679 static int SCLogTestInit04(void)
1680 {
1681  SCLogInitLogModule(NULL);
1682 
1683  SCLogAddFDFilter("bamboo");
1684  SCLogAddFDFilter("soo");
1685  SCLogAddFDFilter("foo");
1686  SCLogAddFDFilter("roo");
1687 
1689 
1690  SCLogAddFDFilter("loo");
1691  SCLogAddFDFilter("soo");
1692 
1694 
1695  SCLogRemoveFDFilter("bamboo");
1696  SCLogRemoveFDFilter("soo");
1697  SCLogRemoveFDFilter("foo");
1698  SCLogRemoveFDFilter("noo");
1699 
1701 
1703 
1704  PASS;
1705 }
1706 
1707 static int SCLogTestInit05(void)
1708 {
1709  char str[4096];
1710  memset(str, 'A', sizeof(str));
1711  SCLogInfo("%s", str);
1712 
1713  PASS;
1714 }
1715 
1716 #endif /* UNITTESTS */
1717 
1719 {
1720 
1721 #ifdef UNITTESTS
1722 
1723  UtRegisterTest("SCLogTestInit01", SCLogTestInit01);
1724  UtRegisterTest("SCLogTestInit02", SCLogTestInit02);
1725  UtRegisterTest("SCLogTestInit03", SCLogTestInit03);
1726  UtRegisterTest("SCLogTestInit04", SCLogTestInit04);
1727  UtRegisterTest("SCLogTestInit05", SCLogTestInit05);
1728 
1729 #endif /* UNITTESTS */
1730 
1731  return;
1732 }
SCLogConfig_::op_filter_regex_study
pcre_extra * op_filter_regex_study
Definition: util-debug.h:180
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
pcre_free_study
#define pcre_free_study
Definition: suricata-common.h:373
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
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:1299
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:1333
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:681
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:1899
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:176
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:1515
packet-queue.h
LOG_DEBUG
#define LOG_DEBUG
Definition: win32-syslog.h:46
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:350
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:381
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:618
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
MAX_SUBSTRINGS
#define MAX_SUBSTRINGS
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:879
ConfGet
int ConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition: conf.c:331
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
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:1259
SCLogRegisterTests
void SCLogRegisterTests()
Definition: util-debug.c:1718
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
SC_ERR_MUTEX
@ SC_ERR_MUTEX
Definition: util-error.h:151
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:282
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:541
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:261
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:815
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
SCLogConfig_::op_filter_regex
pcre * op_filter_regex
Definition: util-debug.h:179
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:39
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:637
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:1151
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:273
ConfigGetLogDirectory
const char * ConfigGetLogDirectory()
Definition: util-conf.c:36
head
Flow * head
Definition: flow-hash.h:0
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:591
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:1214
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:571
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
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:662
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:843
SC_LOG_FMT_TM
#define SC_LOG_FMT_TM
Definition: util-debug.h:192