|
|
|
|
@ -327,13 +327,13 @@ void debug_output(debug_level_t level, debug_category_t category,
|
|
|
|
|
#undef BUFFER_SIZE |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Parse debug configuration from string */ |
|
|
|
|
/* Parse debug configuration from string (e.g., "ll_queue:debug,uasync:info,memory:warn,etcp:error") */ |
|
|
|
|
int debug_parse_config(const char* config_string) { |
|
|
|
|
if (!config_string || !*config_string) { |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
char* str = strdup(config_string); |
|
|
|
|
char* str = u_strdup(config_string); |
|
|
|
|
if (!str) { |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
@ -341,60 +341,63 @@ int debug_parse_config(const char* config_string) {
|
|
|
|
|
debug_category_t categories = 0; |
|
|
|
|
debug_level_t level = DEBUG_LEVEL_NONE; |
|
|
|
|
|
|
|
|
|
char* token = strtok(str, ";"); |
|
|
|
|
char* token = strtok(str, ","); |
|
|
|
|
while (token) { |
|
|
|
|
/* Trim leading spaces */ |
|
|
|
|
while (isspace(*token)) { |
|
|
|
|
token++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
char* eq = strchr(token, '='); |
|
|
|
|
if (!eq) { |
|
|
|
|
char* colon = strchr(token, ':'); |
|
|
|
|
if (!colon) { |
|
|
|
|
u_free(str); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
*eq = '\0'; |
|
|
|
|
char* key = token; |
|
|
|
|
char* value = eq + 1; |
|
|
|
|
*colon = '\0'; |
|
|
|
|
char* category_name = token; |
|
|
|
|
char* level_name = colon + 1; |
|
|
|
|
|
|
|
|
|
/* Trim leading spaces in value */ |
|
|
|
|
while (isspace(*value)) { |
|
|
|
|
value++; |
|
|
|
|
/* Trim leading spaces in level_name */ |
|
|
|
|
while (isspace(*level_name)) { |
|
|
|
|
level_name++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (strcasecmp(key, "modules") == 0) { |
|
|
|
|
char* mod_token = strtok(value, ","); |
|
|
|
|
while (mod_token) { |
|
|
|
|
/* Trim leading spaces */ |
|
|
|
|
while (isspace(*mod_token)) { |
|
|
|
|
mod_token++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
debug_category_t cat = get_category_by_name(mod_token); |
|
|
|
|
if (cat == DEBUG_CATEGORY_NONE) { |
|
|
|
|
u_free(str); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
categories |= cat; |
|
|
|
|
mod_token = strtok(NULL, ","); |
|
|
|
|
} |
|
|
|
|
} else if (strcasecmp(key, "level") == 0) { |
|
|
|
|
int lev_num = atoi(value); |
|
|
|
|
if (lev_num < DEBUG_LEVEL_NONE || lev_num > DEBUG_LEVEL_TRACE) { |
|
|
|
|
u_free(str); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
level = (debug_level_t)lev_num; |
|
|
|
|
debug_category_t cat = get_category_by_name(category_name); |
|
|
|
|
if (cat == DEBUG_CATEGORY_NONE) { |
|
|
|
|
u_free(str); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
debug_level_t lev = DEBUG_LEVEL_NONE; |
|
|
|
|
if (strcasecmp(level_name, "none") == 0) { |
|
|
|
|
lev = DEBUG_LEVEL_NONE; |
|
|
|
|
} else if (strcasecmp(level_name, "error") == 0) { |
|
|
|
|
lev = DEBUG_LEVEL_ERROR; |
|
|
|
|
} else if (strcasecmp(level_name, "warn") == 0) { |
|
|
|
|
lev = DEBUG_LEVEL_WARN; |
|
|
|
|
} else if (strcasecmp(level_name, "info") == 0) { |
|
|
|
|
lev = DEBUG_LEVEL_INFO; |
|
|
|
|
} else if (strcasecmp(level_name, "debug") == 0) { |
|
|
|
|
lev = DEBUG_LEVEL_DEBUG; |
|
|
|
|
} else if (strcasecmp(level_name, "trace") == 0) { |
|
|
|
|
lev = DEBUG_LEVEL_TRACE; |
|
|
|
|
} else { |
|
|
|
|
u_free(str); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
token = strtok(NULL, ";"); |
|
|
|
|
} |
|
|
|
|
/* Set per-category level */ |
|
|
|
|
int idx = 0; |
|
|
|
|
while (!(cat & (1ULL << idx)) && idx < DEBUG_CATEGORY_COUNT) { |
|
|
|
|
idx++; |
|
|
|
|
} |
|
|
|
|
if (idx < DEBUG_CATEGORY_COUNT) { |
|
|
|
|
g_debug_config.category_levels[idx] = lev; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
debug_set_masks(categories, level); |
|
|
|
|
token = strtok(NULL, ","); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
u_free(str); |
|
|
|
|
return 0; |
|
|
|
|
|