diff --git a/mongoose.c b/mongoose.c index 0f291723ba25e87044af3265b804560485b293f6..fe7bb00edbfeeceed93c83b24112a938df0f4cac 100644 --- a/mongoose.c +++ b/mongoose.c @@ -428,6 +428,9 @@ int cs_base64_decode(const unsigned char *s, int len, char *dst, int *dec_len) { extern "C" { #endif /* __cplusplus */ +/* + * Log level; `LL_INFO` is the default. Use `cs_log_set_level()` to change it. + */ enum cs_log_level { LL_NONE = -1, LL_ERROR = 0, @@ -440,12 +443,54 @@ enum cs_log_level { _LL_MAX = 5, }; -/* Set log level. */ +/* + * Set max log level to print; messages with the level above the given one will + * not be printed. + */ void cs_log_set_level(enum cs_log_level level); -/* Set log filter. NULL (a default) logs everything. */ -void cs_log_set_filter(const char *source_file_name); +/* + * Set log filter. NULL (a default) logs everything. + * Otherwise, function name and file name will be tested against the given + * pattern, and only matching messages will be printed. + * + * For the pattern syntax, refer to `mg_match_prefix()` in `str_util.h`. + * + * Example: + * ```c + * void foo(void) { + * LOG(LL_INFO, ("hello from foo")); + * } + * + * void bar(void) { + * LOG(LL_INFO, ("hello from bar")); + * } + * + * void test(void) { + * cs_log_set_filter(NULL); + * foo(); + * bar(); + * + * cs_log_set_filter("f*"); + * foo(); + * bar(); // Will NOT print anything + * + * cs_log_set_filter("bar"); + * foo(); // Will NOT print anything + * bar(); + * } + * ``` + */ +void cs_log_set_filter(const char *pattern); +/* + * Helper function which prints message prefix with the given `level`, function + * name `func` and `filename`. If message should be printed (accordingly to the + * current log level and filter), prints the prefix and returns 1, otherwise + * returns 0. + * + * Clients should typically just use `LOG()` macro. + */ int cs_log_print_prefix(enum cs_log_level level, const char *func, const char *filename); @@ -453,13 +498,29 @@ extern enum cs_log_level cs_log_threshold; #if CS_ENABLE_STDIO +/* + * Set file to write logs into. If `NULL`, logs go to `stderr`. + */ void cs_log_set_file(FILE *file); + +/* + * Prints log to the current log file, appends "\n" in the end and flushes the + * stream. + */ void cs_log_printf(const char *fmt, ...) #ifdef __GNUC__ __attribute__((format(printf, 1, 2))) #endif ; +/* + * Format and print message `x` with the given level `l`. Example: + * + * ```c + * LOG(LL_INFO, ("my info message: %d", 123)); + * LOG(LL_DEBUG, ("my debug message: %d", 123)); + * ``` + */ #define LOG(l, x) \ do { \ if (cs_log_print_prefix(l, __func__, __FILE__)) cs_log_printf x; \ @@ -467,6 +528,9 @@ void cs_log_printf(const char *fmt, ...) #ifndef CS_NDEBUG +/* + * Shortcut for `LOG(LL_VERBOSE_DEBUG, (...))` + */ #define DBG(x) LOG(LL_VERBOSE_DEBUG, x) #else /* NDEBUG */ @@ -524,12 +588,12 @@ double cs_log_ts WEAK; enum cs_log_level cs_log_cur_msg_level WEAK = LL_NONE; -void cs_log_set_filter(const char *str) WEAK; -void cs_log_set_filter(const char *str) { +void cs_log_set_filter(const char *pattern) WEAK; +void cs_log_set_filter(const char *pattern) { free(s_filter_pattern); - if (str != NULL) { - s_filter_pattern = strdup(str); - s_filter_pattern_len = strlen(str); + if (pattern != NULL) { + s_filter_pattern = strdup(pattern); + s_filter_pattern_len = strlen(pattern); } else { s_filter_pattern = NULL; s_filter_pattern_len = 0;