X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcutil%2Fsilclog.c;h=b415c664d1eecc3ed45b0b6829da2895f859c206;hb=a818c5b5411bbc4436d1c5f011236985c96bb787;hp=e48bfeed58adef486d6c40e8695a437b0e066473;hpb=d724e6e0616bad77bdcd83ed08a3f20daf5660b2;p=silc.git diff --git a/lib/silcutil/silclog.c b/lib/silcutil/silclog.c index e48bfeed..b415c664 100644 --- a/lib/silcutil/silclog.c +++ b/lib/silcutil/silclog.c @@ -21,8 +21,8 @@ #include "silcincludes.h" -/* default flush time (5 minutes) */ -#define SILC_LOG_TIMEOUT 300 +/* Minimum time delay for log flushing calls (in seconds) */ +#define SILC_LOG_FLUSH_MIN_DELAY 2 /* nice macro for looping through all logs -- makes the code more readable */ #define SILC_FOREACH_LOG(__x__) for (__x__ = 0; __x__ < SILC_LOG_MAX; __x__++) @@ -32,7 +32,7 @@ struct SilcLogStruct { char *filename; FILE *fp; - uint32 maxsize; + SilcUInt32 maxsize; char *typename; SilcLogType type; SilcLogCb cb; @@ -43,8 +43,8 @@ typedef struct SilcLogStruct *SilcLog; /* These are the known logging channels */ static struct SilcLogStruct silclogs[SILC_LOG_MAX] = { {NULL, NULL, 0, "Info", SILC_LOG_INFO, NULL, NULL}, - {NULL, NULL, 0, "Error", SILC_LOG_ERROR, NULL, NULL}, {NULL, NULL, 0, "Warning", SILC_LOG_WARNING, NULL, NULL}, + {NULL, NULL, 0, "Error", SILC_LOG_ERROR, NULL, NULL}, {NULL, NULL, 0, "Fatal", SILC_LOG_FATAL, NULL, NULL}, }; @@ -55,8 +55,11 @@ bool silc_log_quick = FALSE; bool silc_debug = FALSE; bool silc_debug_hexdump = FALSE; +/* Flush delay */ +long silc_log_flushdelay = 300; + /* Regular pattern matching expression for the debug output */ -static char *silc_log_debug_string = NULL; +char *silc_log_debug_string = NULL; /* Debug callbacks. If set these are used instead of default ones. */ static SilcLogDebugCb silc_log_debug_cb = NULL; @@ -68,6 +71,9 @@ static void *silc_log_hexdump_context = NULL; static bool silc_log_scheduled = FALSE; static bool silc_log_no_init = FALSE; +/* This is only needed during starting up -- don't lose any logging */ +static bool silc_log_starting = TRUE; + /* The type wrapper utility. Translates a SilcLogType id to the corresponding * logfile, or NULL if not found. */ static SilcLog silc_log_find_by_type(SilcLogType type) @@ -135,6 +141,7 @@ static bool silc_log_reset(SilcLog log) fflush(log->fp); fclose(log->fp); } + if (!log->filename) return FALSE; if (!(log->fp = fopen(log->filename, "a+"))) { SILC_LOG_WARNING(("Couldn't reset logfile %s for type \"%s\": %s", log->filename, log->typename, strerror(errno))); @@ -153,8 +160,11 @@ SILC_TASK_CALLBACK(silc_log_fflush_callback) SILC_FOREACH_LOG(u) silc_log_checksize(&silclogs[u]); } + silc_log_starting = FALSE; + if (silc_log_flushdelay < SILC_LOG_FLUSH_MIN_DELAY) + silc_log_flushdelay = SILC_LOG_FLUSH_MIN_DELAY; silc_schedule_task_add((SilcSchedule) context, 0, silc_log_fflush_callback, - context, SILC_LOG_TIMEOUT, 0, SILC_TASK_TIMEOUT, + context, silc_log_flushdelay, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); } @@ -166,6 +176,7 @@ SILC_TASK_CALLBACK(silc_log_fflush_callback) void silc_log_output(SilcLogType type, char *string) { char *typename; + FILE *fp; SilcLog log; if ((type > SILC_LOG_MAX) || !(log = silc_log_find_by_type(type))) @@ -177,25 +188,26 @@ void silc_log_output(SilcLogType type, char *string) goto end; } + /* save the original typename, because if we redirect the channel we + * keep however the original destination channel name */ + typename = log->typename; + if (!silc_log_scheduled) { if (silc_log_no_init == FALSE) { - fprintf(stderr, + fprintf(stderr, "Warning, trying to output without log files initialization, " "log output is going to stderr\n"); silc_log_no_init = TRUE; } - - fprintf(stderr, "%s\n", string); - goto end; + /* redirect output */ + fp = stderr; + log = NULL; + goto found; } - /* save the original typename, because if we redirect the channel we - * keep however the original destination channel name */ - typename = log->typename; - /* ok, now we have to find an open stream */ while (TRUE) { - if (log && log->fp) goto found; + if (log && (fp = log->fp)) goto found; if (type == 0) break; log = silc_log_find_by_type(--type); } @@ -205,10 +217,11 @@ void silc_log_output(SilcLogType type, char *string) goto end; found: - fprintf(log->fp, "[%s] [%s] %s\n", silc_get_time(), typename, string); - if (silc_log_quick) { - fflush(log->fp); - silc_log_checksize(log); + fprintf(fp, "[%s] [%s] %s\n", silc_get_time(), typename, string); + if (silc_log_quick || silc_log_starting) { + fflush(fp); + if (log) + silc_log_checksize(log); } end: @@ -228,7 +241,7 @@ char *silc_log_get_file(SilcLogType type) } /* Set and initialize the specified logging channel. See the API reference */ -bool silc_log_set_file(SilcLogType type, char *filename, uint32 maxsize, +bool silc_log_set_file(SilcLogType type, char *filename, SilcUInt32 maxsize, SilcSchedule scheduler) { FILE *fp = NULL; @@ -270,9 +283,9 @@ bool silc_log_set_file(SilcLogType type, char *filename, uint32 maxsize, if (silc_log_scheduled) return TRUE; - /* make sure we write to the disk sometimes */ + /* add schedule hook with a short delay to make sure we'll use right delay */ silc_schedule_task_add(scheduler, 0, silc_log_fflush_callback, - (void *) scheduler, SILC_LOG_TIMEOUT, 0, + (void *) scheduler, 10, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); silc_log_scheduled = TRUE; @@ -331,18 +344,22 @@ void silc_log_output_debug(char *file, char *function, { if (!silc_debug) goto end; + if (silc_log_debug_string && - !silc_string_regex_match(silc_log_debug_string, file) && - !silc_string_regex_match(silc_log_debug_string, function)) + !silc_string_regex_match(silc_log_debug_string, file) && + !silc_string_regex_match(silc_log_debug_string, function)) goto end; + if (silc_log_debug_cb) { if ((*silc_log_debug_cb)(file, function, line, string, silc_log_debug_context)) goto end; } + fprintf(stderr, "%s:%d: %s\n", function, line, string); fflush(stderr); -end: + + end: silc_free(string); } @@ -350,7 +367,7 @@ end: void silc_log_output_hexdump(char *file, char *function, int line, void *data_in, - uint32 len, char *string) + SilcUInt32 len, char *string) { int i, k; int off, pos, count; @@ -358,10 +375,12 @@ void silc_log_output_hexdump(char *file, char *function, if (!silc_debug_hexdump) goto end; + if (silc_log_debug_string && - !silc_string_regex_match(silc_log_debug_string, file) && - !silc_string_regex_match(silc_log_debug_string, function)) + !silc_string_regex_match(silc_log_debug_string, file) && + !silc_string_regex_match(silc_log_debug_string, function)) goto end; + if (silc_log_hexdump_cb) { if ((*silc_log_hexdump_cb)(file, function, line, data_in, len, string, silc_log_hexdump_context)) @@ -369,7 +388,6 @@ void silc_log_output_hexdump(char *file, char *function, } fprintf(stderr, "%s:%d: %s\n", function, line, string); - silc_free(string); k = 0; pos = 0; @@ -425,9 +443,8 @@ void silc_log_output_hexdump(char *file, char *function, if (count < 16) break; } - return; -end: + end: silc_free(string); }