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) {
690  "Fatal error encountered in SCLogAllocLogOPBuffer. Exiting...");
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) {
718  "Fatal error encountered in SCLogallocLogOPIfaceCtx. Exiting...");
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) {
745  "Fatal error encountered in SCLogInitFileOPIface. Exiting...");
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) {
810  "Fatal error encountered in SCLogInitConsoleOPIface. Exiting...");
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) {
876  "Fatal error encountered in SCLogInitSyslogOPIface. Exiting...");
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 
975 {
977 }
978 
979 static inline const char *SCLogGetDefaultLogFormat(void)
980 {
981  const char *prog_ver = GetProgramVersion();
982  if (strstr(prog_ver, "RELEASE") != NULL) {
984  }
986 }
987 
988 /**
989  * \brief Internal function used to set the logging module global_log_format
990  * during the initialization phase
991  *
992  * \param sc_lid The initialization data supplied.
993  * \param sc_lc The logging module context which has to be updated.
994  */
995 static inline void SCLogSetLogFormat(SCLogInitData *sc_lid, SCLogConfig *sc_lc)
996 {
997  const char *format = NULL;
998 
999  /* envvar overrides config */
1000  format = getenv(SC_LOG_ENV_LOG_FORMAT);
1001  if (format == NULL) {
1002  if (sc_lid != NULL) {
1003  format = sc_lid->global_log_format;
1004  }
1005  }
1006 
1007  /* deal with the global log format to be used */
1008  if (format == NULL || strlen(format) > SC_LOG_MAX_LOG_FORMAT_LEN) {
1009  format = SCLogGetDefaultLogFormat();
1010 #ifndef UNITTESTS
1011  if (sc_lid != NULL) {
1012  printf("Warning: Invalid/No global_log_format supplied by user or format "
1013  "length exceeded limit of \"%d\" characters. Falling back on "
1014  "default log_format \"%s\"\n", SC_LOG_MAX_LOG_FORMAT_LEN,
1015  format);
1016  }
1017 #endif
1018  }
1019 
1020  if (format != NULL && (sc_lc->log_format = SCStrdup(format)) == NULL) {
1021  printf("Error allocating memory\n");
1022  exit(EXIT_FAILURE);
1023  }
1024 
1025  return;
1026 }
1027 
1028 /**
1029  * \brief Internal function used to set the logging module global_op_ifaces
1030  * during the initialization phase
1031  *
1032  * \param sc_lid The initialization data supplied.
1033  * \param sc_lc The logging module context which has to be updated.
1034  */
1035 static inline void SCLogSetOPIface(SCLogInitData *sc_lid, SCLogConfig *sc_lc)
1036 {
1037  SCLogOPIfaceCtx *op_ifaces_ctx = NULL;
1038  int op_iface = 0;
1039  const char *s = NULL;
1040 
1041  if (sc_lid != NULL && sc_lid->op_ifaces != NULL) {
1042  sc_lc->op_ifaces = sc_lid->op_ifaces;
1043  sc_lid->op_ifaces = NULL;
1044  sc_lc->op_ifaces_cnt = sc_lid->op_ifaces_cnt;
1045  } else {
1046  s = getenv(SC_LOG_ENV_LOG_OP_IFACE);
1047  if (s != NULL) {
1049 
1050  if(op_iface < 0 || op_iface >= SC_LOG_OP_IFACE_MAX) {
1051  op_iface = SC_LOG_DEF_LOG_OP_IFACE;
1052 #ifndef UNITTESTS
1053  printf("Warning: Invalid output interface supplied by user. "
1054  "Falling back on default_output_interface \"%s\"\n",
1056 #endif
1057  }
1058  }
1059  else {
1060  op_iface = SC_LOG_DEF_LOG_OP_IFACE;
1061 #ifndef UNITTESTS
1062  if (sc_lid != NULL) {
1063  printf("Warning: Output_interface not supplied by user. Falling "
1064  "back on default_output_interface \"%s\"\n",
1066  }
1067 #endif
1068  }
1069 
1070  switch (op_iface) {
1072  op_ifaces_ctx = SCLogInitConsoleOPIface(NULL, SC_LOG_LEVEL_MAX,0);
1073  break;
1074  case SC_LOG_OP_IFACE_FILE:
1075  s = getenv(SC_LOG_ENV_LOG_FILE);
1076  if (s == NULL) {
1077  char *str = SCLogGetLogFilename(SC_LOG_DEF_LOG_FILE);
1078  if (str != NULL) {
1079  op_ifaces_ctx = SCLogInitFileOPIface(str, NULL, SC_LOG_LEVEL_MAX,0);
1080  SCFree(str);
1081  }
1082  } else {
1083  op_ifaces_ctx = SCLogInitFileOPIface(s, NULL, SC_LOG_LEVEL_MAX,0);
1084  }
1085  break;
1087  s = getenv(SC_LOG_ENV_LOG_FACILITY);
1088  if (s == NULL)
1090 
1091  op_ifaces_ctx = SCLogInitSyslogOPIface(SCMapEnumNameToValue(s, SCSyslogGetFacilityMap()), NULL, -1,0);
1092  break;
1093  }
1094  sc_lc->op_ifaces = op_ifaces_ctx;
1095  sc_lc->op_ifaces_cnt++;
1096  }
1097  return;
1098 }
1099 
1100 /**
1101  * \brief Internal function used to set the logging module op_filter
1102  * during the initialization phase
1103  *
1104  * \param sc_lid The initialization data supplied.
1105  * \param sc_lc The logging module context which has to be updated.
1106  */
1107 static inline void SCLogSetOPFilter(SCLogInitData *sc_lid, SCLogConfig *sc_lc)
1108 {
1109  const char *filter = NULL;
1110 
1111  int opts = 0;
1112  const char *ep;
1113  int eo = 0;
1114 
1115  /* envvar overrides */
1116  filter = getenv(SC_LOG_ENV_LOG_OP_FILTER);
1117  if (filter == NULL) {
1118  if (sc_lid != NULL) {
1119  filter = sc_lid->op_filter;
1120  }
1121  }
1122 
1123  if (filter != NULL && strcmp(filter, "") != 0) {
1124  sc_lc->op_filter = SCStrdup(filter);
1125  if (sc_lc->op_filter == NULL) {
1126  printf("pcre filter alloc failed\n");
1127  return;
1128  }
1129  sc_lc->op_filter_regex = pcre_compile(filter, opts, &ep, &eo, NULL);
1130  if (sc_lc->op_filter_regex == NULL) {
1131  SCFree(sc_lc->op_filter);
1132  printf("pcre compile of \"%s\" failed at offset %d : %s\n", filter,
1133  eo, ep);
1134  return;
1135  }
1136 
1137  sc_lc->op_filter_regex_study = pcre_study(sc_lc->op_filter_regex, 0,
1138  &ep);
1139  if (ep != NULL) {
1140  printf("pcre study failed: %s\n", ep);
1141  return;
1142  }
1143  }
1144 
1145  return;
1146 }
1147 
1148 /**
1149  * \brief Returns a pointer to a new SCLogInitData. This is a public interface
1150  * intended to be used after the logging paramters are read from the
1151  * conf file
1152  *
1153  * \retval sc_lid Pointer to the newly created SCLogInitData
1154  * \initonly
1155  */
1157 {
1158  SCLogInitData *sc_lid = NULL;
1159 
1160  /* not using SCMalloc here because if it fails we can't log */
1161  if ( (sc_lid = SCMalloc(sizeof(SCLogInitData))) == NULL)
1162  return NULL;
1163 
1164  memset(sc_lid, 0, sizeof(SCLogInitData));
1165 
1166  return sc_lid;
1167 }
1168 
1169 #ifdef UNITTESTS
1170 #ifndef OS_WIN32
1171 /**
1172  * \brief Frees a SCLogInitData
1173  *
1174  * \param sc_lid Pointer to the SCLogInitData to be freed
1175  */
1176 static void SCLogFreeLogInitData(SCLogInitData *sc_lid)
1177 {
1178  if (sc_lid != NULL) {
1179  SCLogFreeLogOPIfaceCtx(sc_lid->op_ifaces);
1180  SCFree(sc_lid);
1181  }
1182 
1183  return;
1184 }
1185 #endif
1186 #endif
1187 
1188 /**
1189  * \brief Frees the logging module context
1190  */
1191 static inline void SCLogFreeLogConfig(SCLogConfig *sc_lc)
1192 {
1193  if (sc_lc != NULL) {
1194  if (sc_lc->startup_message != NULL)
1195  SCFree(sc_lc->startup_message);
1196  if (sc_lc->log_format != NULL)
1197  SCFree(sc_lc->log_format);
1198  if (sc_lc->op_filter != NULL)
1199  SCFree(sc_lc->op_filter);
1200 
1201  if (sc_lc->op_filter_regex != NULL)
1202  pcre_free(sc_lc->op_filter_regex);
1203  if (sc_lc->op_filter_regex_study)
1205 
1206  SCLogFreeLogOPIfaceCtx(sc_lc->op_ifaces);
1207  SCFree(sc_lc);
1208  }
1209 
1210  return;
1211 }
1212 
1213 /**
1214  * \brief Appends an output_interface to the output_interface list sent in head
1215  *
1216  * \param iface_ctx Pointer to the output_interface that has to be added to head
1217  * \param head Pointer to the output_interface list
1218  */
1220 {
1221  SCLogOPIfaceCtx *temp = NULL, *prev = NULL;
1222  SCLogOPIfaceCtx **head = &sc_lid->op_ifaces;
1223 
1224  if (iface_ctx == NULL) {
1225 #ifdef DEBUG
1226  printf("Argument(s) to SCLogAppendOPIfaceCtx() NULL\n");
1227 #endif
1228  return;
1229  }
1230 
1231  temp = *head;
1232  while (temp != NULL) {
1233  prev = temp;
1234  temp = temp->next;
1235  }
1236 
1237  if (prev == NULL)
1238  *head = iface_ctx;
1239  else
1240  prev->next = iface_ctx;
1241 
1242  sc_lid->op_ifaces_cnt++;
1243 
1244  return;
1245 }
1246 
1247 
1248 /**
1249  * \brief Creates a new output interface based on the arguments sent. The kind
1250  * of output interface to be created is decided by the iface_name arg.
1251  * If iface_name is "file", the arg argument will hold the filename to be
1252  * used for logging purposes. If iface_name is "syslog", the arg
1253  * argument holds the facility code. If iface_name is "console", arg is
1254  * NULL.
1255  *
1256  * \param iface_name Interface name. Can be "console", "file" or "syslog"
1257  * \param log_format Override for the global_log_format
1258  * \param log_level Override for the global_log_level
1259  * \param log_level Parameter required by a particular interface. Explained in
1260  * the function description
1261  *
1262  * \retval iface_ctx Pointer to the newly created output interface
1263  */
1264 SCLogOPIfaceCtx *SCLogInitOPIfaceCtx(const char *iface_name,
1265  const char *log_format,
1266  int log_level, const char *arg)
1267 {
1268  int iface = SCMapEnumNameToValue(iface_name, sc_log_op_iface_map);
1269 
1270  if (log_level < SC_LOG_NONE || log_level > SC_LOG_DEBUG) {
1271 #ifndef UNITTESTS
1272  printf("Warning: Supplied log_level_override for op_interface \"%s\" "
1273  "is invalid. Defaulting to not specifying an override\n",
1274  iface_name);
1275 #endif
1276  log_level = SC_LOG_NOTSET;
1277  }
1278 
1279  switch (iface) {
1281  return SCLogInitConsoleOPIface(log_format, log_level, SC_LOG_OP_TYPE_REGULAR);
1282  case SC_LOG_OP_IFACE_FILE:
1283  return SCLogInitFileOPIface(arg, log_format, log_level, SC_LOG_OP_TYPE_REGULAR);
1285  return SCLogInitSyslogOPIface(SCMapEnumNameToValue(arg, SCSyslogGetFacilityMap()),
1286  log_format, log_level, SC_LOG_OP_TYPE_REGULAR);
1287  default:
1288 #ifdef DEBUG
1289  printf("Output Interface \"%s\" not supported by the logging module",
1290  iface_name);
1291 #endif
1292  return NULL;
1293  }
1294 }
1295 
1296 /**
1297  * \brief Initializes the logging module.
1298  *
1299  * \param sc_lid The initialization data for the logging module. If sc_lid is
1300  * NULL, we would stick to the default configuration for the
1301  * logging subsystem.
1302  * \initonly
1303  */
1305 {
1306  /* De-initialize the logging context, if it has already init by the
1307  * environment variables at the start of the engine */
1309 
1310 #if defined (OS_WIN32)
1311  if (SCMutexInit(&sc_log_stream_lock, NULL) != 0) {
1312  FatalError(SC_ERR_FATAL, "Failed to initialize log mutex.");
1313  }
1314 #endif /* OS_WIN32 */
1315 
1316  /* sc_log_config is a global variable */
1317  if ( (sc_log_config = SCMalloc(sizeof(SCLogConfig))) == NULL) {
1319  "Fatal error encountered in SCLogInitLogModule. Exiting...");
1320  }
1321  memset(sc_log_config, 0, sizeof(SCLogConfig));
1322 
1323  SCLogSetLogLevel(sc_lid, sc_log_config);
1324  SCLogSetLogFormat(sc_lid, sc_log_config);
1325  SCLogSetOPIface(sc_lid, sc_log_config);
1326  SCLogSetOPFilter(sc_lid, sc_log_config);
1327 
1330 
1331  //SCOutputPrint(sc_did->startup_message);
1332 
1333  rs_log_set_level(sc_log_global_log_level);
1334  return;
1335 }
1336 
1337 void SCLogLoadConfig(int daemon, int verbose)
1338 {
1339  ConfNode *outputs;
1340  SCLogInitData *sc_lid;
1341  int have_logging = 0;
1342  int max_level = 0;
1343  SCLogLevel min_level = 0;
1344 
1345  /* If verbose logging was requested, set the minimum as
1346  * SC_LOG_NOTICE plus the extra verbosity. */
1347  if (verbose) {
1348  min_level = SC_LOG_NOTICE + verbose;
1349  }
1350 
1351  outputs = ConfGetNode("logging.outputs");
1352  if (outputs == NULL) {
1353  SCLogDebug("No logging.output configuration section found.");
1354  return;
1355  }
1356 
1357  sc_lid = SCLogAllocLogInitData();
1358  if (sc_lid == NULL) {
1359  SCLogDebug("Could not allocate memory for log init data");
1360  return;
1361  }
1362 
1363  /* Get default log level and format. */
1364  const char *default_log_level_s = NULL;
1365  if (ConfGet("logging.default-log-level", &default_log_level_s) == 1) {
1366  SCLogLevel default_log_level =
1367  SCMapEnumNameToValue(default_log_level_s, sc_log_level_map);
1368  if (default_log_level == -1) {
1369  SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid default log level: %s",
1370  default_log_level_s);
1371  exit(EXIT_FAILURE);
1372  }
1373  sc_lid->global_log_level = MAX(min_level, default_log_level);
1374  }
1375  else {
1376  sc_lid->global_log_level = MAX(min_level, SC_LOG_NOTICE);
1377  }
1378 
1379  if (ConfGet("logging.default-log-format", &sc_lid->global_log_format) != 1)
1380  sc_lid->global_log_format = SCLogGetDefaultLogFormat();
1381 
1382  (void)ConfGet("logging.default-output-filter", &sc_lid->op_filter);
1383 
1384  ConfNode *seq_node, *output;
1385  TAILQ_FOREACH(seq_node, &outputs->head, next) {
1386  SCLogLevel level = sc_lid->global_log_level;
1387  SCLogOPIfaceCtx *op_iface_ctx = NULL;
1388  const char *format;
1389  const char *level_s;
1390 
1391  output = ConfNodeLookupChild(seq_node, seq_node->val);
1392  if (output == NULL)
1393  continue;
1394 
1395  /* By default an output is enabled. */
1396  const char *enabled = ConfNodeLookupChildValue(output, "enabled");
1397  if (enabled != NULL && ConfValIsFalse(enabled))
1398  continue;
1399 
1401  const char *type_s = ConfNodeLookupChildValue(output, "type");
1402  if (type_s != NULL) {
1403  if (strcmp(type_s, "regular") == 0)
1405  else if (strcmp(type_s, "json") == 0) {
1407  }
1408  }
1409 
1410  /* if available use the log format setting for this output,
1411  * otherwise fall back to the global setting. */
1412  format = ConfNodeLookupChildValue(output, "format");
1413  if (format == NULL)
1414  format = sc_lid->global_log_format;
1415 
1416  level_s = ConfNodeLookupChildValue(output, "level");
1417  if (level_s != NULL) {
1418  level = SCMapEnumNameToValue(level_s, sc_log_level_map);
1419  if (level == -1) {
1420  SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid log level: %s",
1421  level_s);
1422  exit(EXIT_FAILURE);
1423  }
1424  max_level = MAX(max_level, level);
1425  }
1426 
1427  /* Increase the level of extra verbosity was requested. */
1428  level = MAX(min_level, level);
1429 
1430  if (strcmp(output->name, "console") == 0) {
1431  op_iface_ctx = SCLogInitConsoleOPIface(format, level, type);
1432  }
1433  else if (strcmp(output->name, "file") == 0) {
1434  const char *filename = ConfNodeLookupChildValue(output, "filename");
1435  if (filename == NULL) {
1437  "Logging to file requires a filename");
1438  }
1439  char *path = NULL;
1440  if (!(PathIsAbsolute(filename))) {
1441  path = SCLogGetLogFilename(filename);
1442  } else {
1443  path = SCStrdup(filename);
1444  }
1445  if (path == NULL)
1446  FatalError(SC_ERR_FATAL, "failed to setup output to file");
1447  have_logging = 1;
1448  op_iface_ctx = SCLogInitFileOPIface(path, format, level, type);
1449  SCFree(path);
1450  }
1451  else if (strcmp(output->name, "syslog") == 0) {
1452  int facility = SC_LOG_DEF_SYSLOG_FACILITY;
1453  const char *facility_s = ConfNodeLookupChildValue(output,
1454  "facility");
1455  if (facility_s != NULL) {
1456  facility = SCMapEnumNameToValue(facility_s, SCSyslogGetFacilityMap());
1457  if (facility == -1) {
1458  SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid syslog "
1459  "facility: \"%s\", now using \"%s\" as syslog "
1460  "facility", facility_s, SC_LOG_DEF_SYSLOG_FACILITY_STR);
1461  facility = SC_LOG_DEF_SYSLOG_FACILITY;
1462  }
1463  }
1464  SCLogDebug("Initializing syslog logging with format \"%s\"", format);
1465  have_logging = 1;
1466  op_iface_ctx = SCLogInitSyslogOPIface(facility, format, level, type);
1467  }
1468  else {
1469  SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid logging method: %s, "
1470  "ignoring", output->name);
1471  }
1472  if (op_iface_ctx != NULL) {
1473  SCLogAppendOPIfaceCtx(op_iface_ctx, sc_lid);
1474  }
1475  }
1476 
1477  if (daemon && (have_logging == 0)) {
1479  "NO logging compatible with daemon mode selected,"
1480  " suricata won't be able to log. Please update "
1481  " 'logging.outputs' in the YAML.");
1482  }
1483 
1484  /* Set the global log level to that of the max level used. */
1485  sc_lid->global_log_level = MAX(sc_lid->global_log_level, max_level);
1486  SCLogInitLogModule(sc_lid);
1487 
1488  SCLogDebug("sc_log_global_log_level: %d", sc_log_global_log_level);
1489  SCLogDebug("sc_lc->log_format: %s", sc_log_config->log_format);
1490  SCLogDebug("SCLogSetOPFilter: filter: %s", sc_log_config->op_filter);
1491 
1492  if (sc_lid != NULL)
1493  SCFree(sc_lid);
1494 }
1495 
1496 /**
1497  * \brief Returns a full file path given a filename uses log dir specified in
1498  * conf or DEFAULT_LOG_DIR
1499  *
1500  * \param filearg The relative filename for which we want a full path include
1501  * log directory
1502  *
1503  * \retval log_filename The fullpath of the logfile to open
1504  */
1505 static char *SCLogGetLogFilename(const char *filearg)
1506 {
1507  const char *log_dir = ConfigGetLogDirectory();
1508  char *log_filename = SCMalloc(PATH_MAX);
1509  if (unlikely(log_filename == NULL))
1510  return NULL;
1511  snprintf(log_filename, PATH_MAX, "%s/%s", log_dir, filearg);
1512  return log_filename;
1513 }
1514 
1515 /**
1516  * \brief De-Initializes the logging module
1517  */
1519 {
1520  SCLogFreeLogConfig(sc_log_config);
1521 
1522  /* reset the global logging_module variables */
1526  sc_log_config = NULL;
1527 
1528  /* de-init the FD filters */
1530  /* de-init the FG filters */
1532 
1533 #if defined (OS_WIN32)
1534  SCMutexDestroy(&sc_log_stream_lock);
1535 #endif /* OS_WIN32 */
1536 
1537  return;
1538 }
1539 
1540 //------------------------------------Unit_Tests--------------------------------
1541 
1542 /* The logging engine should be tested to the maximum extent possible, since
1543  * logging code would be used throughout the codebase, and hence we can't afford
1544  * to have a single bug here(not that you can afford to have a bug
1545  * elsewhere ;) ). Please report a bug, if you get a slightest hint of a bug
1546  * from the logging module.
1547  */
1548 
1549 #ifdef UNITTESTS
1550 
1551 static int SCLogTestInit01(void)
1552 {
1553 #ifndef OS_WIN32
1554  /* unset any environment variables set for the logging module */
1558 
1559  SCLogInitLogModule(NULL);
1560 
1561  FAIL_IF_NULL(sc_log_config);
1562 
1563  FAIL_IF_NOT(SC_LOG_DEF_LOG_LEVEL == sc_log_config->log_level);
1564  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1565  SC_LOG_DEF_LOG_OP_IFACE == sc_log_config->op_ifaces->iface);
1566  FAIL_IF_NOT(sc_log_config->log_format != NULL &&
1567  strcmp(SCLogGetDefaultLogFormat(), sc_log_config->log_format) == 0);
1568 
1570 
1571  setenv(SC_LOG_ENV_LOG_LEVEL, "Debug", 1);
1572  setenv(SC_LOG_ENV_LOG_OP_IFACE, "Console", 1);
1573  setenv(SC_LOG_ENV_LOG_FORMAT, "%n- %l", 1);
1574 
1575  SCLogInitLogModule(NULL);
1576 
1577  FAIL_IF_NOT(SC_LOG_DEBUG == sc_log_config->log_level);
1578  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1579  SC_LOG_OP_IFACE_CONSOLE == sc_log_config->op_ifaces->iface);
1580  FAIL_IF_NOT(sc_log_config->log_format != NULL &&
1581  !strcmp("%n- %l", sc_log_config->log_format));
1582 
1586 
1588 #endif
1589  PASS;
1590 }
1591 
1592 static int SCLogTestInit02(void)
1593 {
1594 #ifndef OS_WIN32
1595  SCLogInitData *sc_lid = NULL;
1596  SCLogOPIfaceCtx *sc_iface_ctx = NULL;
1597  char *logfile = SCLogGetLogFilename("boo.txt");
1598  sc_lid = SCLogAllocLogInitData();
1599  FAIL_IF_NULL(sc_lid);
1600  sc_lid->startup_message = "Test02";
1601  sc_lid->global_log_level = SC_LOG_DEBUG;
1602  sc_lid->op_filter = "boo";
1603  sc_iface_ctx = SCLogInitOPIfaceCtx("file", "%m - %d", SC_LOG_ALERT,
1604  logfile);
1605  SCLogAppendOPIfaceCtx(sc_iface_ctx, sc_lid);
1606  sc_iface_ctx = SCLogInitOPIfaceCtx("console", NULL, SC_LOG_ERROR,
1607  NULL);
1608  SCLogAppendOPIfaceCtx(sc_iface_ctx, sc_lid);
1609 
1610  SCLogInitLogModule(sc_lid);
1611 
1612  FAIL_IF_NULL(sc_log_config);
1613 
1614  FAIL_IF_NOT(SC_LOG_DEBUG == sc_log_config->log_level);
1615  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1616  SC_LOG_OP_IFACE_FILE == sc_log_config->op_ifaces->iface);
1617  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1618  sc_log_config->op_ifaces->next != NULL &&
1619  SC_LOG_OP_IFACE_CONSOLE == sc_log_config->op_ifaces->next->iface);
1620  FAIL_IF_NOT(sc_log_config->log_format != NULL &&
1621  strcmp(SCLogGetDefaultLogFormat(), sc_log_config->log_format) == 0);
1622  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1623  sc_log_config->op_ifaces->log_format != NULL &&
1624  strcmp("%m - %d", sc_log_config->op_ifaces->log_format) == 0);
1625  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1626  sc_log_config->op_ifaces->next != NULL &&
1627  sc_log_config->op_ifaces->next->log_format == NULL);
1628 
1629  SCLogFreeLogInitData(sc_lid);
1631 
1632  sc_lid = SCLogAllocLogInitData();
1633  FAIL_IF_NULL(sc_lid);
1634  sc_lid->startup_message = "Test02";
1635  sc_lid->global_log_level = SC_LOG_DEBUG;
1636  sc_lid->op_filter = "boo";
1637  sc_lid->global_log_format = "kaboo";
1638 
1639  SCLogInitLogModule(sc_lid);
1640 
1641  FAIL_IF_NULL(sc_log_config);
1642 
1643  FAIL_IF_NOT(SC_LOG_DEBUG == sc_log_config->log_level);
1644  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1645  SC_LOG_OP_IFACE_CONSOLE == sc_log_config->op_ifaces->iface);
1646  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1647  sc_log_config->op_ifaces->next == NULL);
1648  FAIL_IF_NOT(sc_log_config->log_format != NULL &&
1649  strcmp("kaboo", sc_log_config->log_format) == 0);
1650  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1651  sc_log_config->op_ifaces->log_format == NULL);
1652  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1653  sc_log_config->op_ifaces->next == NULL);
1654 
1655  SCLogFreeLogInitData(sc_lid);
1657  SCFree(logfile);
1658 #endif
1659  PASS;
1660 }
1661 
1662 static int SCLogTestInit03(void)
1663 {
1664  SCLogInitLogModule(NULL);
1665 
1666  SCLogAddFGFilterBL(NULL, "bamboo", -1);
1667  SCLogAddFGFilterBL(NULL, "soo", -1);
1668  SCLogAddFGFilterBL(NULL, "dummy", -1);
1669 
1671 
1672  SCLogAddFGFilterBL(NULL, "dummy1", -1);
1673  SCLogAddFGFilterBL(NULL, "dummy2", -1);
1674 
1676 
1678 
1679  PASS;
1680 }
1681 
1682 static int SCLogTestInit04(void)
1683 {
1684  SCLogInitLogModule(NULL);
1685 
1686  SCLogAddFDFilter("bamboo");
1687  SCLogAddFDFilter("soo");
1688  SCLogAddFDFilter("foo");
1689  SCLogAddFDFilter("roo");
1690 
1692 
1693  SCLogAddFDFilter("loo");
1694  SCLogAddFDFilter("soo");
1695 
1697 
1698  SCLogRemoveFDFilter("bamboo");
1699  SCLogRemoveFDFilter("soo");
1700  SCLogRemoveFDFilter("foo");
1701  SCLogRemoveFDFilter("noo");
1702 
1704 
1706 
1707  PASS;
1708 }
1709 
1710 static int SCLogTestInit05(void)
1711 {
1712  char str[4096];
1713  memset(str, 'A', sizeof(str));
1714  SCLogInfo("%s", str);
1715 
1716  PASS;
1717 }
1718 
1719 #endif /* UNITTESTS */
1720 
1722 {
1723 
1724 #ifdef UNITTESTS
1725 
1726  UtRegisterTest("SCLogTestInit01", SCLogTestInit01);
1727  UtRegisterTest("SCLogTestInit02", SCLogTestInit02);
1728  UtRegisterTest("SCLogTestInit03", SCLogTestInit03);
1729  UtRegisterTest("SCLogTestInit04", SCLogTestInit04);
1730  UtRegisterTest("SCLogTestInit05", SCLogTestInit05);
1731 
1732 #endif /* UNITTESTS */
1733 
1734  return;
1735 }
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:1304
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:1337
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:1976
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:1518
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: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
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:1264
SCLogRegisterTests
void SCLogRegisterTests()
Definition: util-debug.c:1721
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:1043
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: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
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:1156
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: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:1219
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:574
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:974
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:842
SC_LOG_FMT_TM
#define SC_LOG_FMT_TM
Definition: util-debug.h:192