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  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), "%s%s%s%s", substr,
371  yellow, t_thread_name, reset);
372  if (cw < 0)
373  return SC_ERR_SPRINTF;
374  temp += cw;
375  temp_fmt++;
376  substr = temp_fmt;
377  substr++;
378  break;
379 
381  temp_fmt[0] = '\0';
382  s = SCMapEnumValueToName(log_level, sc_log_level_map);
383  if (s != NULL) {
384  if (log_level <= SC_LOG_ERROR)
385  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
386  "%s%s%s%s", substr, redb, s, reset);
387  else if (log_level == SC_LOG_WARNING)
388  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
389  "%s%s%s%s", substr, red, s, reset);
390  else if (log_level == SC_LOG_NOTICE)
391  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
392  "%s%s%s%s", substr, yellowb, s, reset);
393  else
394  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
395  "%s%s%s%s", substr, yellow, s, reset);
396  } else {
397  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
398  "%s%s", substr, "INVALID");
399  }
400  if (cw < 0)
401  return SC_ERR_SPRINTF;
402  temp += cw;
403  temp_fmt++;
404  substr = temp_fmt;
405  substr++;
406  break;
407 
409  temp_fmt[0] = '\0';
410  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
411  "%s%s%s%s", substr, blue, file, reset);
412  if (cw < 0)
413  return SC_ERR_SPRINTF;
414  temp += cw;
415  temp_fmt++;
416  substr = temp_fmt;
417  substr++;
418  break;
419 
420  case SC_LOG_FMT_LINE:
421  temp_fmt[0] = '\0';
422  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
423  "%s%s%u%s", substr, green, line, reset);
424  if (cw < 0)
425  return SC_ERR_SPRINTF;
426  temp += cw;
427  temp_fmt++;
428  substr = temp_fmt;
429  substr++;
430  break;
431 
432  case SC_LOG_FMT_FUNCTION:
433  temp_fmt[0] = '\0';
434  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
435  "%s%s%s%s", substr, green, function, reset);
436  if (cw < 0)
437  return SC_ERR_SPRINTF;
438  temp += cw;
439  temp_fmt++;
440  substr = temp_fmt;
441  substr++;
442  break;
443 
444  }
445  temp_fmt++;
446  }
447  if ((temp - buffer) > SC_LOG_MAX_LOG_MSG_LEN) {
448  return SC_OK;
449  }
450  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), "%s", substr);
451  if (cw < 0) {
452  return SC_ERR_SPRINTF;
453  }
454  temp += cw;
455  if ((temp - buffer) > SC_LOG_MAX_LOG_MSG_LEN) {
456  return SC_OK;
457  }
458 
459  if (error_code != SC_OK) {
460  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
461  "[%sERRCODE%s: %s%s%s(%s%d%s)] - ", yellow, reset, red, SCErrorToString(error_code), reset, yellow, error_code, reset);
462  if (cw < 0) {
463  return SC_ERR_SPRINTF;
464  }
465  temp += cw;
466  if ((temp - buffer) > SC_LOG_MAX_LOG_MSG_LEN) {
467  return SC_OK;
468  }
469  }
470 
471  const char *hi = "";
472  if (error_code > SC_OK)
473  hi = red;
474  else if (log_level <= SC_LOG_NOTICE)
475  hi = yellow;
476  cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), "%s%s%s", hi, message, reset);
477  if (cw < 0) {
478  return SC_ERR_SPRINTF;
479  }
480  temp += cw;
481  if ((temp - buffer) > SC_LOG_MAX_LOG_MSG_LEN) {
482  return SC_OK;
483  }
484 
485  if (sc_log_config->op_filter_regex != NULL) {
486  if (pcre2_match(sc_log_config->op_filter_regex, (PCRE2_SPTR8)buffer, strlen(buffer), 0, 0,
487  sc_log_config->op_filter_regex_match, NULL) < 0) {
488  return SC_ERR_LOG_FG_FILTER_MATCH; // bit hacky, but just return !0
489  }
490  }
491 
492  return SC_OK;
493 }
494 
495 /** \internal
496  * \brief try to reopen file
497  * \note no error reporting here, as we're called by SCLogMessage
498  * \retval status 0 ok, -1 error */
499 static int SCLogReopen(SCLogOPIfaceCtx *op_iface_ctx)
500 {
501  if (op_iface_ctx->file == NULL) {
502  return 0;
503  }
504 
505  if (op_iface_ctx->file_d != NULL) {
506  fclose(op_iface_ctx->file_d);
507  }
508  op_iface_ctx->file_d = fopen(op_iface_ctx->file, "a");
509  if (op_iface_ctx->file_d == NULL) {
510  return -1;
511  }
512  return 0;
513 }
514 
515 /**
516  * \brief Adds the global log_format to the outgoing buffer
517  *
518  * \param log_level log_level of the message that has to be logged
519  * \param msg Buffer containing the outgoing message
520  * \param file File_name from where the message originated
521  * \param function Function_name from where the message originated
522  * \param line Line_no from where the messaged originated
523  *
524  * \retval SC_OK on success; else an error code
525  */
526 SCError SCLogMessage(const SCLogLevel log_level, const char *file,
527  const unsigned int line, const char *function,
528  const SCError error_code, const char *message)
529 {
530  char buffer[SC_LOG_MAX_LOG_MSG_LEN] = "";
531  SCLogOPIfaceCtx *op_iface_ctx = NULL;
532 
533  if (sc_log_module_initialized != 1) {
534  printf("Logging module not initialized. Call SCLogInitLogModule() "
535  "first before using the debug API\n");
536  return SC_OK;
537  }
538 
539  /* get ts here so we log the same ts to each output */
540  struct timeval tval;
541  gettimeofday(&tval, NULL);
542 
543  op_iface_ctx = sc_log_config->op_ifaces;
544  while (op_iface_ctx != NULL) {
545  if (log_level != SC_LOG_NOTSET && log_level > op_iface_ctx->log_level) {
546  op_iface_ctx = op_iface_ctx->next;
547  continue;
548  }
549 
550  switch (op_iface_ctx->iface) {
552  if (SCLogMessageGetBuffer(&tval, op_iface_ctx->use_color, op_iface_ctx->type,
553  buffer, sizeof(buffer),
554  op_iface_ctx->log_format ?
555  op_iface_ctx->log_format : sc_log_config->log_format,
556  log_level, file, line, function,
557  error_code, message) == 0)
558  {
559  SCLogPrintToStream((log_level == SC_LOG_ERROR)? stderr: stdout, buffer);
560  }
561  break;
563  if (SCLogMessageGetBuffer(&tval, 0, op_iface_ctx->type, buffer, sizeof(buffer),
564  op_iface_ctx->log_format ?
565  op_iface_ctx->log_format : sc_log_config->log_format,
566  log_level, file, line, function,
567  error_code, message) == 0)
568  {
569  int r = 0;
570  SCMutexLock(&op_iface_ctx->fp_mutex);
571  if (op_iface_ctx->rotation_flag) {
572  r = SCLogReopen(op_iface_ctx);
573  op_iface_ctx->rotation_flag = 0;
574  }
575  SCLogPrintToStream(op_iface_ctx->file_d, buffer);
576  SCMutexUnlock(&op_iface_ctx->fp_mutex);
577 
578  /* report error outside of lock to avoid recursion */
579  if (r == -1) {
580  SCLogError(SC_ERR_FOPEN, "re-opening file \"%s\" failed: %s",
581  op_iface_ctx->file, strerror(errno));
582  }
583  }
584  break;
586  if (SCLogMessageGetBuffer(&tval, 0, op_iface_ctx->type, buffer, sizeof(buffer),
587  op_iface_ctx->log_format ?
588  op_iface_ctx->log_format : sc_log_config->log_format,
589  log_level, file, line, function,
590  error_code, message) == 0)
591  {
592  SCLogPrintToSyslog(SCLogMapLogLevelToSyslogLevel(log_level), buffer);
593  }
594  break;
595  default:
596  break;
597  }
598  op_iface_ctx = op_iface_ctx->next;
599  }
600  return SC_OK;
601 }
602 
603 void SCLog(int x, const char *file, const char *func, const int line,
604  const char *fmt, ...)
605 {
606  if (sc_log_global_log_level >= x &&
608  SCLogMatchFGFilterWL(file, func, line) == 1 ||
609  SCLogMatchFGFilterBL(file, func, line) == 1) &&
611  SCLogMatchFDFilter(func) == 1))
612  {
614  va_list ap;
615  va_start(ap, fmt);
616  vsnprintf(msg, sizeof(msg), fmt, ap);
617  va_end(ap);
618  SCLogMessage(x, file, line, func, SC_OK, msg);
619  }
620 }
621 
622 void SCLogErr(int x, const char *file, const char *func, const int line,
623  const int err, const char *fmt, ...)
624 {
625  if (sc_log_global_log_level >= x &&
627  SCLogMatchFGFilterWL(file, func, line) == 1 ||
628  SCLogMatchFGFilterBL(file, func, line) == 1) &&
630  SCLogMatchFDFilter(func) == 1))
631  {
633  va_list ap;
634  va_start(ap, fmt);
635  vsnprintf(msg, sizeof(msg), fmt, ap);
636  va_end(ap);
637  SCLogMessage(x, file, line, func, err, msg);
638  }
639 }
640 
641 /**
642  * \brief Returns whether debug messages are enabled to be logged or not
643  *
644  * \retval 1 if debug messages are enabled to be logged
645  * \retval 0 if debug messages are not enabled to be logged
646  */
648 {
649 #ifdef DEBUG
651  return 1;
652  else
653  return 0;
654 #else
655  return 0;
656 #endif
657 }
658 
659 /**
660  * \brief Allocates an output buffer for an output interface. Used when we
661  * want the op_interface log_format to override the global_log_format.
662  * Currently not used.
663  *
664  * \retval buffer Pointer to the newly created output_buffer
665  */
667 {
668  SCLogOPBuffer *buffer = NULL;
669  SCLogOPIfaceCtx *op_iface_ctx = NULL;
670  int i = 0;
671 
672  if ( (buffer = SCMalloc(sc_log_config->op_ifaces_cnt *
673  sizeof(SCLogOPBuffer))) == NULL) {
675  "Fatal error encountered in SCLogAllocLogOPBuffer. Exiting...");
676  }
677 
678  op_iface_ctx = sc_log_config->op_ifaces;
679  for (i = 0;
680  i < sc_log_config->op_ifaces_cnt;
681  i++, op_iface_ctx = op_iface_ctx->next) {
682  buffer[i].log_format = op_iface_ctx->log_format;
683  buffer[i].temp = buffer[i].msg;
684  }
685 
686  return buffer;
687 }
688 
689 /*----------------------The logging module initialization code--------------- */
690 
691 /**
692  * \brief Returns a new output_interface_context
693  *
694  * \retval iface_ctx Pointer to a newly allocated output_interface_context
695  * \initonly
696  */
697 static inline SCLogOPIfaceCtx *SCLogAllocLogOPIfaceCtx(void)
698 {
699  SCLogOPIfaceCtx *iface_ctx = NULL;
700 
701  if ( (iface_ctx = SCMalloc(sizeof(SCLogOPIfaceCtx))) == NULL) {
703  "Fatal error encountered in SCLogallocLogOPIfaceCtx. Exiting...");
704  }
705  memset(iface_ctx, 0, sizeof(SCLogOPIfaceCtx));
706 
707  return iface_ctx;
708 }
709 
710 /**
711  * \brief Initializes the file output interface
712  *
713  * \param file Path to the file used for logging purposes
714  * \param log_format Pointer to the log_format for this op interface, that
715  * overrides the global_log_format
716  * \param log_level Override of the global_log_level by this interface
717  *
718  * \retval iface_ctx Pointer to the file output interface context created
719  * \initonly
720  */
721 static inline SCLogOPIfaceCtx *SCLogInitFileOPIface(const char *file, uint32_t userid,
722  uint32_t groupid, const char *log_format, int log_level, SCLogOPType type)
723 {
724  SCLogOPIfaceCtx *iface_ctx = SCLogAllocLogOPIfaceCtx();
725 
726  if (iface_ctx == NULL) {
728  "Fatal error encountered in SCLogInitFileOPIface. Exiting...");
729  }
730 
731  if (file == NULL) {
732  goto error;
733  }
734 
735  iface_ctx->iface = SC_LOG_OP_IFACE_FILE;
736  iface_ctx->type = type;
737 
738  if ( (iface_ctx->file_d = fopen(file, "a")) == NULL) {
739  printf("Error opening file %s\n", file);
740  goto error;
741  }
742 
743 #ifndef OS_WIN32
744  if (userid != 0 || groupid != 0) {
745  if (chown(file, userid, groupid) == -1) {
746  SCLogWarning(SC_WARN_CHOWN, "Failed to change ownership of file %s: %s", file,
747  strerror(errno));
748  }
749  }
750 #endif
751 
752  if ((iface_ctx->file = SCStrdup(file)) == NULL) {
753  goto error;
754  }
755 
756  if (log_format != NULL && (iface_ctx->log_format = SCStrdup(log_format)) == NULL) {
757  goto error;
758  }
759 
760  SCMutexInit(&iface_ctx->fp_mutex, NULL);
762 
763  iface_ctx->log_level = log_level;
764 
765  return iface_ctx;
766 
767 error:
768  if (iface_ctx->file != NULL) {
769  SCFree((char *)iface_ctx->file);
770  iface_ctx->file = NULL;
771  }
772  if (iface_ctx->log_format != NULL) {
773  SCFree((char *)iface_ctx->log_format);
774  iface_ctx->log_format = NULL;
775  }
776  if (iface_ctx->file_d != NULL) {
777  fclose(iface_ctx->file_d);
778  iface_ctx->file_d = NULL;
779  }
780  SCFree(iface_ctx);
781  return NULL;
782 }
783 
784 /**
785  * \brief Initializes the console output interface and deals with possible
786  * env var overrides.
787  *
788  * \param log_format Pointer to the log_format for this op interface, that
789  * overrides the global_log_format
790  * \param log_level Override of the global_log_level by this interface
791  *
792  * \retval iface_ctx Pointer to the console output interface context created
793  * \initonly
794  */
795 static inline SCLogOPIfaceCtx *SCLogInitConsoleOPIface(const char *log_format,
796  SCLogLevel log_level, SCLogOPType type)
797 {
798  SCLogOPIfaceCtx *iface_ctx = SCLogAllocLogOPIfaceCtx();
799 
800  if (iface_ctx == NULL) {
802  "Fatal error encountered in SCLogInitConsoleOPIface. Exiting...");
803  }
804 
805  iface_ctx->iface = SC_LOG_OP_IFACE_CONSOLE;
806  iface_ctx->type = type;
807 
808  /* console log format is overridden by envvars */
809  const char *tmp_log_format = log_format;
810  const char *s = getenv(SC_LOG_ENV_LOG_FORMAT);
811  if (s != NULL) {
812 #if 0
813  printf("Overriding setting for \"console.format\" because of env "
814  "var SC_LOG_FORMAT=\"%s\".\n", s);
815 #endif
816  tmp_log_format = s;
817  }
818 
819  if (tmp_log_format != NULL &&
820  (iface_ctx->log_format = SCStrdup(tmp_log_format)) == NULL) {
821  printf("Error allocating memory\n");
822  exit(EXIT_FAILURE);
823  }
824 
825  /* console log level is overridden by envvars */
826  SCLogLevel tmp_log_level = log_level;
827  s = getenv(SC_LOG_ENV_LOG_LEVEL);
828  if (s != NULL) {
830  if (l > SC_LOG_NOTSET && l < SC_LOG_LEVEL_MAX) {
831 #if 0
832  printf("Overriding setting for \"console.level\" because of env "
833  "var SC_LOG_LEVEL=\"%s\".\n", s);
834 #endif
835  tmp_log_level = l;
836  }
837  }
838  iface_ctx->log_level = tmp_log_level;
839 
840 #ifndef OS_WIN32
841  if (isatty(fileno(stdout)) && isatty(fileno(stderr))) {
842  iface_ctx->use_color = TRUE;
843  }
844 #endif
845 
846  return iface_ctx;
847 }
848 
849 /**
850  * \brief Initializes the syslog output interface
851  *
852  * \param facility The facility code for syslog
853  * \param log_format Pointer to the log_format for this op interface, that
854  * overrides the global_log_format
855  * \param log_level Override of the global_log_level by this interface
856  *
857  * \retval iface_ctx Pointer to the syslog output interface context created
858  */
859 static inline SCLogOPIfaceCtx *SCLogInitSyslogOPIface(int facility,
860  const char *log_format,
861  SCLogLevel log_level,
863 {
864  SCLogOPIfaceCtx *iface_ctx = SCLogAllocLogOPIfaceCtx();
865 
866  if ( iface_ctx == NULL) {
868  "Fatal error encountered in SCLogInitSyslogOPIface. Exiting...");
869  }
870 
871  iface_ctx->iface = SC_LOG_OP_IFACE_SYSLOG;
872  iface_ctx->type = type;
873 
874  if (facility == -1)
875  facility = SC_LOG_DEF_SYSLOG_FACILITY;
876  iface_ctx->facility = facility;
877 
878  if (log_format != NULL &&
879  (iface_ctx->log_format = SCStrdup(log_format)) == NULL) {
880  printf("Error allocating memory\n");
881  exit(EXIT_FAILURE);
882  }
883 
884  iface_ctx->log_level = log_level;
885 
886  openlog(NULL, LOG_NDELAY, iface_ctx->facility);
887 
888  return iface_ctx;
889 }
890 
891 /**
892  * \brief Frees the output_interface context supplied as an argument
893  *
894  * \param iface_ctx Pointer to the op_interface_context to be freed
895  */
896 static inline void SCLogFreeLogOPIfaceCtx(SCLogOPIfaceCtx *iface_ctx)
897 {
898  SCLogOPIfaceCtx *temp = NULL;
899 
900  while (iface_ctx != NULL) {
901  temp = iface_ctx;
902 
903  if (iface_ctx->file_d != NULL) {
904  fclose(iface_ctx->file_d);
905  SCMutexDestroy(&iface_ctx->fp_mutex);
906  }
907 
908  if (iface_ctx->file != NULL)
909  SCFree((void *)iface_ctx->file);
910 
911  if (iface_ctx->log_format != NULL)
912  SCFree((void *)iface_ctx->log_format);
913 
914  if (iface_ctx->iface == SC_LOG_OP_IFACE_SYSLOG) {
915  closelog();
916  }
917 
918  iface_ctx = iface_ctx->next;
919 
920  SCFree(temp);
921  }
922 
923  return;
924 }
925 
926 /**
927  * \brief Internal function used to set the logging module global_log_level
928  * during the initialization phase
929  *
930  * \param sc_lid The initialization data supplied.
931  * \param sc_lc The logging module context which has to be updated.
932  */
933 static inline void SCLogSetLogLevel(SCLogInitData *sc_lid, SCLogConfig *sc_lc)
934 {
935  SCLogLevel log_level = SC_LOG_NOTSET;
936  const char *s = NULL;
937 
938  /* envvar overrides config */
939  s = getenv(SC_LOG_ENV_LOG_LEVEL);
940  if (s != NULL) {
941  log_level = SCMapEnumNameToValue(s, sc_log_level_map);
942  } else if (sc_lid != NULL) {
943  log_level = sc_lid->global_log_level;
944  }
945 
946  /* deal with the global_log_level to be used */
947  if (log_level > SC_LOG_NOTSET && log_level < SC_LOG_LEVEL_MAX)
948  sc_lc->log_level = log_level;
949  else {
951 #ifndef UNITTESTS
952  if (sc_lid != NULL) {
953  printf("Warning: Invalid/No global_log_level assigned by user. Falling "
954  "back on the default_log_level \"%s\"\n",
956  }
957 #endif
958  }
959 
960  /* we also set it to a global var, as it is easier to access it */
962 
963  return;
964 }
965 
967 {
969 }
970 
971 static inline const char *SCLogGetDefaultLogFormat(void)
972 {
973  const char *prog_ver = GetProgramVersion();
974  if (strstr(prog_ver, "RELEASE") != NULL) {
976  }
978 }
979 
980 /**
981  * \brief Internal function used to set the logging module global_log_format
982  * during the initialization phase
983  *
984  * \param sc_lid The initialization data supplied.
985  * \param sc_lc The logging module context which has to be updated.
986  */
987 static inline void SCLogSetLogFormat(SCLogInitData *sc_lid, SCLogConfig *sc_lc)
988 {
989  const char *format = NULL;
990 
991  /* envvar overrides config */
992  format = getenv(SC_LOG_ENV_LOG_FORMAT);
993  if (format == NULL) {
994  if (sc_lid != NULL) {
995  format = sc_lid->global_log_format;
996  }
997  }
998 
999  /* deal with the global log format to be used */
1000  if (format == NULL || strlen(format) > SC_LOG_MAX_LOG_FORMAT_LEN) {
1001  format = SCLogGetDefaultLogFormat();
1002 #ifndef UNITTESTS
1003  if (sc_lid != NULL) {
1004  printf("Warning: Invalid/No global_log_format supplied by user or format "
1005  "length exceeded limit of \"%d\" characters. Falling back on "
1006  "default log_format \"%s\"\n", SC_LOG_MAX_LOG_FORMAT_LEN,
1007  format);
1008  }
1009 #endif
1010  }
1011 
1012  if (format != NULL && (sc_lc->log_format = SCStrdup(format)) == NULL) {
1013  printf("Error allocating memory\n");
1014  exit(EXIT_FAILURE);
1015  }
1016 
1017  return;
1018 }
1019 
1020 /**
1021  * \brief Internal function used to set the logging module global_op_ifaces
1022  * during the initialization phase
1023  *
1024  * \param sc_lid The initialization data supplied.
1025  * \param sc_lc The logging module context which has to be updated.
1026  */
1027 static inline void SCLogSetOPIface(SCLogInitData *sc_lid, SCLogConfig *sc_lc)
1028 {
1029  SCLogOPIfaceCtx *op_ifaces_ctx = NULL;
1030  int op_iface = 0;
1031  const char *s = NULL;
1032 
1033  if (sc_lid != NULL && sc_lid->op_ifaces != NULL) {
1034  sc_lc->op_ifaces = sc_lid->op_ifaces;
1035  sc_lid->op_ifaces = NULL;
1036  sc_lc->op_ifaces_cnt = sc_lid->op_ifaces_cnt;
1037  } else {
1038  s = getenv(SC_LOG_ENV_LOG_OP_IFACE);
1039  if (s != NULL) {
1041 
1042  if(op_iface < 0 || op_iface >= SC_LOG_OP_IFACE_MAX) {
1043  op_iface = SC_LOG_DEF_LOG_OP_IFACE;
1044 #ifndef UNITTESTS
1045  printf("Warning: Invalid output interface supplied by user. "
1046  "Falling back on default_output_interface \"%s\"\n",
1048 #endif
1049  }
1050  }
1051  else {
1052  op_iface = SC_LOG_DEF_LOG_OP_IFACE;
1053 #ifndef UNITTESTS
1054  if (sc_lid != NULL) {
1055  printf("Warning: Output_interface not supplied by user. Falling "
1056  "back on default_output_interface \"%s\"\n",
1058  }
1059 #endif
1060  }
1061 
1062  switch (op_iface) {
1064  op_ifaces_ctx = SCLogInitConsoleOPIface(NULL, SC_LOG_LEVEL_MAX,0);
1065  break;
1066  case SC_LOG_OP_IFACE_FILE:
1067  s = getenv(SC_LOG_ENV_LOG_FILE);
1068  if (s == NULL) {
1069  char *str = SCLogGetLogFilename(SC_LOG_DEF_LOG_FILE);
1070  if (str != NULL) {
1071  op_ifaces_ctx = SCLogInitFileOPIface(str, 0, 0, NULL, SC_LOG_LEVEL_MAX, 0);
1072  SCFree(str);
1073  }
1074  } else {
1075  op_ifaces_ctx = SCLogInitFileOPIface(s, 0, 0, NULL, SC_LOG_LEVEL_MAX, 0);
1076  }
1077  break;
1079  s = getenv(SC_LOG_ENV_LOG_FACILITY);
1080  if (s == NULL)
1082 
1083  op_ifaces_ctx = SCLogInitSyslogOPIface(SCMapEnumNameToValue(s, SCSyslogGetFacilityMap()), NULL, -1,0);
1084  break;
1085  }
1086  sc_lc->op_ifaces = op_ifaces_ctx;
1087  sc_lc->op_ifaces_cnt++;
1088  }
1089  return;
1090 }
1091 
1092 /**
1093  * \brief Internal function used to set the logging module op_filter
1094  * during the initialization phase
1095  *
1096  * \param sc_lid The initialization data supplied.
1097  * \param sc_lc The logging module context which has to be updated.
1098  */
1099 static inline void SCLogSetOPFilter(SCLogInitData *sc_lid, SCLogConfig *sc_lc)
1100 {
1101  const char *filter = NULL;
1102 
1103  int opts = 0;
1104  int en;
1105  PCRE2_SIZE eo = 0;
1106 
1107  /* envvar overrides */
1108  filter = getenv(SC_LOG_ENV_LOG_OP_FILTER);
1109  if (filter == NULL) {
1110  if (sc_lid != NULL) {
1111  filter = sc_lid->op_filter;
1112  }
1113  }
1114 
1115  if (filter != NULL && strcmp(filter, "") != 0) {
1116  sc_lc->op_filter = SCStrdup(filter);
1117  if (sc_lc->op_filter == NULL) {
1118  printf("pcre filter alloc failed\n");
1119  return;
1120  }
1121  sc_lc->op_filter_regex =
1122  pcre2_compile((PCRE2_SPTR8)filter, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
1123  if (sc_lc->op_filter_regex == NULL) {
1124  SCFree(sc_lc->op_filter);
1125  PCRE2_UCHAR errbuffer[256];
1126  pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
1127  printf("pcre2 compile of \"%s\" failed at offset %d : %s\n", filter, (int)eo,
1128  errbuffer);
1129  return;
1130  }
1131  sc_lc->op_filter_regex_match =
1132  pcre2_match_data_create_from_pattern(sc_lc->op_filter_regex, NULL);
1133  }
1134 
1135  return;
1136 }
1137 
1138 /**
1139  * \brief Returns a pointer to a new SCLogInitData. This is a public interface
1140  * intended to be used after the logging paramters are read from the
1141  * conf file
1142  *
1143  * \retval sc_lid Pointer to the newly created SCLogInitData
1144  * \initonly
1145  */
1147 {
1148  SCLogInitData *sc_lid = NULL;
1149 
1150  /* not using SCMalloc here because if it fails we can't log */
1151  if ( (sc_lid = SCMalloc(sizeof(SCLogInitData))) == NULL)
1152  return NULL;
1153 
1154  memset(sc_lid, 0, sizeof(SCLogInitData));
1155 
1156  return sc_lid;
1157 }
1158 
1159 #ifdef UNITTESTS
1160 #ifndef OS_WIN32
1161 /**
1162  * \brief Frees a SCLogInitData
1163  *
1164  * \param sc_lid Pointer to the SCLogInitData to be freed
1165  */
1166 static void SCLogFreeLogInitData(SCLogInitData *sc_lid)
1167 {
1168  if (sc_lid != NULL) {
1169  SCLogFreeLogOPIfaceCtx(sc_lid->op_ifaces);
1170  SCFree(sc_lid);
1171  }
1172 
1173  return;
1174 }
1175 #endif
1176 #endif
1177 
1178 /**
1179  * \brief Frees the logging module context
1180  */
1181 static inline void SCLogFreeLogConfig(SCLogConfig *sc_lc)
1182 {
1183  if (sc_lc != NULL) {
1184  if (sc_lc->startup_message != NULL)
1185  SCFree(sc_lc->startup_message);
1186  if (sc_lc->log_format != NULL)
1187  SCFree(sc_lc->log_format);
1188  if (sc_lc->op_filter != NULL)
1189  SCFree(sc_lc->op_filter);
1190 
1191  if (sc_lc->op_filter_regex != NULL)
1192  pcre2_code_free(sc_lc->op_filter_regex);
1193  if (sc_lc->op_filter_regex_match)
1194  pcre2_match_data_free(sc_lc->op_filter_regex_match);
1195 
1196  SCLogFreeLogOPIfaceCtx(sc_lc->op_ifaces);
1197  SCFree(sc_lc);
1198  }
1199 
1200  return;
1201 }
1202 
1203 /**
1204  * \brief Appends an output_interface to the output_interface list sent in head
1205  *
1206  * \param iface_ctx Pointer to the output_interface that has to be added to head
1207  * \param head Pointer to the output_interface list
1208  */
1210 {
1211  SCLogOPIfaceCtx *temp = NULL, *prev = NULL;
1212  SCLogOPIfaceCtx **head = &sc_lid->op_ifaces;
1213 
1214  if (iface_ctx == NULL) {
1215 #ifdef DEBUG
1216  printf("Argument(s) to SCLogAppendOPIfaceCtx() NULL\n");
1217 #endif
1218  return;
1219  }
1220 
1221  temp = *head;
1222  while (temp != NULL) {
1223  prev = temp;
1224  temp = temp->next;
1225  }
1226 
1227  if (prev == NULL)
1228  *head = iface_ctx;
1229  else
1230  prev->next = iface_ctx;
1231 
1232  sc_lid->op_ifaces_cnt++;
1233 
1234  return;
1235 }
1236 
1237 
1238 /**
1239  * \brief Creates a new output interface based on the arguments sent. The kind
1240  * of output interface to be created is decided by the iface_name arg.
1241  * If iface_name is "file", the arg argument will hold the filename to be
1242  * used for logging purposes. If iface_name is "syslog", the arg
1243  * argument holds the facility code. If iface_name is "console", arg is
1244  * NULL.
1245  *
1246  * \param iface_name Interface name. Can be "console", "file" or "syslog"
1247  * \param log_format Override for the global_log_format
1248  * \param log_level Override for the global_log_level
1249  * \param log_level Parameter required by a particular interface. Explained in
1250  * the function description
1251  *
1252  * \retval iface_ctx Pointer to the newly created output interface
1253  */
1254 SCLogOPIfaceCtx *SCLogInitOPIfaceCtx(const char *iface_name,
1255  const char *log_format,
1256  int log_level, const char *arg)
1257 {
1258  int iface = SCMapEnumNameToValue(iface_name, sc_log_op_iface_map);
1259 
1260  if (log_level < SC_LOG_NONE || log_level > SC_LOG_DEBUG) {
1261 #ifndef UNITTESTS
1262  printf("Warning: Supplied log_level_override for op_interface \"%s\" "
1263  "is invalid. Defaulting to not specifying an override\n",
1264  iface_name);
1265 #endif
1266  log_level = SC_LOG_NOTSET;
1267  }
1268 
1269  switch (iface) {
1271  return SCLogInitConsoleOPIface(log_format, log_level, SC_LOG_OP_TYPE_REGULAR);
1272  case SC_LOG_OP_IFACE_FILE:
1273  return SCLogInitFileOPIface(arg, 0, 0, log_format, log_level, SC_LOG_OP_TYPE_REGULAR);
1275  return SCLogInitSyslogOPIface(SCMapEnumNameToValue(arg, SCSyslogGetFacilityMap()),
1276  log_format, log_level, SC_LOG_OP_TYPE_REGULAR);
1277  default:
1278 #ifdef DEBUG
1279  printf("Output Interface \"%s\" not supported by the logging module",
1280  iface_name);
1281 #endif
1282  return NULL;
1283  }
1284 }
1285 
1286 /**
1287  * \brief Initializes the logging module.
1288  *
1289  * \param sc_lid The initialization data for the logging module. If sc_lid is
1290  * NULL, we would stick to the default configuration for the
1291  * logging subsystem.
1292  * \initonly
1293  */
1295 {
1296  /* De-initialize the logging context, if it has already init by the
1297  * environment variables at the start of the engine */
1299 
1300 #if defined (OS_WIN32)
1301  if (SCMutexInit(&sc_log_stream_lock, NULL) != 0) {
1302  FatalError(SC_ERR_FATAL, "Failed to initialize log mutex.");
1303  }
1304 #endif /* OS_WIN32 */
1305 
1306  /* sc_log_config is a global variable */
1307  if ( (sc_log_config = SCMalloc(sizeof(SCLogConfig))) == NULL) {
1309  "Fatal error encountered in SCLogInitLogModule. Exiting...");
1310  }
1311  memset(sc_log_config, 0, sizeof(SCLogConfig));
1312 
1313  SCLogSetLogLevel(sc_lid, sc_log_config);
1314  SCLogSetLogFormat(sc_lid, sc_log_config);
1315  SCLogSetOPIface(sc_lid, sc_log_config);
1316  SCLogSetOPFilter(sc_lid, sc_log_config);
1317 
1320 
1321  //SCOutputPrint(sc_did->startup_message);
1322 
1323  rs_log_set_level(sc_log_global_log_level);
1324  return;
1325 }
1326 
1327 void SCLogLoadConfig(int daemon, int verbose, uint32_t userid, uint32_t groupid)
1328 {
1329  ConfNode *outputs;
1330  SCLogInitData *sc_lid;
1331  int have_logging = 0;
1332  int max_level = 0;
1333  SCLogLevel min_level = 0;
1334 
1335  /* If verbose logging was requested, set the minimum as
1336  * SC_LOG_NOTICE plus the extra verbosity. */
1337  if (verbose) {
1338  min_level = SC_LOG_NOTICE + verbose;
1339  }
1340 
1341  outputs = ConfGetNode("logging.outputs");
1342  if (outputs == NULL) {
1343  SCLogDebug("No logging.output configuration section found.");
1344  return;
1345  }
1346 
1347  sc_lid = SCLogAllocLogInitData();
1348  if (sc_lid == NULL) {
1349  SCLogDebug("Could not allocate memory for log init data");
1350  return;
1351  }
1352 
1353  /* Get default log level and format. */
1354  const char *default_log_level_s = NULL;
1355  if (ConfGet("logging.default-log-level", &default_log_level_s) == 1) {
1356  SCLogLevel default_log_level =
1357  SCMapEnumNameToValue(default_log_level_s, sc_log_level_map);
1358  if (default_log_level == -1) {
1359  SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid default log level: %s",
1360  default_log_level_s);
1361  exit(EXIT_FAILURE);
1362  }
1363  sc_lid->global_log_level = MAX(min_level, default_log_level);
1364  }
1365  else {
1366  sc_lid->global_log_level = MAX(min_level, SC_LOG_NOTICE);
1367  }
1368 
1369  if (ConfGet("logging.default-log-format", &sc_lid->global_log_format) != 1)
1370  sc_lid->global_log_format = SCLogGetDefaultLogFormat();
1371 
1372  (void)ConfGet("logging.default-output-filter", &sc_lid->op_filter);
1373 
1374  ConfNode *seq_node, *output;
1375  TAILQ_FOREACH(seq_node, &outputs->head, next) {
1376  SCLogLevel level = sc_lid->global_log_level;
1377  SCLogOPIfaceCtx *op_iface_ctx = NULL;
1378  const char *format;
1379  const char *level_s;
1380 
1381  output = ConfNodeLookupChild(seq_node, seq_node->val);
1382  if (output == NULL)
1383  continue;
1384 
1385  /* By default an output is enabled. */
1386  const char *enabled = ConfNodeLookupChildValue(output, "enabled");
1387  if (enabled != NULL && ConfValIsFalse(enabled))
1388  continue;
1389 
1391  const char *type_s = ConfNodeLookupChildValue(output, "type");
1392  if (type_s != NULL) {
1393  if (strcmp(type_s, "regular") == 0)
1395  else if (strcmp(type_s, "json") == 0) {
1397  }
1398  }
1399 
1400  /* if available use the log format setting for this output,
1401  * otherwise fall back to the global setting. */
1402  format = ConfNodeLookupChildValue(output, "format");
1403  if (format == NULL)
1404  format = sc_lid->global_log_format;
1405 
1406  level_s = ConfNodeLookupChildValue(output, "level");
1407  if (level_s != NULL) {
1408  level = SCMapEnumNameToValue(level_s, sc_log_level_map);
1409  if (level == -1) {
1410  SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid log level: %s",
1411  level_s);
1412  exit(EXIT_FAILURE);
1413  }
1414  max_level = MAX(max_level, level);
1415  }
1416 
1417  /* Increase the level of extra verbosity was requested. */
1418  level = MAX(min_level, level);
1419 
1420  if (strcmp(output->name, "console") == 0) {
1421  op_iface_ctx = SCLogInitConsoleOPIface(format, level, type);
1422  }
1423  else if (strcmp(output->name, "file") == 0) {
1424  const char *filename = ConfNodeLookupChildValue(output, "filename");
1425  if (filename == NULL) {
1427  "Logging to file requires a filename");
1428  }
1429  char *path = NULL;
1430  if (!(PathIsAbsolute(filename))) {
1431  path = SCLogGetLogFilename(filename);
1432  } else {
1433  path = SCStrdup(filename);
1434  }
1435  if (path == NULL)
1436  FatalError(SC_ERR_FATAL, "failed to setup output to file");
1437  have_logging = 1;
1438  op_iface_ctx = SCLogInitFileOPIface(path, userid, groupid, format, level, type);
1439  SCFree(path);
1440  }
1441  else if (strcmp(output->name, "syslog") == 0) {
1442  int facility = SC_LOG_DEF_SYSLOG_FACILITY;
1443  const char *facility_s = ConfNodeLookupChildValue(output,
1444  "facility");
1445  if (facility_s != NULL) {
1446  facility = SCMapEnumNameToValue(facility_s, SCSyslogGetFacilityMap());
1447  if (facility == -1) {
1448  SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid syslog "
1449  "facility: \"%s\", now using \"%s\" as syslog "
1450  "facility", facility_s, SC_LOG_DEF_SYSLOG_FACILITY_STR);
1451  facility = SC_LOG_DEF_SYSLOG_FACILITY;
1452  }
1453  }
1454  SCLogDebug("Initializing syslog logging with format \"%s\"", format);
1455  have_logging = 1;
1456  op_iface_ctx = SCLogInitSyslogOPIface(facility, format, level, type);
1457  }
1458  else {
1459  SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid logging method: %s, "
1460  "ignoring", output->name);
1461  }
1462  if (op_iface_ctx != NULL) {
1463  SCLogAppendOPIfaceCtx(op_iface_ctx, sc_lid);
1464  }
1465  }
1466 
1467  if (daemon && (have_logging == 0)) {
1469  "NO logging compatible with daemon mode selected,"
1470  " suricata won't be able to log. Please update "
1471  " 'logging.outputs' in the YAML.");
1472  }
1473 
1474  /* Set the global log level to that of the max level used. */
1475  sc_lid->global_log_level = MAX(sc_lid->global_log_level, max_level);
1476  SCLogInitLogModule(sc_lid);
1477 
1478  SCLogDebug("sc_log_global_log_level: %d", sc_log_global_log_level);
1479  SCLogDebug("sc_lc->log_format: %s", sc_log_config->log_format);
1480  SCLogDebug("SCLogSetOPFilter: filter: %s", sc_log_config->op_filter);
1481 
1482  if (sc_lid != NULL)
1483  SCFree(sc_lid);
1484 }
1485 
1486 /**
1487  * \brief Returns a full file path given a filename uses log dir specified in
1488  * conf or DEFAULT_LOG_DIR
1489  *
1490  * \param filearg The relative filename for which we want a full path include
1491  * log directory
1492  *
1493  * \retval log_filename The fullpath of the logfile to open
1494  */
1495 static char *SCLogGetLogFilename(const char *filearg)
1496 {
1497  const char *log_dir = ConfigGetLogDirectory();
1498  char *log_filename = SCMalloc(PATH_MAX);
1499  if (unlikely(log_filename == NULL))
1500  return NULL;
1501  snprintf(log_filename, PATH_MAX, "%s/%s", log_dir, filearg);
1502  return log_filename;
1503 }
1504 
1505 /**
1506  * \brief De-Initializes the logging module
1507  */
1509 {
1510  SCLogFreeLogConfig(sc_log_config);
1511 
1512  /* reset the global logging_module variables */
1516  sc_log_config = NULL;
1517 
1518  /* de-init the FD filters */
1520  /* de-init the FG filters */
1522 
1523 #if defined (OS_WIN32)
1524  SCMutexDestroy(&sc_log_stream_lock);
1525 #endif /* OS_WIN32 */
1526 
1527  return;
1528 }
1529 
1530 //------------------------------------Unit_Tests--------------------------------
1531 
1532 /* The logging engine should be tested to the maximum extent possible, since
1533  * logging code would be used throughout the codebase, and hence we can't afford
1534  * to have a single bug here(not that you can afford to have a bug
1535  * elsewhere ;) ). Please report a bug, if you get a slightest hint of a bug
1536  * from the logging module.
1537  */
1538 
1539 #ifdef UNITTESTS
1540 
1541 static int SCLogTestInit01(void)
1542 {
1543 #ifndef OS_WIN32
1544  /* unset any environment variables set for the logging module */
1548 
1549  SCLogInitLogModule(NULL);
1550 
1551  FAIL_IF_NULL(sc_log_config);
1552 
1553  FAIL_IF_NOT(SC_LOG_DEF_LOG_LEVEL == sc_log_config->log_level);
1554  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1555  SC_LOG_DEF_LOG_OP_IFACE == sc_log_config->op_ifaces->iface);
1556  FAIL_IF_NOT(sc_log_config->log_format != NULL &&
1557  strcmp(SCLogGetDefaultLogFormat(), sc_log_config->log_format) == 0);
1558 
1560 
1561  setenv(SC_LOG_ENV_LOG_LEVEL, "Debug", 1);
1562  setenv(SC_LOG_ENV_LOG_OP_IFACE, "Console", 1);
1563  setenv(SC_LOG_ENV_LOG_FORMAT, "%n- %l", 1);
1564 
1565  SCLogInitLogModule(NULL);
1566 
1567  FAIL_IF_NOT(SC_LOG_DEBUG == sc_log_config->log_level);
1568  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1569  SC_LOG_OP_IFACE_CONSOLE == sc_log_config->op_ifaces->iface);
1570  FAIL_IF_NOT(sc_log_config->log_format != NULL &&
1571  !strcmp("%n- %l", sc_log_config->log_format));
1572 
1576 
1578 #endif
1579  PASS;
1580 }
1581 
1582 static int SCLogTestInit02(void)
1583 {
1584 #ifndef OS_WIN32
1585  SCLogInitData *sc_lid = NULL;
1586  SCLogOPIfaceCtx *sc_iface_ctx = NULL;
1587  char *logfile = SCLogGetLogFilename("boo.txt");
1588  sc_lid = SCLogAllocLogInitData();
1589  FAIL_IF_NULL(sc_lid);
1590  sc_lid->startup_message = "Test02";
1591  sc_lid->global_log_level = SC_LOG_DEBUG;
1592  sc_lid->op_filter = "boo";
1593  sc_iface_ctx = SCLogInitOPIfaceCtx("file", "%m - %d", SC_LOG_ALERT,
1594  logfile);
1595  SCLogAppendOPIfaceCtx(sc_iface_ctx, sc_lid);
1596  sc_iface_ctx = SCLogInitOPIfaceCtx("console", NULL, SC_LOG_ERROR,
1597  NULL);
1598  SCLogAppendOPIfaceCtx(sc_iface_ctx, sc_lid);
1599 
1600  SCLogInitLogModule(sc_lid);
1601 
1602  FAIL_IF_NULL(sc_log_config);
1603 
1604  FAIL_IF_NOT(SC_LOG_DEBUG == sc_log_config->log_level);
1605  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1606  SC_LOG_OP_IFACE_FILE == sc_log_config->op_ifaces->iface);
1607  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1608  sc_log_config->op_ifaces->next != NULL &&
1609  SC_LOG_OP_IFACE_CONSOLE == sc_log_config->op_ifaces->next->iface);
1610  FAIL_IF_NOT(sc_log_config->log_format != NULL &&
1611  strcmp(SCLogGetDefaultLogFormat(), sc_log_config->log_format) == 0);
1612  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1613  sc_log_config->op_ifaces->log_format != NULL &&
1614  strcmp("%m - %d", sc_log_config->op_ifaces->log_format) == 0);
1615  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1616  sc_log_config->op_ifaces->next != NULL &&
1617  sc_log_config->op_ifaces->next->log_format == NULL);
1618 
1619  SCLogFreeLogInitData(sc_lid);
1621 
1622  sc_lid = SCLogAllocLogInitData();
1623  FAIL_IF_NULL(sc_lid);
1624  sc_lid->startup_message = "Test02";
1625  sc_lid->global_log_level = SC_LOG_DEBUG;
1626  sc_lid->op_filter = "boo";
1627  sc_lid->global_log_format = "kaboo";
1628 
1629  SCLogInitLogModule(sc_lid);
1630 
1631  FAIL_IF_NULL(sc_log_config);
1632 
1633  FAIL_IF_NOT(SC_LOG_DEBUG == sc_log_config->log_level);
1634  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1635  SC_LOG_OP_IFACE_CONSOLE == sc_log_config->op_ifaces->iface);
1636  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1637  sc_log_config->op_ifaces->next == NULL);
1638  FAIL_IF_NOT(sc_log_config->log_format != NULL &&
1639  strcmp("kaboo", sc_log_config->log_format) == 0);
1640  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1641  sc_log_config->op_ifaces->log_format == NULL);
1642  FAIL_IF_NOT(sc_log_config->op_ifaces != NULL &&
1643  sc_log_config->op_ifaces->next == NULL);
1644 
1645  SCLogFreeLogInitData(sc_lid);
1647  SCFree(logfile);
1648 #endif
1649  PASS;
1650 }
1651 
1652 static int SCLogTestInit03(void)
1653 {
1654  SCLogInitLogModule(NULL);
1655 
1656  SCLogAddFGFilterBL(NULL, "bamboo", -1);
1657  SCLogAddFGFilterBL(NULL, "soo", -1);
1658  SCLogAddFGFilterBL(NULL, "dummy", -1);
1659 
1661 
1662  SCLogAddFGFilterBL(NULL, "dummy1", -1);
1663  SCLogAddFGFilterBL(NULL, "dummy2", -1);
1664 
1666 
1668 
1669  PASS;
1670 }
1671 
1672 static int SCLogTestInit04(void)
1673 {
1674  SCLogInitLogModule(NULL);
1675 
1676  SCLogAddFDFilter("bamboo");
1677  SCLogAddFDFilter("soo");
1678  SCLogAddFDFilter("foo");
1679  SCLogAddFDFilter("roo");
1680 
1682 
1683  SCLogAddFDFilter("loo");
1684  SCLogAddFDFilter("soo");
1685 
1687 
1688  SCLogRemoveFDFilter("bamboo");
1689  SCLogRemoveFDFilter("soo");
1690  SCLogRemoveFDFilter("foo");
1691  SCLogRemoveFDFilter("noo");
1692 
1694 
1696 
1697  PASS;
1698 }
1699 
1700 static int SCLogTestInit05(void)
1701 {
1702  char str[4096];
1703  memset(str, 'A', sizeof(str));
1704  SCLogInfo("%s", str);
1705 
1706  PASS;
1707 }
1708 
1709 #endif /* UNITTESTS */
1710 
1712 {
1713 
1714 #ifdef UNITTESTS
1715 
1716  UtRegisterTest("SCLogTestInit01", SCLogTestInit01);
1717  UtRegisterTest("SCLogTestInit02", SCLogTestInit02);
1718  UtRegisterTest("SCLogTestInit03", SCLogTestInit03);
1719  UtRegisterTest("SCLogTestInit04", SCLogTestInit04);
1720  UtRegisterTest("SCLogTestInit05", SCLogTestInit05);
1721 
1722 #endif /* UNITTESTS */
1723 
1724  return;
1725 }
SC_LOG_DEF_LOG_FORMAT_REL
#define SC_LOG_DEF_LOG_FORMAT_REL
Definition: util-debug.h:82
tm-threads.h
SC_LOG_DEF_SYSLOG_FACILITY
#define SC_LOG_DEF_SYSLOG_FACILITY
Definition: util-debug.h:102
SCLogConfig_::op_ifaces
SCLogOPIfaceCtx * op_ifaces
Definition: util-debug.h:183
SCLogMatchFGFilterBL
int SCLogMatchFGFilterBL(const char *file, const char *function, int line)
Checks if there is a match for the incoming log_message with any of the FG filters....
Definition: util-debug-filters.c:309
SC_LOG_DEF_SYSLOG_FACILITY_STR
#define SC_LOG_DEF_SYSLOG_FACILITY_STR
Definition: util-debug.h:101
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
SCLogConfig_::op_filter_regex_match
pcre2_match_data * op_filter_regex_match
Definition: util-debug.h:180
SC_ERR_MISSING_CONFIG_PARAM
@ SC_ERR_MISSING_CONFIG_PARAM
Definition: util-error.h:148
SCLogInitLogModule
void SCLogInitLogModule(SCLogInitData *sc_lid)
Initializes the logging module.
Definition: util-debug.c:1294
syslog
#define syslog(__pri, __fmt, __param)
Definition: win32-syslog.h:78
SCLogOPIfaceCtx_::log_level
SCLogLevel log_level
Definition: util-debug.h:135
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:666
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
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:1508
packet-queue.h
LOG_DEBUG
#define LOG_DEBUG
Definition: win32-syslog.h:46
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:253
sc_log_module_initialized
int sc_log_module_initialized
Used to indicate whether the logging module has been init or not.
Definition: util-debug.c:100
SC_LOG_NOTICE
@ SC_LOG_NOTICE
Definition: util-debug.h:58
SCMutexLock
#define SCMutexLock(mut)
Definition: threads-debug.h:117
SC_LOG_DEF_LOG_OP_IFACE
#define SC_LOG_DEF_LOG_OP_IFACE
Definition: util-debug.h:95
rust.h
SCLogOPIfaceCtx_::log_format
const char * log_format
Definition: util-debug.h:138
SCLogInitData_
Structure containing init data, that would be passed to SCInitDebugModule()
Definition: util-debug.h:150
JSON_ESCAPE_SLASH
#define JSON_ESCAPE_SLASH
Definition: suricata-common.h:262
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:376
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
SCLogOPIfaceCtx_::type
SCLogOPType type
Definition: util-debug.h:121
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 evaluates to false.
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:603
closelog
#define closelog()
Definition: win32-syslog.h:75
t_thread_name
thread_local char t_thread_name[THREAD_NAME_LEN+1]
Definition: threads.c:33
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
SCLogReleaseFGFilters
void SCLogReleaseFGFilters(void)
Definition: util-debug-filters.c:356
SCLogOPIfaceCtx_
The output interface context for the logging module.
Definition: util-debug.h:117
OutputRegisterFileRotationFlag
void OutputRegisterFileRotationFlag(int *flag)
Register a flag for file rotation notification.
Definition: output.c:833
ConfGet
int ConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition: conf.c:330
SC_LOG_INFO
@ SC_LOG_INFO
Definition: util-debug.h:59
SC_LOG_ERROR
@ SC_LOG_ERROR
Definition: util-debug.h:56
SC_LOG_ENV_LOG_LEVEL
#define SC_LOG_ENV_LOG_LEVEL
ENV vars that can be used to set the properties for the logging module.
Definition: util-debug.h:38
decode.h
util-debug.h
type
uint8_t type
Definition: decode-icmpv4.h:0
SCLogReleaseFDFilters
void SCLogReleaseFDFilters(void)
Releases all the FD filters added to the logging module.
Definition: util-debug-filters.c:722
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
util-error.h
SCLogPrintFGFilters
int SCLogPrintFGFilters()
Prints the FG filters(both WL and BL). Used for debugging purposes.
Definition: util-debug-filters.c:408
SCLogConfig_::op_filter_regex
pcre2_code * op_filter_regex
Definition: util-debug.h:179
SCLogOPIfaceCtx_::use_color
int16_t use_color
Definition: util-debug.h:120
SCSyslogGetFacilityMap
SCEnumCharMap * SCSyslogGetFacilityMap(void)
returns the syslog facility enum map
Definition: util-syslog.c:57
SCMutexUnlock
#define SCMutexUnlock(mut)
Definition: threads-debug.h:119
SCLogInitOPIfaceCtx
SCLogOPIfaceCtx * SCLogInitOPIfaceCtx(const char *iface_name, const char *log_format, int log_level, const char *arg)
Creates a new output interface based on the arguments sent. The kind of output interface to be create...
Definition: util-debug.c:1254
SCLogRegisterTests
void SCLogRegisterTests()
Definition: util-debug.c:1711
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
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:1119
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:281
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:271
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:526
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:260
sc_log_op_iface_map
SCEnumCharMap sc_log_op_iface_map[]
Definition: util-debug.c:68
SC_LOG_ALERT
@ SC_LOG_ALERT
Definition: util-debug.h:54
ConfNodeLookupChild
ConfNode * ConfNodeLookupChild(const ConfNode *node, const char *name)
Lookup a child configuration node by name.
Definition: conf.c:814
tm-queuehandlers.h
SC_LOG_CRITICAL
@ SC_LOG_CRITICAL
Definition: util-debug.h:55
SCMapEnumValueToName
const char * SCMapEnumValueToName(int enum_value, SCEnumCharMap *table)
Maps an enum value to a string name, from the supplied table.
Definition: util-enum.c:68
SCLogPrintFDFilters
int SCLogPrintFDFilters(void)
Prints the FG filters(both WL and BL). Used for debugging purposes.
Definition: util-debug-filters.c:811
SCMapEnumNameToValue
int SCMapEnumNameToValue(const char *enum_name, SCEnumCharMap *table)
Maps a string name to an enum value from the supplied table. Please specify the last element of any m...
Definition: util-enum.c:40
suricata-common.h
tm-queues.h
SC_LOG_DEF_LOG_LEVEL
#define SC_LOG_DEF_LOG_LEVEL
Definition: util-debug.h:92
SCEnumCharMap_
Definition: util-enum.h:27
SC_LOG_ENV_LOG_OP_FILTER
#define SC_LOG_ENV_LOG_OP_FILTER
Definition: util-debug.h:43
SCLogConfig_::log_format
char * log_format
Definition: util-debug.h:175
ConfNode_::name
char * name
Definition: conf.h:33
SCLogOPIfaceCtx_::next
struct SCLogOPIfaceCtx_ * next
Definition: util-debug.h:143
SCError
SCError
Definition: util-error.h:29
SC_LOG_ENV_LOG_FORMAT
#define SC_LOG_ENV_LOG_FORMAT
Definition: util-debug.h:42
PathIsAbsolute
int PathIsAbsolute(const char *path)
Check if a path is absolute.
Definition: util-path.c:45
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
SC_LOG_PERF
@ SC_LOG_PERF
Definition: util-debug.h:60
SCLogConfig_
Holds the config state used by the logging api.
Definition: util-debug.h:172
SCLogInitData_::op_ifaces_cnt
uint8_t op_ifaces_cnt
Definition: util-debug.h:166
SCLogOPIfaceCtx_::rotation_flag
int rotation_flag
Definition: util-debug.h:129
SC_LOG_DEF_LOG_FORMAT_DEV
#define SC_LOG_DEF_LOG_FORMAT_DEV
Definition: util-debug.h:83
sc_log_fd_filters_present
int sc_log_fd_filters_present
Definition: util-debug-filters.c:36
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
FatalError
#define FatalError(x,...)
Definition: util-debug.h:532
LOG_WARNING
#define LOG_WARNING
Definition: win32-syslog.h:43
SCLogErr
void SCLogErr(int x, const char *file, const char *func, const int line, const int err, const char *fmt,...)
Definition: util-debug.c:622
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:1146
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:272
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
SCLogLoadConfig
void SCLogLoadConfig(int daemon, int verbose, uint32_t userid, uint32_t groupid)
Definition: util-debug.c:1327
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:1209
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
msg
const char * msg
Definition: app-layer-htp.c:562
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:966
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:647
SC_WARN_CHOWN
@ SC_WARN_CHOWN
Definition: util-error.h:379
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