power_play/src/log.h

170 lines
5.1 KiB
C

#ifndef LOG_H
#define LOG_H
#include "string.h"
#include "sys.h"
#define LOG_LEVEL(l) (l <= LOG_LEVEL_COMPTIME)
/* Log level configuration */
#ifndef LOG_LEVEL_COMPTIME
# if RTC || PROFILING
# define LOG_LEVEL_COMPTIME LOG_LEVEL_DEBUG
# else
# define LOG_LEVEL_COMPTIME LOG_LEVEL_INFO
# endif
#endif
/* Source location configuration */
#ifndef LOG_INCLUDE_SOURCE_LOCATION
# define LOG_INCLUDE_SOURCE_LOCATION (DEBINFO)
#endif
#define LOG_LEVEL_NONE -1
#define LOG_LEVEL_CRITICAL 0
#define LOG_LEVEL_ERROR 1
#define LOG_LEVEL_WARNING 2
#define LOG_LEVEL_SUCCESS 3
#define LOG_LEVEL_INFO 4
#define LOG_LEVEL_DEBUG 5
#define LOG_LEVEL_COUNT 6
/* ========================== *
* Callback interface
* ========================== */
struct log_level_settings {
struct string shorthand;
u32 color;
};
struct log_event {
/* Msg lifetime is only as long as callback duration */
struct string msg;
i32 level;
struct sys_datetime datetime;
i64 time_ns;
/* These will be nulled if LOG_INCLUDE_SOURCE_LOCATION is disabled */
struct string file;
i32 line;
};
#define LOG_EVENT_CALLBACK_FUNC_DEF(name, log_event_arg) void name(struct log_event log_event_arg)
typedef LOG_EVENT_CALLBACK_FUNC_DEF(log_event_callback_func, log_event);
void log_register_callback(log_event_callback_func *func, i32 level);
/* ========================== *
* Logging macros
* ========================== */
#define log_panic(msg) _log_panic(msg)
#if LOG_LEVEL(LOG_LEVEL_CRITICAL)
# if LOG_INCLUDE_SOURCE_LOCATION
# define log_critical(msg) _log(LOG_LEVEL_CRITICAL, LIT(__FILE__), __LINE__, msg)
# define logf_critical(fmt_lit, ...) _logf(LOG_LEVEL_CRITICAL, LIT(__FILE__), __LINE__, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END)
# else
# define log_critical(msg) _log(LOG_LEVEL_CRITICAL, msg)
# define logf_critical(fmt_lit, ...) _logf(LOG_LEVEL_CRITICAL, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END)
# endif
#else
# define log_critical(msg)
# define logf_critical(fmt_lit, ...)
#endif
#if LOG_LEVEL(LOG_LEVEL_ERROR)
# if LOG_INCLUDE_SOURCE_LOCATION
# define log_error(msg) _log(LOG_LEVEL_ERROR, LIT(__FILE__), __LINE__, msg)
# define logf_error(fmt_lit, ...) _logf(LOG_LEVEL_ERROR, LIT(__FILE__), __LINE__, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END)
# else
# define log_error(msg) _log(LOG_LEVEL_ERROR, msg)
# define logf_error(fmt_lit, ...) _logf(LOG_LEVEL_ERROR, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END)
# endif
#else
# define log_error(msg)
# define logf_error(fmt_lit, ...)
#endif
#if LOG_LEVEL(LOG_LEVEL_WARNING)
# if LOG_INCLUDE_SOURCE_LOCATION
# define log_warning(msg) _log(LOG_LEVEL_WARNING, LIT(__FILE__), __LINE__, msg)
# define logf_warning(fmt_lit, ...) _logf(LOG_LEVEL_WARNING, LIT(__FILE__), __LINE__, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END)
# else
# define log_warning(msg) _log(LOG_LEVEL_WARNING, msg)
# define logf_warning(fmt_lit, ...) _logf(LOG_LEVEL_WARNING, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END)
# endif
#else
# define log_warning(msg)
# define logf_warning(fmt_lit, ...)
#endif
#if LOG_LEVEL(LOG_LEVEL_SUCCESS)
# if LOG_INCLUDE_SOURCE_LOCATION
# define log_success(msg) _log(LOG_LEVEL_SUCCESS, LIT(__FILE__), __LINE__, msg)
# define logf_success(fmt_lit, ...) _logf(LOG_LEVEL_SUCCESS, LIT(__FILE__), __LINE__, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END)
# else
# define log_success(msg) _log(LOG_LEVEL_SUCCESS, msg)
# define logf_success(fmt_lit, ...) _logf(LOG_LEVEL_SUCCESS, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END)
# endif
#else
# define log_success(msg)
# define logf_success(fmt_lit, ...)
#endif
#if LOG_LEVEL(LOG_LEVEL_INFO)
# if LOG_INCLUDE_SOURCE_LOCATION
# define log_info(msg) _log(LOG_LEVEL_INFO, LIT(__FILE__), __LINE__, msg)
# define logf_info(fmt_lit, ...) _logf(LOG_LEVEL_INFO, LIT(__FILE__), __LINE__, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END)
# else
# define log_info(msg) _log(LOG_LEVEL_INFO, msg)
# define logf_info(fmt_lit, ...) _logf(LOG_LEVEL_INFO, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END)
# endif
#else
# define log_info(msg)
# define logf_info(fmt_lit, ...)
#endif
#if LOG_LEVEL(LOG_LEVEL_DEBUG)
# if LOG_INCLUDE_SOURCE_LOCATION
# define log_debug(msg) _log(LOG_LEVEL_DEBUG, LIT(__FILE__), __LINE__, msg)
# define logf_debug(fmt_lit, ...) _logf(LOG_LEVEL_DEBUG, LIT(__FILE__), __LINE__, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END)
# else
# define log_debug(msg) _log(LOG_LEVEL_DEBUG, msg)
# define logf_debug(fmt_lit, ...) _logf(LOG_LEVEL_DEBUG, LIT(fmt_lit) , ## __VA_ARGS__, FMT_END)
# endif
#else
# define log_debug(msg)
# define logf_debug(fmt_lit, ...)
#endif
/* ========================== *
* Function declarations
* ========================== */
void log_startup(struct string logfile_path);
void _log_panic(struct string msg);
#if LOG_INCLUDE_SOURCE_LOCATION
void _log(i32 level, struct string file, u32 line, struct string msg);
#else
void _log(i32 level, struct string msg);
#endif
#if LOG_INCLUDE_SOURCE_LOCATION
void _logfv(i32 level, struct string file, u32 line, struct string fmt, va_list args);
#else
void _logfv(i32 level, struct string fmt, va_list args);
#endif
#if LOG_INCLUDE_SOURCE_LOCATION
void _logf(i32 level, struct string file, u32 line, struct string fmt, ...);
#else
void _logf(i32 level, struct string fmt, ...);
#endif
#endif