-/* Copyright (C) 2007-2020 Open Information Security Foundation
+/* Copyright (C) 2007-2021 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
static SCMutex sc_log_stream_lock;
#endif /* OS_WIN32 */
+/**
+ * \brief Transform the module name into display module name for logging
+ */
+static const char *SCTransformModule(const char *module_name, int *dn_len);
+
/**
* \brief Holds the config state for the logging module
*/
*/
static int SCLogMessageJSON(struct timeval *tval, char *buffer, size_t buffer_size,
SCLogLevel log_level, const char *file, unsigned line, const char *function,
- const char *message)
+ const char *module, const char *message)
{
json_t *js = json_object();
if (unlikely(js == NULL))
if (message)
json_object_set_new(ejs, "message", json_string(message));
+ if (t_thread_name[0] != '\0') {
+ json_object_set_new(ejs, "thread_name", json_string(t_thread_name));
+ }
+
+ if (module) {
+ /* Determine how much of module name to display */
+ int dn_len = 0;
+ const char *dn_name;
+ dn_name = SCTransformModule(module, &dn_len);
+ json_object_set_new(ejs, "module", json_string(dn_name));
+ }
+
if (log_level >= SC_LOG_DEBUG) {
if (function)
json_object_set_new(ejs, "function", json_string(function));
return -1;
}
+static const int transform_max_segs = 2; /* The maximum segment count to display */
+/*
+ * \brief Return a display name for the given module name for logging.
+ *
+ * The transformation is dependent upon the source code module names
+ * that use the dash character to separate incremental refinements of
+ * the subsystem.
+ *
+ * The transformation uses the local constant "transform_max_segs" to determine
+ * how many segments to display; the transformed name will never consist
+ * of more than this many segments.
+ *
+ * E.g., "detect-http-content-len" ==> "detect-http" when the max is 2
+ *
+ * \param module_name The source code module name to be transformed.
+ * \param dn_len The number of characters in the display name to print.
+ *
+ * \retval Pointer to the display name
+ */
+static const char *SCTransformModule(const char *module_name, int *dn_len)
+{
+ /*
+ * special case for source code module names beginning with:
+ * Prefixes skipped
+ * tm-*
+ * util-*
+ * source-*
+ * No transformation
+ * app-layer-*
+ */
+ if (strncmp("tm-", module_name, 3) == 0) {
+ *dn_len = strlen(module_name) - 3;
+ return module_name + 3;
+ } else if (strncmp("util-", module_name, 5) == 0) {
+ *dn_len = strlen(module_name) - 5;
+ return module_name + 5;
+ } else if (strncmp("source-", module_name, 7) == 0) {
+ *dn_len = strlen(module_name) - 7;
+ return module_name + 7;
+ } else if (strncmp("app-layer-", module_name, 10) == 0) {
+ *dn_len = strlen(module_name);
+ return module_name;
+ }
+
+ int seg_cnt = 0;
+
+ char *last;
+ char *w = (char *)module_name;
+ while (w && (w = strchr(w, '-')) != NULL && seg_cnt < transform_max_segs) {
+ seg_cnt++;
+ last = w;
+ w++; /* skip past '-' */
+ }
+
+ if (seg_cnt < transform_max_segs)
+ *dn_len = strlen(module_name);
+ else
+ *dn_len = last - module_name;
+
+ return module_name;
+}
+
/**
* \brief Adds the global log_format to the outgoing buffer
*
* \retval 0 on success; else a negative value on error
*/
static SCError SCLogMessageGetBuffer(struct timeval *tval, int color, SCLogOPType type,
- char *buffer, size_t buffer_size, const char *log_format,
-
- const SCLogLevel log_level, const char *file, const unsigned int line, const char *function,
+ char *buffer, size_t buffer_size, const char *log_format, const SCLogLevel log_level,
+ const char *file, const unsigned int line, const char *function, const char *module,
const char *message)
{
if (type == SC_LOG_OP_TYPE_JSON)
return SCLogMessageJSON(
- tval, buffer, buffer_size, log_level, file, line, function, message);
+ tval, buffer, buffer_size, log_level, file, line, function, module, message);
char *temp = buffer;
const char *s = NULL;
substr++;
break;
+ case SC_LOG_FMT_THREAD_NAME:
case SC_LOG_FMT_TM:
temp_fmt[0] = '\0';
cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), "%s%s%s%s", substr,
substr++;
break;
+ case SC_LOG_FMT_SUBSYSTEM:
+ temp_fmt[0] = '\0';
+
+ /* Determine how much of module name to display */
+ int dn_len = 0;
+ const char *dn_name = "unknown";
+ if (module) {
+ dn_name = SCTransformModule(module, &dn_len);
+ }
+
+ cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), "%s%s%s%s", substr,
+ green, dn_name, reset);
+ if (cw < 0)
+ return -1;
+ temp += cw;
+ temp_fmt++;
+ substr = temp_fmt;
+ substr++;
+ break;
+
case SC_LOG_FMT_FUNCTION:
temp_fmt[0] = '\0';
cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer),
substr = temp_fmt;
substr++;
break;
-
}
temp_fmt++;
}
* \retval SC_OK on success; else an error code
*/
SCError SCLogMessage(const SCLogLevel log_level, const char *file, const unsigned int line,
- const char *function, const char *message)
+ const char *function, const char *module, const char *message)
{
char buffer[SC_LOG_MAX_LOG_MSG_LEN] = "";
SCLogOPIfaceCtx *op_iface_ctx = NULL;
buffer, sizeof(buffer),
op_iface_ctx->log_format ? op_iface_ctx->log_format
: sc_log_config->log_format,
- log_level, file, line, function, message) == 0) {
+ log_level, file, line, function, module, message) == 0) {
SCLogPrintToStream((log_level == SC_LOG_ERROR)? stderr: stdout, buffer);
}
break;
if (SCLogMessageGetBuffer(&tval, 0, op_iface_ctx->type, buffer, sizeof(buffer),
op_iface_ctx->log_format ? op_iface_ctx->log_format
: sc_log_config->log_format,
- log_level, file, line, function, message) == 0) {
+ log_level, file, line, function, module, message) == 0) {
int r = 0;
SCMutexLock(&op_iface_ctx->fp_mutex);
if (op_iface_ctx->rotation_flag) {
if (SCLogMessageGetBuffer(&tval, 0, op_iface_ctx->type, buffer, sizeof(buffer),
op_iface_ctx->log_format ? op_iface_ctx->log_format
: sc_log_config->log_format,
- log_level, file, line, function, message) == 0) {
+ log_level, file, line, function, module, message) == 0) {
SCLogPrintToSyslog(SCLogMapLogLevelToSyslogLevel(log_level), buffer);
}
break;
return SC_OK;
}
-void SCLog(int x, const char *file, const char *func, const int line,
+void SCLog(int x, const char *file, const char *func, const int line, const char *module,
const char *fmt, ...)
{
if (sc_log_global_log_level >= x &&
va_start(ap, fmt);
vsnprintf(msg, sizeof(msg), fmt, ap);
va_end(ap);
- SCLogMessage(x, file, line, func, msg);
+ SCLogMessage(x, file, line, func, module, msg);
}
}
-void SCLogErr(int x, const char *file, const char *func, const int line, const char *fmt, ...)
+void SCLogErr(int x, const char *file, const char *func, const int line, const char *module,
+ const char *fmt, ...)
{
if (sc_log_global_log_level >= x &&
(sc_log_fg_filters_present == 0 ||
va_start(ap, fmt);
vsnprintf(msg, sizeof(msg), fmt, ap);
va_end(ap);
- SCLogMessage(x, file, line, func, msg);
+ SCLogMessage(x, file, line, func, module, msg);
}
}
} SCLogOPType;
/* The default log_format, if it is not supplied by the user */
-#define SC_LOG_DEF_LOG_FORMAT_REL "%t - <%d> - "
-#define SC_LOG_DEF_LOG_FORMAT_DEV "[%i] %t - (%f:%l) <%d> (%n) -- "
+#define SC_LOG_DEF_LOG_FORMAT_REL "%t [%S] - <%d> - "
+#ifdef DEBUG
+#define SC_LOG_DEF_LOG_FORMAT_DEV "[%i] %t [%S] - (%f:%l) <%d> (%n) -- %E"
+#else
+#define SC_LOG_DEF_LOG_FORMAT_DEV "[%i] %t [%S] - <%d> -- %E"
+#endif
/* The maximum length of the log message */
#define SC_LOG_MAX_LOG_MSG_LEN 2048
#define SC_LOG_FMT_FILE_NAME 'f' /* File name */
#define SC_LOG_FMT_LINE 'l' /* Line number */
#define SC_LOG_FMT_FUNCTION 'n' /* Function */
+#define SC_LOG_FMT_SUBSYSTEM 'S' /* Subsystem name */
+#define SC_LOG_FMT_THREAD_NAME 'T' /* thread name */
/* The log format prefix for the format specifiers */
#define SC_LOG_FMT_PREFIX '%'
+/* Module and thread tagging */
+/* The module name, usually the containing source-module name */
+static const char *_sc_module __attribute__((unused)) = __SCFILENAME__;
+
extern SCLogLevel sc_log_global_log_level;
extern int sc_log_module_initialized;
extern int sc_log_module_cleaned;
-void SCLog(int x, const char *file, const char *func, const int line,
- const char *fmt, ...) ATTR_FMT_PRINTF(5,6);
-void SCLogErr(int x, const char *file, const char *func, const int line, const char *fmt, ...)
- ATTR_FMT_PRINTF(5, 6);
+void SCLog(int x, const char *file, const char *func, const int line, const char *module,
+ const char *fmt, ...) ATTR_FMT_PRINTF(6, 7);
+void SCLogErr(int x, const char *file, const char *func, const int line, const char *module,
+ const char *fmt, ...) ATTR_FMT_PRINTF(6, 7);
/**
* \brief Macro used to log INFORMATIONAL messages.
*
* \retval ... Takes as argument(s), a printf style format message
*/
-#define SCLogInfo(...) SCLog(SC_LOG_INFO, \
- __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
-#define SCLogInfoRaw(file, func, line, ...) SCLog(SC_LOG_INFO, \
- (file), (func), (line), __VA_ARGS__)
+#define SCLogInfo(...) SCLog(SC_LOG_INFO, __FILE__, __FUNCTION__, __LINE__, _sc_module, __VA_ARGS__)
+#define SCLogInfoRaw(file, func, line, ...) \
+ SCLog(SC_LOG_INFO, (file), (func), (line), _sc_module, __VA_ARGS__)
-#define SCLogConfig(...) SCLog(SC_LOG_CONFIG, \
- __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
-#define SCLogPerf(...) SCLog(SC_LOG_PERF, \
- __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
+#define SCLogConfig(...) \
+ SCLog(SC_LOG_CONFIG, __FILE__, __FUNCTION__, __LINE__, _sc_module, __VA_ARGS__)
+#define SCLogPerf(...) SCLog(SC_LOG_PERF, __FILE__, __FUNCTION__, __LINE__, _sc_module, __VA_ARGS__)
/**
* \brief Macro used to log NOTICE messages.
*
* \retval ... Takes as argument(s), a printf style format message
*/
-#define SCLogNotice(...) SCLog(SC_LOG_NOTICE, \
- __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
-#define SCLogNoticeRaw(file, func, line, ... ) SCLog(SC_LOG_NOTICE, \
- (file), (func), (line), __VA_ARGS__)
+#define SCLogNotice(...) \
+ SCLog(SC_LOG_NOTICE, __FILE__, __FUNCTION__, __LINE__, _sc_module, __VA_ARGS__)
+#define SCLogNoticeRaw(file, func, line, ...) \
+ SCLog(SC_LOG_NOTICE, (file), (func), (line), _sc_module, __VA_ARGS__)
/**
* \brief Macro used to log WARNING messages.
* warning message
* \retval ... Takes as argument(s), a printf style format message
*/
-#define SCLogWarning(...) SCLogErr(SC_LOG_WARNING, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
+#define SCLogWarning(...) \
+ SCLogErr(SC_LOG_WARNING, __FILE__, __FUNCTION__, __LINE__, _sc_module, __VA_ARGS__)
#define SCLogWarningRaw(file, func, line, ...) \
- SCLogErr(SC_LOG_WARNING, (file), (func), (line), __VA_ARGS__)
+ SCLogErr(SC_LOG_WARNING, (file), (func), (line), _sc_module, __VA_ARGS__)
/**
* \brief Macro used to log ERROR messages.
* error message
* \retval ... Takes as argument(s), a printf style format message
*/
-#define SCLogError(...) SCLogErr(SC_LOG_ERROR, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
+#define SCLogError(...) \
+ SCLogErr(SC_LOG_ERROR, __FILE__, __FUNCTION__, __LINE__, _sc_module, __VA_ARGS__)
#define SCLogErrorRaw(file, func, line, ...) \
- SCLogErr(SC_LOG_ERROR, (file), (func), (line), __VA_ARGS__)
+ SCLogErr(SC_LOG_ERROR, (file), (func), (line), _sc_module, __VA_ARGS__)
/**
* \brief Macro used to log CRITICAL messages.
* critical message
* \retval ... Takes as argument(s), a printf style format message
*/
-#define SCLogCritical(...) SCLogErr(SC_LOG_CRITICAL, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
+#define SCLogCritical(...) \
+ SCLogErr(SC_LOG_CRITICAL, __FILE__, __FUNCTION__, __LINE__, _sc_module, __VA_ARGS__)
/**
* \brief Macro used to log ALERT messages.
*
* alert message
* \retval ... Takes as argument(s), a printf style format message
*/
-#define SCLogAlert(...) SCLogErr(SC_LOG_ALERT, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
+#define SCLogAlert(...) \
+ SCLogErr(SC_LOG_ALERT, __FILE__, __FUNCTION__, __LINE__, _sc_module, __VA_ARGS__)
/**
* \brief Macro used to log EMERGENCY messages.
*
* emergency message
* \retval ... Takes as argument(s), a printf style format message
*/
-#define SCLogEmerg(...) SCLogErr(SC_LOG_EMERGENCY, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
+#define SCLogEmerg(...) \
+ SCLogErr(SC_LOG_EMERGENCY, __FILE__, __FUNCTION__, __LINE__, _sc_module, __VA_ARGS__)
/* Avoid the overhead of using the debugging subsystem, in production mode */
#ifndef DEBUG
*
* \retval ... Takes as argument(s), a printf style format message
*/
-#define SCLogDebug(...) SCLog(SC_LOG_DEBUG, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
+#define SCLogDebug(...) \
+ SCLog(SC_LOG_DEBUG, __FILE__, __FUNCTION__, __LINE__, _sc_module, __VA_ARGS__)
/**
* \brief Macro used to log debug messages on function entry. Comes under the
} \
} while(0)
-
/**
* \brief Macro used to log debug messages on function exit. Comes under the
- * debugging sybsystem, and hence will be enabled only in the presence
+ * debugging subsystem, and hence will be enabled only in the presence
* of the DEBUG macro. Apart from logging function_exit logs, it also
* processes the FD filters, if any FD filters are registered. This
* function_exit macro should be used for functions that don't return
/**
* \brief Macro used to log debug messages on function exit. Comes under the
- * debugging sybsystem, and hence will be enabled only in the presence
+ * debugging subsystem, and hence will be enabled only in the presence
* of the DEBUG macro. Apart from logging function_exit logs, it also
* processes the FD filters, if any FD filters are registered. This
* function_exit macro should be used for functions that returns an
/**
* \brief Macro used to log debug messages on function exit. Comes under the
- * debugging sybsystem, and hence will be enabled only in the presence
+ * debugging subsystem, and hence will be enabled only in the presence
* of the DEBUG macro. Apart from logging function_exit logs, it also
* processes the FD filters, if any FD filters are registered. This
* function_exit macro should be used for functions that returns an
/**
* \brief Macro used to log debug messages on function exit. Comes under the
- * debugging sybsystem, and hence will be enabled only in the presence
+ * debugging subsystem, and hence will be enabled only in the presence
* of the DEBUG macro. Apart from logging function_exit logs, it also
* processes the FD filters, if any FD filters are registered. This
* function_exit macro should be used for functions that returns a
/**
* \brief Macro used to log debug messages on function exit. Comes under the
- * debugging sybsystem, and hence will be enabled only in the presence
+ * debugging subsystem, and hence will be enabled only in the presence
* of the DEBUG macro. Apart from logging function_exit logs, it also
* processes the FD filters, if any FD filters are registered. This
* function_exit macro should be used for functions that returns a var
/**
* \brief Macro used to log debug messages on function exit. Comes under the
- * debugging sybsystem, and hence will be enabled only in the presence
+ * debugging subsystem, and hence will be enabled only in the presence
* of the DEBUG macro. Apart from logging function_exit logs, it also
* processes the FD filters, if any FD filters are registered. This
* function_exit macro should be used for functions that returns a
return x; \
} while(0)
-
/**
* \brief Macro used to log debug messages on function exit. Comes under the
- * debugging sybsystem, and hence will be enabled only in the presence
+ * debugging subsystem, and hence will be enabled only in the presence
* of the DEBUG macro. Apart from logging function_exit logs, it also
* processes the FD filters, if any FD filters are registered. This
* function_exit macro should be used for functions that returns a var
/**
* \brief Macro used to log debug messages on function exit. Comes under the
- * debugging sybsystem, and hence will be enabled only in the presence
+ * debugging subsystem, and hence will be enabled only in the presence
* of the DEBUG macro. Apart from logging function_exit logs, it also
* processes the FD filters, if any FD filters are registered. This
* function_exit macro should be used for functions that returns a
void SCLogDeInitLogModule(void);
-SCError SCLogMessage(
- const SCLogLevel, const char *, const unsigned int, const char *, const char *message);
+SCError SCLogMessage(const SCLogLevel, const char *, const unsigned int, const char *, const char *,
+ const char *message);
SCLogOPBuffer *SCLogAllocLogOPBuffer(void);