feature: add JsonSockLogLevel directive for configurable log levels

- New directive: JsonSockLogLevel (DEBUG, INFO, WARNING, ERROR, EMERG)
- Default level: WARNING
- Controls verbosity of module logs in Apache error_log
- DEBUG: Log header skipping, buffer truncation, size limits
- Updates conf/mod_reqin_log.conf with example configuration

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
Jacquin Antoine
2026-03-01 02:31:16 +01:00
parent c61774f8ec
commit 3d2e4f8e70
3 changed files with 67 additions and 8 deletions

View File

@ -27,3 +27,11 @@ JsonSockLogReconnectInterval 10
# Minimum delay between error messages to Apache error_log (seconds) # Minimum delay between error messages to Apache error_log (seconds)
JsonSockLogErrorReportInterval 10 JsonSockLogErrorReportInterval 10
# Log level for module messages: DEBUG, INFO, WARNING, ERROR, EMERG (default: WARNING)
# DEBUG: Log all messages including header skipping and buffer truncation
# INFO: Log informational messages
# WARNING: Log warnings (default)
# ERROR: Log only errors
# EMERG: Log only emergency messages
JsonSockLogLevel WARNING

View File

@ -40,6 +40,7 @@ install -m 644 %{_pkgroot}/%{_sysconfdir}/httpd/conf.d/mod_reqin_log.conf %{buil
* Sun Mar 01 2026 Developer <dev@example.com> - 1.0.6 * Sun Mar 01 2026 Developer <dev@example.com> - 1.0.6
- CONF: Change default socket path to /var/run/logcorrelator/http.socket - CONF: Change default socket path to /var/run/logcorrelator/http.socket
- BUILD: Allow Docker cache for RPM builds (remove --no-cache flag) - BUILD: Allow Docker cache for RPM builds (remove --no-cache flag)
- FEATURE: Add JsonSockLogLevel directive (DEBUG, INFO, WARNING, ERROR, EMERG)
* Sun Mar 01 2026 Developer <dev@example.com> - 1.0.4 * Sun Mar 01 2026 Developer <dev@example.com> - 1.0.4
- BUILD: Fix RPM package paths in Dockerfile.package (el8, el9, el10 directories) - BUILD: Fix RPM package paths in Dockerfile.package (el8, el9, el10 directories)

View File

@ -54,6 +54,9 @@
} \ } \
} while(0) } while(0)
/* Helper macro to check if a log level should be emitted */
#define SHOULD_LOG(srv_conf, level) ((srv_conf) && (srv_conf)->log_level <= (level))
/* Default sensitive headers blacklist - prevents accidental logging of credentials */ /* Default sensitive headers blacklist - prevents accidental logging of credentials */
static const char *const DEFAULT_SENSITIVE_HEADERS[] = { static const char *const DEFAULT_SENSITIVE_HEADERS[] = {
"Authorization", "Authorization",
@ -84,10 +87,20 @@ typedef struct {
int connect_failed; int connect_failed;
} reqin_log_child_state_t; } reqin_log_child_state_t;
/* Log levels */
typedef enum {
REQIN_LOG_LEVEL_DEBUG = 0,
REQIN_LOG_LEVEL_INFO = 1,
REQIN_LOG_LEVEL_WARNING = 2,
REQIN_LOG_LEVEL_ERROR = 3,
REQIN_LOG_LEVEL_EMERG = 4
} reqin_log_level_t;
/* Module server configuration structure */ /* Module server configuration structure */
typedef struct { typedef struct {
reqin_log_config_t *config; reqin_log_config_t *config;
reqin_log_child_state_t child_state; reqin_log_child_state_t child_state;
reqin_log_level_t log_level;
} reqin_log_server_conf_t; } reqin_log_server_conf_t;
/* Forward declarations for helper functions */ /* Forward declarations for helper functions */
@ -107,6 +120,7 @@ static const char *cmd_set_max_headers(cmd_parms *cmd, void *dummy, const char *
static const char *cmd_set_max_header_value_len(cmd_parms *cmd, void *dummy, const char *arg); static const char *cmd_set_max_header_value_len(cmd_parms *cmd, void *dummy, const char *arg);
static const char *cmd_set_reconnect_interval(cmd_parms *cmd, void *dummy, const char *arg); static const char *cmd_set_reconnect_interval(cmd_parms *cmd, void *dummy, const char *arg);
static const char *cmd_set_error_report_interval(cmd_parms *cmd, void *dummy, const char *arg); static const char *cmd_set_error_report_interval(cmd_parms *cmd, void *dummy, const char *arg);
static const char *cmd_set_log_level(cmd_parms *cmd, void *dummy, const char *arg);
/* Forward declarations for hooks */ /* Forward declarations for hooks */
static int reqin_log_post_read_request(request_rec *r); static int reqin_log_post_read_request(request_rec *r);
@ -130,6 +144,8 @@ static const command_rec reqin_log_cmds[] = {
"Reconnect interval in seconds (default: 10)"), "Reconnect interval in seconds (default: 10)"),
AP_INIT_TAKE1("JsonSockLogErrorReportInterval", cmd_set_error_report_interval, NULL, RSRC_CONF, AP_INIT_TAKE1("JsonSockLogErrorReportInterval", cmd_set_error_report_interval, NULL, RSRC_CONF,
"Error report interval in seconds (default: 10)"), "Error report interval in seconds (default: 10)"),
AP_INIT_TAKE1("JsonSockLogLevel", cmd_set_log_level, NULL, RSRC_CONF,
"Log level: DEBUG, INFO, WARNING, ERROR, EMERG (default: WARNING)"),
{ NULL } { NULL }
}; };
@ -170,6 +186,8 @@ static void *reqin_log_create_server_conf(apr_pool_t *pool, server_rec *s)
srv_conf->child_state.last_error_report = 0; srv_conf->child_state.last_error_report = 0;
srv_conf->child_state.connect_failed = 0; srv_conf->child_state.connect_failed = 0;
srv_conf->log_level = REQIN_LOG_LEVEL_WARNING;
return srv_conf; return srv_conf;
} }
@ -413,6 +431,32 @@ static const char *cmd_set_error_report_interval(cmd_parms *cmd, void *dummy, co
return NULL; return NULL;
} }
static const char *cmd_set_log_level(cmd_parms *cmd, void *dummy, const char *arg)
{
(void)dummy;
reqin_log_server_conf_t *srv_conf = get_server_conf(cmd->server);
if (srv_conf == NULL) {
return "Internal error: server configuration not available";
}
if (arg == NULL || arg[0] == '\0') {
return "JsonSockLogLevel must be a non-empty string";
}
if (strcasecmp(arg, "DEBUG") == 0) {
srv_conf->log_level = REQIN_LOG_LEVEL_DEBUG;
} else if (strcasecmp(arg, "INFO") == 0) {
srv_conf->log_level = REQIN_LOG_LEVEL_INFO;
} else if (strcasecmp(arg, "WARNING") == 0) {
srv_conf->log_level = REQIN_LOG_LEVEL_WARNING;
} else if (strcasecmp(arg, "ERROR") == 0) {
srv_conf->log_level = REQIN_LOG_LEVEL_ERROR;
} else if (strcasecmp(arg, "EMERG") == 0) {
srv_conf->log_level = REQIN_LOG_LEVEL_EMERG;
} else {
return "JsonSockLogLevel must be one of: DEBUG, INFO, WARNING, ERROR, EMERG";
}
return NULL;
}
/* ============== Socket Functions ============== */ /* ============== Socket Functions ============== */
/** /**
@ -612,7 +656,7 @@ static const char *get_header(request_rec *r, const char *name)
return NULL; return NULL;
} }
static void log_request(request_rec *r, reqin_log_config_t *cfg, reqin_log_child_state_t *state) static void log_request(request_rec *r, reqin_log_config_t *cfg, reqin_log_child_state_t *state, reqin_log_server_conf_t *srv_conf)
{ {
apr_pool_t *pool; apr_pool_t *pool;
server_rec *s; server_rec *s;
@ -736,8 +780,10 @@ static void log_request(request_rec *r, reqin_log_config_t *cfg, reqin_log_child
/* Check buffer size before adding headers to prevent memory exhaustion */ /* Check buffer size before adding headers to prevent memory exhaustion */
if (buf.len >= MAX_JSON_SIZE) { if (buf.len >= MAX_JSON_SIZE) {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, if (SHOULD_LOG(srv_conf, REQIN_LOG_LEVEL_DEBUG)) {
MOD_REQIN_LOG_NAME ": JSON buffer size limit reached before headers"); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
MOD_REQIN_LOG_NAME ": JSON buffer size limit reached before headers");
}
return; return;
} }
@ -753,8 +799,10 @@ static void log_request(request_rec *r, reqin_log_config_t *cfg, reqin_log_child
/* Skip sensitive headers to prevent credential leakage */ /* Skip sensitive headers to prevent credential leakage */
if (is_sensitive_header(header_name)) { if (is_sensitive_header(header_name)) {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, if (SHOULD_LOG(srv_conf, REQIN_LOG_LEVEL_DEBUG)) {
MOD_REQIN_LOG_NAME ": Skipping sensitive header: %s", header_name); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
MOD_REQIN_LOG_NAME ": Skipping sensitive header: %s", header_name);
}
continue; continue;
} }
@ -766,8 +814,10 @@ static void log_request(request_rec *r, reqin_log_config_t *cfg, reqin_log_child
char *truncated; char *truncated;
if (buf.len + header_contrib >= MAX_JSON_SIZE) { if (buf.len + header_contrib >= MAX_JSON_SIZE) {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, if (SHOULD_LOG(srv_conf, REQIN_LOG_LEVEL_DEBUG)) {
MOD_REQIN_LOG_NAME ": JSON size limit reached, truncating headers"); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
MOD_REQIN_LOG_NAME ": JSON size limit reached, truncating headers");
}
break; break;
} }
@ -824,7 +874,7 @@ static int reqin_log_post_read_request(request_rec *r)
return DECLINED; return DECLINED;
} }
log_request(r, srv_conf->config, &srv_conf->child_state); log_request(r, srv_conf->config, &srv_conf->child_state, srv_conf);
return DECLINED; return DECLINED;
} }