#include "log.h" #include "ctx.h" #include #include const char *log_colors[] = { "\033[34m", "\033[01;34m", "\033[01;33m", "\033[0m", "\033[31m", "\033[01;31m" }; const char *log_levels[] = { "DEBUG", "INFO", "WARNING", "ERROR", "FATAL" }; void vsist_logf(const char *filepath, int level, char *format, va_list ap) { static int is_tty = -1; if (is_tty == -1) { is_tty = isatty(STDERR_FILENO); } char log_str[LOG_MAX_LENGTH]; char datetime[32]; time_t t; struct tm result; t = time(NULL); localtime_r(&t, &result); strftime(datetime, sizeof(datetime), "%Y-%m-%d %H:%M:%S", &result); int log_len; if (LogCtx.json_logs) { vsnprintf(log_str, sizeof(log_str), format, ap); cJSON *log_str_json = cJSON_CreateString(log_str); char *log_str_json_str = cJSON_PrintUnformatted(log_str_json); cJSON *filepath_json = cJSON_CreateString(filepath); char *filepath_json_str = cJSON_PrintUnformatted(filepath_json); log_len = snprintf( log_str, sizeof(log_str), "{\"thread\":\"T%d\",\"datetime\":\"%s\",\"level\":\"%s\",\"filepath\":%s,\"message\":%s}\n", ProcData.thread_id, datetime, log_levels[level], filepath_json_str, log_str_json_str ); cJSON_Delete(filepath_json); cJSON_Delete(log_str_json); free(log_str_json_str); free(filepath_json_str); write(STDOUT_FILENO, log_str, log_len); return; } if (is_tty) { log_len = snprintf( log_str, sizeof(log_str), "\033[%dmT%d%s [%s] [%s %s] ", 31 + ProcData.thread_id % 7, ProcData.thread_id, log_colors[level], datetime, log_levels[level], filepath ); } else { log_len = snprintf( log_str, sizeof(log_str), "T%d [%s] [%s %s] ", ProcData.thread_id, datetime, log_levels[level], filepath ); } size_t maxsize = sizeof(log_str) - log_len; log_len += vsnprintf(log_str + log_len, maxsize, format, ap); if (log_len >= maxsize) { fprintf(stderr, "([%s] FIXME: Log string is too long to display: %dB)\n", log_levels[level], log_len); return; } if (is_tty) { log_len += sprintf(log_str + log_len, "\033[0m\n"); } else { *(log_str + log_len) = '\n'; log_len += 1; } if (PrintingProgressBar) { PrintingProgressBar = FALSE; memmove(log_str + 1, log_str, log_len); log_str[0] = '\n'; log_len += 1; } write(STDERR_FILENO, log_str, log_len); } void sist_logf(const char *filepath, int level, char *format, ...) { va_list ap; va_start(ap, format); vsist_logf(filepath, level, format, ap); va_end(ap); } void sist_log(const char *filepath, int level, char *str) { static int is_tty = -1; if (is_tty == -1) { is_tty = isatty(STDERR_FILENO); } char log_str[LOG_MAX_LENGTH]; char datetime[32]; time_t t; struct tm result; t = time(NULL); localtime_r(&t, &result); strftime(datetime, sizeof(datetime), "%Y-%m-%d %H:%M:%S", &result); int log_len; if (LogCtx.json_logs) { cJSON *log_str_json = cJSON_CreateString(str); char *log_str_json_str = cJSON_PrintUnformatted(log_str_json); cJSON *filepath_json = cJSON_CreateString(filepath); char *filepath_json_str = cJSON_PrintUnformatted(filepath_json); log_len = snprintf( log_str, sizeof(log_str), "{\"thread\":\"T%d\",\"datetime\":\"%s\",\"level\":\"%s\",\"filepath\":%s,\"message\":%s}\n", ProcData.thread_id, datetime, log_levels[level], filepath_json_str, log_str_json_str ); cJSON_Delete(log_str_json); cJSON_Delete(filepath_json); free(log_str_json_str); free(filepath_json_str); write(STDOUT_FILENO, log_str, log_len); return; } if (is_tty) { log_len = snprintf( log_str, sizeof(log_str), "\033[%dmT%d%s [%s] [%s %s] %s \033[0m\n", 31 + ProcData.thread_id % 7, ProcData.thread_id, log_colors[level], datetime, log_levels[level], filepath, str ); } else { log_len = snprintf( log_str, sizeof(log_str), "T%d [%s] [%s %s] %s \n", ProcData.thread_id, datetime, log_levels[level], filepath, str ); } if (PrintingProgressBar) { PrintingProgressBar = FALSE; memmove(log_str + 1, log_str, log_len); log_str[0] = '\n'; log_len += 1; } write(STDERR_FILENO, log_str, log_len); }