(percent space) is a zero-witdh field delimiter that does not produce any
output.</p>
- <p>The above behaviour can be changed by adding flags to the format string
- item. A <code>-</code> (minus) flag causes a minus to be logged if the
+ <p>The above behaviour can be changed by adding modifiers to the format
+ string item. A <code>-</code> (minus) modifier causes a minus to be logged if the
respective item does not produce any output. In once-per-connection/request
- formats, it is also possible to use the <code>+</code> (plus) flag. If an
- item with the plus flag does not produce any output, the whole line is
+ formats, it is also possible to use the <code>+</code> (plus) modifier. If an
+ item with the plus modifier does not produce any output, the whole line is
ommitted.</p>
+ <p>A number as modifier can be used to assign a log severity level to a
+ format item. The item will only be logged if the severity of the log
+ message is not higher than the specified log severity level. The number can
+ range from 1 (alert) over 4 (warn) and 7 (debug) to 15 (trace8).</p>
+
<p>Some format string items accept additional parameters in braces.</p>
<table border="1" style="zebra">
with error log lines.</p>
<example><title>Example (somewhat similar to default format)</title>
- ErrorLogFormat "[%{u}t] [%-m:%l] [pid %P] %F: %E: [client\ %a]
+ ErrorLogFormat "[%{u}t] [%-m:%l] [pid %P] %7F: %E: [client\ %a]
%M% ,\ referer\ %{Referer}i"
</example>
<example><title>Example (similar to the 2.2.x format)</title>
- ErrorLogFormat "[%t] [%l] %F: %E: [client\ %a]
+ ErrorLogFormat "[%t] [%l] %7F: %E: [client\ %a]
%M% ,\ referer\ %{Referer}i"
</example>
<example><title>Advanced example with request/connection log IDs</title>
- ErrorLogFormat "[%{uc}t] [%-m:%-l] [R:%L] [C:%{C}L] %M"<br/>
+ ErrorLogFormat "[%{uc}t] [%-m:%-l] [R:%L] [C:%{C}L] %7F: %E: %M"<br/>
ErrorLogFormat request "[%{uc}t] [R:%L] Request %k on C:%{c}L pid:%P tid:%T"<br/>
ErrorLogFormat request "[%{uc}t] [R:%L] UA:'%+{User-Agent}i'"<br/>
ErrorLogFormat request "[%{uc}t] [R:%L] Referer:'%+{Referer}i'"<br/>
typedef struct {
ap_errorlog_handler_fn_t *func;
const char *arg;
-#define AP_ERRORLOG_FLAG_FIELD_SEP 1
-#define AP_ERRORLOG_FLAG_MESSAGE 2
-#define AP_ERRORLOG_FLAG_REQUIRED 4
-#define AP_ERRORLOG_FLAG_NULL_AS_HYPHEN 8
+#define AP_ERRORLOG_FLAG_FIELD_SEP 1 /* item starts a new field */
+#define AP_ERRORLOG_FLAG_MESSAGE 2 /* item is the actual error message */
+#define AP_ERRORLOG_FLAG_REQUIRED 4 /* skip whole line if item is zero-length */
+#define AP_ERRORLOG_FLAG_NULL_AS_HYPHEN 8 /* log zero-length item as '-' */
unsigned int flags;
+ unsigned int min_loglevel; /* only log if level is higher than this */
} ap_errorlog_format_item;
AP_DECLARE(void) ap_register_builtin_errorlog_handlers(apr_pool_t *p);
{
const char *s = *sa;
ap_errorlog_handler *handler;
+ int i;
if (*s != '%') {
if (*s == ' ') {
++s;
it->flags |= AP_ERRORLOG_FLAG_NULL_AS_HYPHEN;
break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ i = *s - '0';
+ while (apr_isdigit(*++s))
+ i = i * 10 + (*s) - '0';
+ it->min_loglevel = i;
+ break;
case 'M':
it->func = NULL;
it->flags |= AP_ERRORLOG_FLAG_MESSAGE;
static apr_array_header_t *parse_errorlog_string(apr_pool_t *p,
const char *s,
const char **err,
- int want_msg_fmt)
+ int is_main_fmt)
{
apr_array_header_t *a = apr_array_make(p, 30,
sizeof(ap_errorlog_format_item));
return NULL;
}
if (item->flags & AP_ERRORLOG_FLAG_MESSAGE) {
- if (!want_msg_fmt) {
+ if (!is_main_fmt) {
*err = "%M cannot be used in once-per-request or "
"once-per-connection formats";
return NULL;
}
seen_msg_fmt = 1;
}
- if (want_msg_fmt && item->flags & AP_ERRORLOG_FLAG_REQUIRED) {
+ if (is_main_fmt && item->flags & AP_ERRORLOG_FLAG_REQUIRED) {
*err = "The '+' flag cannot be used in the main error log format";
return NULL;
}
+ if (!is_main_fmt && item->min_loglevel) {
+ *err = "The loglevel cannot be used as a condition in "
+ "once-per-request or once-per-connection formats";
+ return NULL;
+ }
+ if (item->min_loglevel > APLOG_TRACE8) {
+ *err = "The specified loglevel modifier is out of range";
+ return NULL;
+ }
}
- if (want_msg_fmt && !seen_msg_fmt) {
+ if (is_main_fmt && !seen_msg_fmt) {
*err = "main ErrorLogFormat must contain message format string '%M'";
return NULL;
}
else if (skipping) {
continue;
}
+ else if (item->min_loglevel > info->level) {
+ len = field_start;
+ skipping = 1;
+ }
else {
int item_len = (*item->func)(info, item->arg, buf + len,
buflen - len);