#include "log.h" #include #include #include #include static const char* LOG_LEVEL_STRING_TABLE[] = { "ERROR", "WARN", "INFO", "DEBUG", "TRACE" }; // Maybe add __attribute__((constructor)) in the future if available to skip _config_initialized static bool _user_default_config_initialized = false; static struct log_config_s _user_default_config; static inline struct log_config_s _default_config() { if (_user_default_config_initialized) { return _user_default_config; } return (struct log_config_s) { .loc_error = stderr, .loc_warn = stderr, .loc_info = stdout, .loc_debug = NULL, .loc_trace = NULL, .timestamp = true, }; } void log_set_default_config(struct log_config_s config) { _user_default_config = config; _user_default_config_initialized = true; } struct logger_s log_new(const char* module_name) { return (struct logger_s) { .module_name = module_name, .config = _default_config(), }; } void log_log(const struct logger_s* logger, enum LOG_LEVEL log_level, const char* fmt, ...) { assert(logger != NULL); FILE* dest = NULL; switch (log_level) { case LOG_ERR: dest = logger->config.loc_error; break; case LOG_WARN: dest = logger->config.loc_warn; break; case LOG_INFO: dest = logger->config.loc_info; break; case LOG_DEBUG: dest = logger->config.loc_debug; break; case LOG_TRACE: dest = logger->config.loc_trace; break; default: break; } if (dest == NULL) { return; } va_list varargs; va_start(varargs, fmt); if (logger->config.timestamp) { struct timespec utc_time; struct tm local_time; char time_str_buf[10+1+8+1]; timespec_get(&utc_time, TIME_UTC); localtime_r(&(utc_time.tv_sec), &local_time); if(strftime(time_str_buf, sizeof(time_str_buf), "%F %T", &local_time)) { fprintf(dest, "[%s.%9lu] ", time_str_buf, utc_time.tv_nsec); } } fprintf(dest, "[%s] %s: ", LOG_LEVEL_STRING_TABLE[log_level], logger->module_name); vfprintf(dest, fmt, varargs); fprintf(dest, "\n"); } void log_log_ssl_err(const struct logger_s* logger, enum LOG_LEVEL log_level, unsigned long error, const char* message_fmt, ...) { char error_buf[256]; ERR_error_string_n(ERR_get_error(), error_buf, sizeof(error_buf)); va_list varargs; va_start(varargs, message_fmt); log_log(logger, log_level, message_fmt, varargs); log_log(logger, log_level, "%s", error_buf); }