From dc9e9c06421eb9156baf425ac14ec8f50cb8b5ae Mon Sep 17 00:00:00 2001 From: Federico Angelilli Date: Mon, 14 Apr 2025 17:40:07 +0200 Subject: Update logging --- src/any_log.h | 156 +++++++++++++++++++++++++++++++--------------------- src/blocks/script.c | 9 ++- src/comet.c | 11 +++- src/lua/log.c | 31 ++++------- src/lua/log.h | 15 +++++ 5 files changed, 136 insertions(+), 86 deletions(-) create mode 100644 src/lua/log.h diff --git a/src/any_log.h b/src/any_log.h index 5667f03..4d4dc17 100644 --- a/src/any_log.h +++ b/src/any_log.h @@ -1,4 +1,4 @@ -// any_log v0.3.0 +// any_log v0.3.1 // // A single-file library that provides a simple and somewhat opinionated // interface for logging and structured logging. @@ -328,37 +328,59 @@ const char *any_log_level_to_string(any_log_level_t level); ANY_LOG_ATTRIBUTE(pure) any_log_level_t any_log_level_from_string(const char *string); +#ifndef ANY_LOG_NO_COLOR + // The default format macros for all logging function uses the global // any_log_color to get the color sequence to use when printing the logs. // // By default this global points to any_log_colors_enabled, but you can // set it to any_log_colors_disabled or to a custom array of your choice. // -// The array you give should have length ANY_LOG_ALL + 3 and the following layout +// Your custom color array should have length ANY_LOG_COLOR_ALL. +// Alternatively you can change the default colors by defining +// ANY_LOG_COLOR_[...]_DEFAULT. For example: // -// - from ANY_LOG_PANIC to ANY_LOG_TRACE: the colors indexed by log levels -// - ANY_LOG_ALL: the color reset sequence -// - ANY_LOG_ALL + 1: the color for the module -// - ANY_LOG_ALL + 2: the color for the function +// #define ANY_LOG_COLOR_FUNC_DEFAULT "\x1b[1m" +// #include "any_log.h" // -// If the macro ANY_LOG_NO_COLOR by default colors will be disabled. +// If you changed the default format in the implementation (by redefining +// ANY_LOG_FORMAT_*, ANY_LOG_VALUE_* and ANY_LOG_PANIC_*), these variables +// can be safely ignored and can use whatever method you prefer to get the colors. // -// NOTE: If you changed the default format in the implementation -// (by redefining ANY_LOG_FORMAT_*, ANY_LOG_VALUE_* and ANY_LOG_PANIC_*), -// you can safely ignore these variables and use whatever method you -// prefer to get the colors. +// In that case you may want to disable colors altogether by defining +// ANY_LOG_NO_COLOR. // extern const char **any_log_colors; +typedef enum { + ANY_LOG_COLOR_PANIC, + ANY_LOG_COLOR_ERROR, + ANY_LOG_COLOR_WARN, + ANY_LOG_COLOR_INFO, + ANY_LOG_COLOR_DEBUG, + ANY_LOG_COLOR_TRACE, + ANY_LOG_COLOR_MODULE, + ANY_LOG_COLOR_FUNC, + ANY_LOG_COLOR_RESET, + ANY_LOG_COLOR_ALL, +} any_log_color_t; + +// Little helper for getting the colors +// +#define ANY_LOG_COLOR_GET(c) any_log_colors[c] + // This array contains the default colors. // // See ANY_LOG_[level]_COLOR, ANY_LOG_RESET_COLOR, ANY_LOG_MODULE_COLOR and // ANY_LOG_FUNC_COLOR in the implementation. // -extern const char *any_log_colors_enabled[ANY_LOG_ALL + 3]; +extern const char *any_log_colors_enabled[ANY_LOG_COLOR_ALL]; // This array contains empty strings. -extern const char *any_log_colors_disabled[ANY_LOG_ALL + 3]; +// +extern const char *any_log_colors_disabled[ANY_LOG_COLOR_ALL]; + +#endif // NOTE: You should never call the functions below directly! // See the above explanations on how to use logging. @@ -455,73 +477,76 @@ any_log_level_t any_log_level_from_string(const char *string) return ANY_LOG_ALL; } +#ifndef ANY_LOG_NO_COLOR + // These colors related variables are provided just to provide a uniform // interface for setting the colors. If you decide to change the default // log format macros, feel free to ignore all this variables. // -// If the macro ANY_LOG_NO_COLOR is defined, any_log_colors_disabled -// will be used instead of any_log_colors_enabled. -// -const char **any_log_colors = -#ifdef ANY_LOG_NO_COLOR - any_log_colors_disabled; -#else - any_log_colors_enabled; -#endif +const char **any_log_colors = any_log_colors_enabled; // Log colors indexed by log level, with the addition of special colors // for func, module and reset sequence. // -#ifndef ANY_LOG_PANIC_COLOR -#define ANY_LOG_PANIC_COLOR "\x1b[1;91m" +#ifndef ANY_LOG_COLOR_PANIC_DEFAULT +#define ANY_LOG_COLOR_PANIC_DEFAULT "\x1b[1;91m" #endif -#ifndef ANY_LOG_ERROR_COLOR -#define ANY_LOG_ERROR_COLOR "\x1b[1;31m" +#ifndef ANY_LOG_COLOR_ERROR_DEFAULT +#define ANY_LOG_COLOR_ERROR_DEFAULT "\x1b[1;31m" #endif -#ifndef ANY_LOG_WARN_COLOR -#define ANY_LOG_WARN_COLOR "\x1b[1;33m" +#ifndef ANY_LOG_COLOR_WARN_DEFAULT +#define ANY_LOG_COLOR_WARN_DEFAULT "\x1b[1;33m" #endif -#ifndef ANY_LOG_INFO_COLOR -#define ANY_LOG_INFO_COLOR "\x1b[1;96m" +#ifndef ANY_LOG_COLOR_INFO_DEFAULT +#define ANY_LOG_COLOR_INFO_DEFAULT "\x1b[1;96m" #endif -#ifndef ANY_LOG_DEBUG_COLOR -#define ANY_LOG_DEBUG_COLOR "\x1b[1;37m" +#ifndef ANY_LOG_COLOR_DEBUG_DEFAULT +#define ANY_LOG_COLOR_DEBUG_DEFAULT "\x1b[1;37m" #endif -#ifndef ANY_LOG_TRACE_COLOR -#define ANY_LOG_TRACE_COLOR "\x1b[1;90m" +#ifndef ANY_LOG_COLOR_TRACE_DEFAULT +#define ANY_LOG_COLOR_TRACE_DEFAULT "\x1b[1;90m" #endif -#ifndef ANY_LOG_RESET_COLOR -#define ANY_LOG_RESET_COLOR "\x1b[0m" +#ifndef ANY_LOG_COLOR_RESET_DEFAULT +#define ANY_LOG_COLOR_RESET_DEFAULT "\x1b[0m" #endif -#ifndef ANY_LOG_MODULE_COLOR -#define ANY_LOG_MODULE_COLOR "" +#ifndef ANY_LOG_COLOR_MODULE_DEFAULT +#define ANY_LOG_COLOR_MODULE_DEFAULT "" #endif -#ifndef ANY_LOG_FUNC_COLOR -#define ANY_LOG_FUNC_COLOR "\x1b[1m" +#ifndef ANY_LOG_COLOR_FUNC_DEFAULT +#define ANY_LOG_COLOR_FUNC_DEFAULT "\x1b[1m" #endif const char *any_log_colors_enabled[ANY_LOG_ALL + 3] = { - ANY_LOG_PANIC_COLOR, - ANY_LOG_ERROR_COLOR, - ANY_LOG_WARN_COLOR, - ANY_LOG_INFO_COLOR , - ANY_LOG_DEBUG_COLOR, - ANY_LOG_TRACE_COLOR, - ANY_LOG_RESET_COLOR, - ANY_LOG_MODULE_COLOR, - ANY_LOG_FUNC_COLOR + ANY_LOG_COLOR_PANIC_DEFAULT, + ANY_LOG_COLOR_ERROR_DEFAULT, + ANY_LOG_COLOR_WARN_DEFAULT, + ANY_LOG_COLOR_INFO_DEFAULT, + ANY_LOG_COLOR_DEBUG_DEFAULT, + ANY_LOG_COLOR_TRACE_DEFAULT, + ANY_LOG_COLOR_MODULE_DEFAULT, + ANY_LOG_COLOR_FUNC_DEFAULT, + ANY_LOG_COLOR_RESET_DEFAULT, }; -const char *any_log_colors_disabled[ANY_LOG_ALL + 3] = { - "", "", "", "", "", "", "", +const char *any_log_colors_disabled[ANY_LOG_COLOR_ALL] = { + "", "", "", "", "", "", "", "", "" }; +#else + +// Define this to not break the default format macros +// +#define ANY_LOG_COLOR_GET(c) "" + +#endif + // Format for any_log_format (used at the start) #ifndef ANY_LOG_FORMAT_BEFORE #define ANY_LOG_FORMAT_BEFORE(stream, level, module, func) \ - fprintf(stream, "[%s%s%s %s%s%s] %s%s%s: ", any_log_colors[ANY_LOG_ALL + 1], module, any_log_colors[ANY_LOG_ALL], \ - any_log_colors[ANY_LOG_ALL + 2], func, any_log_colors[ANY_LOG_ALL], \ - any_log_colors[level], any_log_level_strings[level], any_log_colors[ANY_LOG_ALL]) + fprintf(stream, "[%s%s%s %s%s%s] %s%s%s: ", \ + ANY_LOG_COLOR_GET(ANY_LOG_COLOR_MODULE), module, ANY_LOG_COLOR_GET(ANY_LOG_COLOR_RESET), \ + ANY_LOG_COLOR_GET(ANY_LOG_COLOR_FUNC), func, ANY_LOG_COLOR_GET(ANY_LOG_COLOR_RESET), \ + ANY_LOG_COLOR_GET(level), any_log_level_strings[level], ANY_LOG_COLOR_GET(ANY_LOG_COLOR_RESET)) #endif // Format for any_log_format (used at the end) @@ -566,9 +591,10 @@ void any_log_format(any_log_level_t level, const char *module, // Format for any_log_value (used at the start) #ifndef ANY_LOG_VALUE_BEFORE #define ANY_LOG_VALUE_BEFORE(stream, level, module, func, message) \ - fprintf(stream, "[%s%s%s %s%s%s] %s%s%s: %s [", any_log_colors[ANY_LOG_ALL + 1], module, any_log_colors[ANY_LOG_ALL], \ - any_log_colors[ANY_LOG_ALL + 2], func, any_log_colors[ANY_LOG_ALL], \ - any_log_colors[level], any_log_level_strings[level], any_log_colors[ANY_LOG_ALL], message) + fprintf(stream, "[%s%s%s %s%s%s] %s%s%s: %s [", \ + ANY_LOG_COLOR_GET(ANY_LOG_COLOR_MODULE), module, ANY_LOG_COLOR_GET(ANY_LOG_COLOR_RESET), \ + ANY_LOG_COLOR_GET(ANY_LOG_COLOR_FUNC), func, ANY_LOG_COLOR_GET(ANY_LOG_COLOR_RESET), \ + ANY_LOG_COLOR_GET(level), any_log_level_strings[level], ANY_LOG_COLOR_GET(ANY_LOG_COLOR_RESET), message) #endif // Format for any_log_value (used at the end) @@ -647,7 +673,9 @@ void any_log_format(any_log_level_t level, const char *module, #define ANY_LOG_VALUE_PAIR_SEP ", " #endif -// NOTE: This function should be called with at least one pair +// NOTE: This function should be called with at least one parameter after message. +// The log_value_[level] macros automatically add a NULL. +// void any_log_value(any_log_level_t level, const char *module, const char *func, const char *message, ...) { @@ -759,16 +787,18 @@ tdefault:; // Format for any_log_panic (used at the start) #ifndef ANY_LOG_PANIC_BEFORE #define ANY_LOG_PANIC_BEFORE(stream, file, line, module, func) \ - fprintf(stream, "[%s%s%s %s%s%s] %s%s%s: ", any_log_colors[ANY_LOG_ALL + 1], module, any_log_colors[ANY_LOG_ALL], \ - any_log_colors[ANY_LOG_ALL + 2], func, any_log_colors[ANY_LOG_ALL], \ - any_log_colors[ANY_LOG_PANIC], any_log_level_strings[ANY_LOG_PANIC], any_log_colors[ANY_LOG_ALL]) + fprintf(stream, "[%s%s%s %s%s%s] %s%s%s: ", \ + ANY_LOG_COLOR_GET(ANY_LOG_COLOR_MODULE), module, ANY_LOG_COLOR_GET(ANY_LOG_COLOR_RESET), \ + ANY_LOG_COLOR_GET(ANY_LOG_COLOR_FUNC), func, ANY_LOG_COLOR_GET(ANY_LOG_COLOR_RESET), \ + ANY_LOG_COLOR_GET(ANY_LOG_PANIC), any_log_level_strings[ANY_LOG_PANIC], ANY_LOG_COLOR_GET(ANY_LOG_COLOR_RESET)) #endif // Format for any_log_panic (used at the start) #ifndef ANY_LOG_PANIC_AFTER #define ANY_LOG_PANIC_AFTER(stream, file, line, module, func) \ - fprintf(stream, "\n%spanic was invoked from%s %s:%d (%s%s%s)\n", any_log_colors[ANY_LOG_PANIC], \ - any_log_colors[ANY_LOG_ALL], file, line, any_log_colors[ANY_LOG_ALL + 1], module, any_log_colors[ANY_LOG_ALL]) + fprintf(stream, "\n%spanic was invoked from%s %s:%d (module %s%s%s)\n", \ + ANY_LOG_COLOR_GET(ANY_LOG_PANIC), ANY_LOG_COLOR_GET(ANY_LOG_COLOR_RESET), file, line, \ + ANY_LOG_COLOR_GET(ANY_LOG_COLOR_MODULE), module, ANY_LOG_COLOR_GET(ANY_LOG_COLOR_RESET)) #endif // NOTE: This function *exceptionally* gets more location information diff --git a/src/blocks/script.c b/src/blocks/script.c index ca0e506..10fe0fe 100644 --- a/src/blocks/script.c +++ b/src/blocks/script.c @@ -31,9 +31,16 @@ static void block_script_update(block_t *block) } char buffer[128] = { 0 }; - fgets(buffer, sizeof(buffer), output); + char *s = fgets(buffer, sizeof(buffer), output); pclose(output); + if (s == NULL) { + log_value_warn("Failed to execute a script", + "s:label", block->label, + "s:script", script->script); + return; + } + log_value_trace("Executed a script", "s:label", block->label, "s:script", script->script); diff --git a/src/comet.c b/src/comet.c index 9be94bf..f74cfda 100644 --- a/src/comet.c +++ b/src/comet.c @@ -12,14 +12,20 @@ #include "lua/api.h" #ifdef RELEASE -#define ANY_LOG_NO_TRACE +#define ANY_LOG_FORMAT_BEFORE(stream, level, module, func) \ + fprintf(stream, "[%s] %s%s%s: ", \ + func, ANY_LOG_COLOR_GET(level), any_log_level_strings[level], ANY_LOG_COLOR_GET(ANY_LOG_COLOR_RESET)) + +#define ANY_LOG_VALUE_BEFORE(stream, level, module, func, message) \ + fprintf(stream, "[%s] %s%s%s: %s [", \ + func, ANY_LOG_COLOR_GET(level), any_log_level_strings[level], ANY_LOG_COLOR_GET(ANY_LOG_COLOR_RESET), message) #endif #define ANY_LOG_VALUE_STRING(stream, key, value) \ fprintf(stream, "%s=\"%s\"", key, value ? value : "(null)") #define ANY_LOG_IMPLEMENT -#include "any_log.h" +#include "log.h" static sig_atomic_t running = true; @@ -73,6 +79,7 @@ int main(int argc, char **argv) lua_api_t lua; lua_api_init(&lua); + (void)luaL_dostring(lua.state, "log.warn('hello')"); if (luaL_dofile(lua.state, "example.lua") != LUA_OK) { const char *error_message = lua_tostring(lua.state, -1); log_error("Lua script failed: %s", error_message); diff --git a/src/lua/log.c b/src/lua/log.c index b49c003..6811ec3 100644 --- a/src/lua/log.c +++ b/src/lua/log.c @@ -2,7 +2,6 @@ #include #include "log.h" -#include "../any_log.h" static lua_CFunction lua_log_getinfo = NULL; @@ -10,15 +9,15 @@ static lua_CFunction lua_log_stringformat = NULL; static lua_CFunction lua_log_tostring = NULL; -static inline void lua_log_debuginfo(lua_State *state, const char **source, const char **func, - char buffer[], size_t size) +static inline void lua_log_debuginfo(lua_State *state, char buffer[], size_t size) { lua_pushcfunction(state, lua_log_getinfo); // Ignore the first frame (the c function itself) lua_pushnumber(state, 2); + // S: source, l: currentline, n: name - lua_pushstring(state, "Sln"); + lua_pushstring(state, "Sl"); if (lua_pcall(state, 2, 1, 0) == LUA_OK) { lua_getfield(state, -1, "short_src"); @@ -29,16 +28,10 @@ static inline void lua_log_debuginfo(lua_State *state, const char **source, cons if (!strncmp(shortsrc, "[string ", 8)) { int length = strlen(shortsrc); - snprintf(buffer, size, "lua %.*s", length - 9, shortsrc + 8); + snprintf(buffer, size, "%.*s", length - 9, shortsrc + 8); } else { - snprintf(buffer, size, "lua %s:%d", shortsrc, line); + snprintf(buffer, size, "%s:%d", shortsrc, line); } - - lua_getfield(state, -3, "name"); - const char *name = lua_tostring(state, -1); - - *source = buffer; - *func = name ? name : "..."; } else { log_trace("Failed to retrieve Lua debug information"); } @@ -61,11 +54,10 @@ static int lua_log_wrapper(lua_State *state, int skip_args, any_log_level_t leve lua_call(state, n_args, 1); const char *message = lua_tostring(state, -1); - const char *source = "?", *func = "?"; - char buffer[4096]; - lua_log_debuginfo(state, &source, &func, buffer, sizeof(buffer)); + char buffer[4096] = { "lua?" }; + lua_log_debuginfo(state, buffer, sizeof(buffer)); - any_log_format(level, source, func, "%s", message); + any_log_format(level, "lua_api", buffer, "%s", message); return 0; } @@ -113,11 +105,10 @@ static int lua_log_wrapperv(lua_State *state, any_log_level_t level) lua_remove(state, 1); luaL_checktype(state, 1, LUA_TTABLE); - const char *source = "?", *func = "?"; - char buffer[4096]; - lua_log_debuginfo(state, &source, &func, buffer, sizeof(buffer)); + char buffer[4096] = { "lua?" }; + lua_log_debuginfo(state, buffer, sizeof(buffer)); - any_log_value(level, source, func, message, + any_log_value(level, "lua_api", buffer, message, "g:value", ANY_LOG_FORMATTER(lua_print_value), state, NULL); return 0; diff --git a/src/lua/log.h b/src/lua/log.h new file mode 100644 index 0000000..32c235b --- /dev/null +++ b/src/lua/log.h @@ -0,0 +1,15 @@ +#ifndef COMET_LUA_LOG_H +#define COMET_LUA_LOG_H + +#include "api.h" +#include "../log.h" + +// Print the first value on the stack +// +void lua_print_value(FILE *stream, lua_State *state); + +void lua_print_value_at(FILE *stream, lua_State *state, int index); + +int lua_log_library(lua_State *state); + +#endif -- cgit v1.2.3