Prepare for having per destination module log levels

This commit is contained in:
Nils O. Selåsdal
2013-05-31 03:40:33 +02:00
parent 5a427007d6
commit af8cab5034
+76 -27
View File
@@ -9,6 +9,11 @@
#include "ucore/logging.h" #include "ucore/logging.h"
//used to realise per destination settings
struct uc_log_module_setting {
int log_level;
};
struct uc_log_destination { struct uc_log_destination {
SLIST_ENTRY(uc_log_destination) entry; SLIST_ENTRY(uc_log_destination) entry;
enum UC_LOG_DESTINATION dest_type; enum UC_LOG_DESTINATION dest_type;
@@ -16,6 +21,7 @@ struct uc_log_destination {
int log_level; int log_level;
//Whether to log the source file name and line number //Whether to log the source file name and line number
int log_location; int log_location;
struct uc_log_module_setting *module_settings;
union { union {
//for syslog openlog() //for syslog openlog()
struct { struct {
@@ -95,6 +101,22 @@ static inline int uc_ll_2_syslog(enum UC_LOG_LEVEL l)
return LOG_INFO; return LOG_INFO;
} }
static int uc_log_init_settings(struct uc_log_destination *dest)
{
int i;
dest->module_settings = calloc(g_modules.cnt, sizeof *dest->module_settings);
if (dest->module_settings == NULL) {
return -1;
}
for (i = 0; i < g_modules.cnt; i++) {
dest->module_settings[i].log_level = g_modules.mods[i].log_level;
}
return 0;
}
struct uc_log_destination *uc_log_new_stderr(int log_level, int log_location) struct uc_log_destination *uc_log_new_stderr(int log_level, int log_location)
{ {
struct uc_log_destination *dest = calloc(1, sizeof *dest); struct uc_log_destination *dest = calloc(1, sizeof *dest);
@@ -102,6 +124,11 @@ struct uc_log_destination *uc_log_new_stderr(int log_level, int log_location)
if(dest == NULL) if(dest == NULL)
return NULL; return NULL;
if (uc_log_init_settings(dest) != 0) {
free(dest);
return NULL;
}
dest->dest_type = UC_LDEST_STDERR; dest->dest_type = UC_LDEST_STDERR;
dest->type.file.file = stderr; dest->type.file.file = stderr;
dest->log_level = log_level;; dest->log_level = log_level;;
@@ -118,9 +145,15 @@ struct uc_log_destination *uc_log_new_syslog(const char *ident, int facility, in
if (dest == NULL) if (dest == NULL)
return NULL; return NULL;
if (uc_log_init_settings(dest) != 0) {
free(dest);
return NULL;
}
//copy the ident - though it's unused inside the struct for now //copy the ident - though it's unused inside the struct for now
id = strdup(ident); id = strdup(ident);
if (id == NULL) { if (id == NULL) {
free(dest->module_settings);
free(dest); free(dest);
return NULL; return NULL;
} }
@@ -145,14 +178,21 @@ struct uc_log_destination *uc_log_new_file(const char *filename, int log_level,
if (dest == NULL) if (dest == NULL)
return NULL; return NULL;
if (uc_log_init_settings(dest) != 0) {
free(dest);
return NULL;
}
name = strdup(filename); name = strdup(filename);
if (name == NULL) { if (name == NULL) {
free(dest->module_settings);
free(dest); free(dest);
return NULL; return NULL;
} }
f = fopen(filename, "a"); f = fopen(filename, "a");
if (f == NULL) { if (f == NULL) {
free(dest->module_settings);
free(name); free(name);
free(dest); free(dest);
return NULL; return NULL;
@@ -245,6 +285,7 @@ void uc_log_delete_destination(struct uc_log_destination *dest)
free(dest->type.file.file_name); free(dest->type.file.file_name);
break; break;
} }
free(dest->module_settings);
free(dest); free(dest);
@@ -412,43 +453,51 @@ void uc_logf(int log_level, int module, int raw,
else else
log_module = &g_unknown_module; log_module = &g_unknown_module;
//Check if the module should not be logged
if (log_level < log_module->log_level)
goto out;
//do logging for each destination //do logging for each destination
SLIST_FOREACH(dest, &g_destinations, entry) { SLIST_FOREACH(dest, &g_destinations, entry) {
va_list apc; va_list apc;
int module_log_level;
if (log_level >= dest->log_level) {
const struct uc_log_args args = {
.dest = dest,
.module = log_module,
.log_level = log_level,
.file = file,
.line = line,
.raw = raw
};
//log func will mess with the va_list, //destnation level
//so make a copy if (log_level < dest->log_level)
va_copy(apc, ap); continue;
switch (dest->dest_type) { //individual module level
case UC_LDEST_SYSLOG: if (module >= 0 && module < g_modules.cnt)
uc_vlog_syslog(&args, fmt, apc); module_log_level = dest->module_settings[module].log_level;
break; else //application bug. use global/unknown module
case UC_LDEST_STDERR: module_log_level = log_module->log_level;
case UC_LDEST_FILE:
uc_vlog_file(&args, fmt, apc);
break;
}
va_end(apc); if (log_level < module_log_level)
continue;
const struct uc_log_args args = {
.dest = dest,
.module = log_module,
.log_level = log_level,
.file = file,
.line = line,
.raw = raw
};
//log func will mess with the va_list,
//so make a copy
va_copy(apc, ap);
switch (dest->dest_type) {
case UC_LDEST_SYSLOG:
uc_vlog_syslog(&args, fmt, apc);
break;
case UC_LDEST_STDERR:
case UC_LDEST_FILE:
uc_vlog_file(&args, fmt, apc);
break;
} }
va_end(apc);
} }
out:
pthread_mutex_unlock(&g_log_lock); pthread_mutex_unlock(&g_log_lock);
va_end(ap); va_end(ap);
} }