minor enhencements; added log.level and log.target options
commit
95fa874571
|
@ -37,6 +37,8 @@ typedef struct connection connection;
|
|||
|
||||
#include "connection.h"
|
||||
|
||||
#include "plugin_core.h"
|
||||
|
||||
#define SERVER_VERSION ((guint) 0x01FF0000)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -509,10 +509,57 @@
|
|||
|
||||
/* create condition lvalue */
|
||||
str = n->value.opt_string->str;
|
||||
if (g_str_equal(str, "req.path") || g_str_equal(str, "request.path"))
|
||||
lvalue = condition_lvalue_new(COMP_REQUEST_PATH, NULL);
|
||||
|
||||
if (g_str_has_prefix(str, "req")) {
|
||||
str += 3;
|
||||
if (g_str_has_prefix(str, "."))
|
||||
str++;
|
||||
else if (g_str_has_prefix(str, "uest."))
|
||||
str += 5;
|
||||
else {
|
||||
log_warning(srv, NULL, "unkown lvalue for condition: %s", n->value.opt_string->str);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (g_str_equal(str, "host"))
|
||||
lvalue = condition_lvalue_new(COMP_REQUEST_HOST, NULL);
|
||||
else if (g_str_equal(str, "path"))
|
||||
lvalue = condition_lvalue_new(COMP_REQUEST_PATH, NULL);
|
||||
else if (g_str_equal(str, "query"))
|
||||
lvalue = condition_lvalue_new(COMP_REQUEST_QUERY_STRING, NULL);
|
||||
else if (g_str_equal(str, "method"))
|
||||
lvalue = condition_lvalue_new(COMP_REQUEST_METHOD, NULL);
|
||||
else if (g_str_equal(str, "scheme"))
|
||||
lvalue = condition_lvalue_new(COMP_REQUEST_SCHEME, NULL);
|
||||
else {
|
||||
log_warning(srv, NULL, "unkown lvalue for condition: %s", n->value.opt_string->str);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (g_str_has_prefix(str, "phys")) {
|
||||
str += 3;
|
||||
if (g_str_has_prefix(str, "."))
|
||||
str++;
|
||||
else if (g_str_has_prefix(str, "ical."))
|
||||
str += 5;
|
||||
else {
|
||||
log_warning(srv, NULL, "unkown lvalue for condition: %s", n->value.opt_string->str);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (g_str_equal(str, "path"))
|
||||
lvalue = condition_lvalue_new(COMP_PHYSICAL_PATH, NULL);
|
||||
else if (g_str_equal(str, "exists"))
|
||||
lvalue = condition_lvalue_new(COMP_PHYSICAL_PATH_EXISTS, NULL);
|
||||
else if (g_str_equal(str, "size"))
|
||||
lvalue = condition_lvalue_new(COMP_PHYSICAL_SIZE, NULL);
|
||||
else {
|
||||
log_warning(srv, NULL, "unkown lvalue for condition: %s", n->value.opt_string->str);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
log_warning(srv, NULL, "unkown lvalue for condition: %s", str);
|
||||
log_warning(srv, NULL, "unkown lvalue for condition: %s", n->value.opt_string->str);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
54
src/log.c
54
src/log.c
|
@ -39,8 +39,8 @@ gboolean log_write_(server *srv, connection *con, log_level_t log_level, const g
|
|||
|
||||
if (con != NULL) {
|
||||
/* get log index from connection */
|
||||
log = con->log;
|
||||
log_level_want = con->log_level;
|
||||
log = CORE_OPTION(CORE_OPTION_LOG_TARGET) ? CORE_OPTION(CORE_OPTION_LOG_TARGET) : srv->log_stderr;
|
||||
log_level_want = (log_level_t) CORE_OPTION(CORE_OPTION_LOG_LEVEL);
|
||||
}
|
||||
else {
|
||||
log = srv->log_stderr;
|
||||
|
@ -202,6 +202,56 @@ void log_unref(server *srv, log_t *log) {
|
|||
g_mutex_unlock(srv->log_mutex);
|
||||
}
|
||||
|
||||
log_type_t log_type_from_path(GString *path) {
|
||||
if (path->len == 0)
|
||||
return LOG_TYPE_STDERR;
|
||||
|
||||
/* targets starting with a slash are absolute paths and therefor file targets */
|
||||
if (*path->str == '/')
|
||||
return LOG_TYPE_FILE;
|
||||
|
||||
/* targets starting with a pipe are ... pipes! */
|
||||
if (*path->str == '|')
|
||||
return LOG_TYPE_PIPE;
|
||||
|
||||
if (g_str_equal(path->str, "stderr"))
|
||||
return LOG_TYPE_STDERR;
|
||||
|
||||
if (g_str_equal(path->str, "syslog"))
|
||||
return LOG_TYPE_SYSLOG;
|
||||
|
||||
/* fall back to stderr */
|
||||
return LOG_TYPE_STDERR;
|
||||
}
|
||||
|
||||
log_level_t log_level_from_string(GString *str) {
|
||||
if (g_str_equal(str->str, "debug"))
|
||||
return LOG_LEVEL_DEBUG;
|
||||
if (g_str_equal(str->str, "info"))
|
||||
return LOG_LEVEL_INFO;
|
||||
if (g_str_equal(str->str, "message"))
|
||||
return LOG_LEVEL_MESSAGE;
|
||||
if (g_str_equal(str->str, "warning"))
|
||||
return LOG_LEVEL_WARNING;
|
||||
if (g_str_equal(str->str, "error"))
|
||||
return LOG_LEVEL_ERROR;
|
||||
|
||||
/* fall back to debug level */
|
||||
return LOG_LEVEL_DEBUG;
|
||||
}
|
||||
|
||||
gchar* log_level_str(log_level_t log_level) {
|
||||
switch (log_level) {
|
||||
case LOG_LEVEL_DEBUG: return "debug";
|
||||
case LOG_LEVEL_INFO: return "info";
|
||||
case LOG_LEVEL_MESSAGE: return "message";
|
||||
case LOG_LEVEL_WARNING: return "warning";
|
||||
case LOG_LEVEL_ERROR: return "error";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
log_t *log_new(server *srv, log_type_t type, GString *path) {
|
||||
log_t *log;
|
||||
gint fd = -1;
|
||||
|
|
|
@ -105,6 +105,11 @@ struct log_entry_t {
|
|||
GString *msg;
|
||||
};
|
||||
|
||||
/* determines the type of a log target by the path given. /absolute/path = file; |app = pipe; stderr = stderr; syslog = syslog */
|
||||
log_type_t log_type_from_path(GString *path);
|
||||
|
||||
log_level_t log_level_from_string(GString *str);
|
||||
gchar* log_level_str(log_level_t log_level);
|
||||
|
||||
/* log_new is used to create a new log target, if a log with the same path already exists, it is referenced instead */
|
||||
log_t *log_new(server *srv, log_type_t type, GString *path);
|
||||
|
|
|
@ -173,7 +173,7 @@ gboolean parse_option(server *srv, const char *name, option *opt, option_set *ma
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (sopt->type != opt->type) {
|
||||
if (sopt->type != opt->type && sopt->type != OPTION_NONE) {
|
||||
ERROR(srv, "Unexpected option type '%s', expected '%s' for option %s",
|
||||
option_type_string(opt->type), option_type_string(sopt->type), name);
|
||||
return FALSE;
|
||||
|
|
|
@ -181,11 +181,13 @@ static action_result core_handle_test(server *srv, connection *con, gpointer par
|
|||
if (con->state != CON_STATE_HANDLE_REQUEST_HEADER) return ACTION_GO_ON;
|
||||
|
||||
con->response.http_status = 200;
|
||||
chunkqueue_append_mem(con->out, CONST_STR_LEN("path: "));
|
||||
chunkqueue_append_mem(con->out, CONST_STR_LEN("host: "));
|
||||
chunkqueue_append_mem(con->out, GSTR_LEN(con->request.uri.host));
|
||||
chunkqueue_append_mem(con->out, CONST_STR_LEN("\r\npath: "));
|
||||
chunkqueue_append_mem(con->out, GSTR_LEN(con->request.uri.path));
|
||||
chunkqueue_append_mem(con->out, CONST_STR_LEN("\r\nquery: "));
|
||||
chunkqueue_append_mem(con->out, GSTR_LEN(con->request.uri.query));
|
||||
chunkqueue_append_mem(con->out, CONST_STR_LEN("\r\n\r\n--- Headers ---\r\n"));
|
||||
chunkqueue_append_mem(con->out, CONST_STR_LEN("\r\n\r\n--- headers ---\r\n"));
|
||||
g_hash_table_iter_init(&iter, con->request.headers->table);
|
||||
while (g_hash_table_iter_next(&iter, &k, &v)) {
|
||||
hv = g_queue_peek_head_link(&((http_header*)v)->values);
|
||||
|
@ -200,6 +202,11 @@ static action_result core_handle_test(server *srv, connection *con, gpointer par
|
|||
chunkqueue_append_mem(con->out, CONST_STR_LEN("\r\n"));
|
||||
connection_handle_direct(srv, con);
|
||||
|
||||
log_debug(srv, con, "core_handle_test: %s%s%s log_level: %s",
|
||||
con->request.uri.path->str, con->request.uri.query->len ? "?" : "", con->request.uri.query->len ? con->request.uri.query->str : "",
|
||||
log_level_str((log_level_t)CORE_OPTION(CORE_OPTION_LOG_LEVEL))
|
||||
);
|
||||
|
||||
return ACTION_GO_ON;
|
||||
}
|
||||
|
||||
|
@ -268,9 +275,60 @@ static gboolean core_listen(server *srv, plugin* p, option *opt) {
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
gboolean core_option_log_target_parse(server *srv, plugin *p, size_t ndx, option *opt, gpointer *value) {
|
||||
log_t *log;
|
||||
log_type_t log_type;
|
||||
|
||||
UNUSED(log);
|
||||
UNUSED(log_type);
|
||||
UNUSED(p);
|
||||
|
||||
assert(opt->type == OPTION_STRING);
|
||||
|
||||
log_type = log_type_from_path(opt->value.opt_string);
|
||||
log = log_new(srv, log_type, opt->value.opt_string);
|
||||
|
||||
*value = (gpointer)log;
|
||||
|
||||
TRACE(srv, "log.target assignment; ndx: %zd, value: %s", ndx, opt->value.opt_string->str);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void core_option_log_target_free(server *srv, plugin *p, size_t ndx, gpointer value) {
|
||||
UNUSED(srv);
|
||||
UNUSED(p);
|
||||
UNUSED(ndx);
|
||||
UNUSED(value);
|
||||
}
|
||||
|
||||
gboolean core_option_log_level_parse(server *srv, plugin *p, size_t ndx, option *opt, gpointer *value) {
|
||||
UNUSED(srv);
|
||||
UNUSED(p);
|
||||
UNUSED(ndx);
|
||||
|
||||
assert(opt->type == OPTION_STRING);
|
||||
|
||||
*value = (gpointer)log_level_from_string(opt->value.opt_string);
|
||||
|
||||
TRACE(srv, "log.level assignment: %s", opt->value.opt_string->str);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void core_option_log_level_free(server *srv, plugin *p, size_t ndx, gpointer value) {
|
||||
UNUSED(srv);
|
||||
UNUSED(p);
|
||||
UNUSED(ndx);
|
||||
UNUSED(value);
|
||||
}
|
||||
|
||||
static const plugin_option options[] = {
|
||||
{ "debug.log_request_handling", OPTION_BOOLEAN, NULL, NULL},
|
||||
{ "log.level", OPTION_STRING, NULL, NULL },
|
||||
{ "debug.log_request_handling", OPTION_BOOLEAN, NULL, NULL },
|
||||
|
||||
{ "log.target", OPTION_STRING, core_option_log_target_parse, core_option_log_target_free },
|
||||
{ "log.level", OPTION_STRING, core_option_log_level_parse, core_option_log_level_free },
|
||||
|
||||
{ "static-file.exclude", OPTION_LIST, NULL, NULL },
|
||||
{ NULL, 0, NULL, NULL }
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
|
||||
enum core_options_t {
|
||||
CORE_OPTION_DEBUG_REQUEST_HANDLING = 0,
|
||||
CORE_OPTION_LOG_LEVEL = 1,
|
||||
|
||||
CORE_OPTION_STATIC_FILE_EXCLUDE = 2
|
||||
CORE_OPTION_LOG_TARGET = 1,
|
||||
CORE_OPTION_LOG_LEVEL = 2,
|
||||
|
||||
CORE_OPTION_STATIC_FILE_EXCLUDE = 3
|
||||
};
|
||||
|
||||
/* the core plugin always has base index 0, as it is the first plugin loaded */
|
||||
|
|
Loading…
Reference in New Issue