From 2686ca6bcf925a85a8f54312dd5413229d882f03 Mon Sep 17 00:00:00 2001 From: Timerix Date: Tue, 25 Nov 2025 18:22:55 +0500 Subject: [PATCH] implemented ServerLogger colors --- dependencies/tlibc | 2 +- include/tcp-chat/log.h | 16 +- src/cli/ClientCLI/ClientCLI.c | 2 +- src/cli/modes/ServerMode.c | 59 +++++++- src/cli/term.c | 189 ------------------------ src/cli/term.h | 47 ------ src/server/responses/GetMessageBlock.c | 3 +- src/server/responses/Login.c | 5 +- src/server/responses/Register.c | 5 +- src/server/responses/SendMessage.c | 3 +- src/server/responses/ServerPublicInfo.c | 3 +- src/server/responses/send_error.c | 3 +- src/server/responses/template | 3 +- src/server/server.c | 27 ++-- 14 files changed, 93 insertions(+), 274 deletions(-) delete mode 100644 src/cli/term.c delete mode 100644 src/cli/term.h diff --git a/dependencies/tlibc b/dependencies/tlibc index 82bd234..4c97787 160000 --- a/dependencies/tlibc +++ b/dependencies/tlibc @@ -1 +1 @@ -Subproject commit 82bd234d08e2556ae37fff8e414a72c5caaa355b +Subproject commit 4c97787c27af5b7867c8a1262a3383a84a1d4957 diff --git a/include/tcp-chat/log.h b/include/tcp-chat/log.h index feb6f90..2767422 100644 --- a/include/tcp-chat/log.h +++ b/include/tcp-chat/log.h @@ -10,17 +10,19 @@ typedef enum LogSeverity { LogSeverity_Error, } LogSeverity; -typedef void (*LogFunction_t)(void* logger, LogSeverity severity, cstr context, cstr msg); +typedef void (*LogFunction_t)(void* logger, cstr context, LogSeverity severity, cstr msg); -#define log(severity, context, format, ...) { \ + +// requires defined LOGGER, LOG_FUNC, LOG_CONTEXT +#define log(severity, format, ...) { \ if(LOG_FUNC) { \ char* ___log_msg = sprintf_malloc(format ,##__VA_ARGS__); \ - LOG_FUNC(LOGGER, severity, context, ___log_msg); \ + LOG_FUNC(LOGGER, LOG_CONTEXT, severity, ___log_msg); \ free(___log_msg); \ } \ } -#define logDebug(context, format, ...) log(LogSeverity_Debug, context, format ,##__VA_ARGS__) -#define logInfo(context, format, ...) log(LogSeverity_Info, context, format ,##__VA_ARGS__) -#define logWarn(context, format, ...) log(LogSeverity_Warn, context, format ,##__VA_ARGS__) -#define logError(context, format, ...) log(LogSeverity_Error, context, format ,##__VA_ARGS__) +#define logDebug(format, ...) log(LogSeverity_Debug, format ,##__VA_ARGS__) +#define logInfo(format, ...) log(LogSeverity_Info, format ,##__VA_ARGS__) +#define logWarn(format, ...) log(LogSeverity_Warn, format ,##__VA_ARGS__) +#define logError(format, ...) log(LogSeverity_Error, format ,##__VA_ARGS__) diff --git a/src/cli/ClientCLI/ClientCLI.c b/src/cli/ClientCLI/ClientCLI.c index c0bddce..655004c 100644 --- a/src/cli/ClientCLI/ClientCLI.c +++ b/src/cli/ClientCLI/ClientCLI.c @@ -1,7 +1,7 @@ #include "tlibc/filesystem.h" +#include "tlibc/term.h" #include "tcp-chat/common_constants.h" #include "cli/ClientCLI/ClientCLI.h" -#include "cli/term.h" #include "network/tcp-chat-protocol/v1.h" static const str greeting_art = STR( diff --git a/src/cli/modes/ServerMode.c b/src/cli/modes/ServerMode.c index 9897cb0..ae31be6 100644 --- a/src/cli/modes/ServerMode.c +++ b/src/cli/modes/ServerMode.c @@ -1,24 +1,62 @@ #include "modes.h" #include "tcp-chat/server.h" #include "tlibc/time.h" +#include "tlibc/term.h" +#include +typedef struct ServerLogger { + pthread_mutex_t mutex; +} ServerLogger; -static void log_func(void* logger, LogSeverity severity, cstr context, cstr msg){ - (void)logger; +void ServerLogger_construct(ServerLogger* self){ + try_fatal_stderrcode(pthread_mutex_init(&self->mutex, NULL)); + try_fatal_void(term_init()); +} + +void ServerLogger_destroy(ServerLogger* self){ + pthread_mutex_destroy(&self->mutex); + term_resetColors(); +} + +static void log_func(void* _logger, cstr context, LogSeverity severity, cstr msg){ + ServerLogger* logger = _logger; cstr severity_cstr; + Color16 fg; + switch(severity){ - default: severity_cstr = "INVALID_LOG_SEVERITY"; break; - case LogSeverity_Debug: severity_cstr = "DBUG"; break; - case LogSeverity_Info: severity_cstr = "INFO"; break; - case LogSeverity_Warn: severity_cstr = "WARN"; break; - case LogSeverity_Error: severity_cstr = "ERRR"; break; + default: + severity_cstr = "INVALID_LOG_SEVERITY"; + fg = Color16_DarkRed; + break; + case LogSeverity_Debug: + severity_cstr = "DBUG"; + fg = Color16_Gray; + break; + case LogSeverity_Info: + severity_cstr = "INFO"; + fg = Color16_White; + break; + case LogSeverity_Warn: + severity_cstr = "WARN"; + fg = Color16_Yellow; + break; + case LogSeverity_Error: + severity_cstr = "EROR"; + fg = Color16_Red; + break; } + pthread_mutex_lock(&logger->mutex); + DateTime dt; DateTime_getLocal(&dt); + term_setFgColor16(fg); printf("[" FMT_DateTime_text "][%s/%s]: %s\n", DT_expand(dt), context, severity_cstr, msg); + term_setFgColor16(Color16_Magenta); + + pthread_mutex_unlock(&logger->mutex); } Result(void) run_ServerMode(cstr config_path) { @@ -34,8 +72,13 @@ Result(void) run_ServerMode(cstr config_path) { Defer(Array_u8_destroy(&config_buf)); str config_str = Array_u8_castTo_str(config_buf, false); + // create logger + ServerLogger logger; + ServerLogger_construct(&logger); + Defer(ServerLogger_destroy(&logger)); + // init server - try(Server* server, p, Server_create(config_str, NULL, log_func)); + try(Server* server, p, Server_create(config_str, &logger, log_func)); Defer(Server_free(server)); // manually close file and free config_buf diff --git a/src/cli/term.c b/src/cli/term.c deleted file mode 100644 index 603d2ad..0000000 --- a/src/cli/term.c +++ /dev/null @@ -1,189 +0,0 @@ -#include "term.h" -#if defined(_WIN64) || defined(_WIN32) - #include - #define try_win_bool(EXPR) if(!(EXPR)) { Return RESULT_ERROR_FMT(#EXPR " failed with WindowsError %lu", GetLastError()); } -#else - #include - #include - #include - #define try_zero_errno(EXPR) if((EXPR) != 0) { \ - char* errno_s = strerror_malloc(errno); \ - ResultVar(void) err = RESULT_ERROR_FMT(#EXPR " failed with errno: %s", strerror(errno)); \ - free(errno_s); \ - Return err; \ - } -#endif - -Result(void) term_init(){ - Deferral(8); - -#if defined(_WIN64) || defined(_WIN32) - DWORD mode = 0; - HANDLE console_handle; - - // configure stdout - console_handle = GetStdHandle(STD_OUTPUT_HANDLE); - try_assert(console_handle != INVALID_HANDLE_VALUE); - GetConsoleMode(console_handle, &mode); - // https://learn.microsoft.com/en-us/windows/console/setconsolemode - mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; - mode |= ENABLE_PROCESSED_OUTPUT; - mode |= DISABLE_NEWLINE_AUTO_RETURN; - SetConsoleMode(console_handle, mode); - - // configure stderr - console_handle = GetStdHandle(STD_ERROR_HANDLE); - try_assert(console_handle != INVALID_HANDLE_VALUE); - GetConsoleMode(console_handle, &mode); - mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; - mode |= ENABLE_PROCESSED_OUTPUT; - mode |= DISABLE_NEWLINE_AUTO_RETURN; - SetConsoleMode(console_handle, mode); - - // configure stdin - console_handle = GetStdHandle(STD_INPUT_HANDLE); - try_assert(console_handle != INVALID_HANDLE_VALUE); - GetConsoleMode(console_handle, &mode); - mode |= ENABLE_VIRTUAL_TERMINAL_INPUT; - SetConsoleMode(console_handle, mode); -#endif - - Return RESULT_VOID; -} - -i64 getenv_int(const char* var_name){ - char* s = getenv(var_name); - if(s == NULL) - return -1; - return strtoll(s, NULL, 0); -} - -Result(void) term_getSize(TerminalSize* out) { - Deferral(4); - -#if defined(_WIN64) || defined(_WIN32) - // helps when STD_OUT is redirected to a file - HANDLE console_handle_stderr = GetStdHandle(STD_ERROR_HANDLE); - try_assert(console_handle_stderr != INVALID_HANDLE_VALUE) - CONSOLE_SCREEN_BUFFER_INFO consoleInfo; - try_win_bool(GetConsoleScreenBufferInfo(console_handle_stderr, &consoleInfo)); - - out->cols = consoleInfo.srWindow.Right - consoleInfo.srWindow.Left + 1; - out->rows = consoleInfo.srWindow.Bottom - consoleInfo.srWindow.Top + 1; -#else - struct winsize ws = {0}; - // try to get terminal size from stdin, stdout, stderr - if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == 0 || - ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0 || - ioctl(STDERR_FILENO, TIOCGWINSZ, &ws) == 0 ){ - out->cols = ws.ws_col; - out->rows = ws.ws_row; - } - // try to get size from environtent variables - else { - out->cols = getenv_int("COLUMNS"); - out->rows = getenv_int("LINES"); - } -#endif - - try_assert(out->cols > 0); - try_assert(out->rows > 0); - Return RESULT_VOID; -} - -Result(void) term_readLine(char* buf, u32 bufsize) { - Deferral(1); - if(fgets(buf, bufsize, stdin) == NULL){ - try_stderrcode(ferror(stdin)); - } - Return RESULT_VOID; -} - -Result(void) term_readLineHidden(char *buf, u32 bufsize) { - Deferral(4); - -#if defined(_WIN64) || defined(_WIN32) - HANDLE console_handle_stdin = GetStdHandle(STD_INPUT_HANDLE); - try_assert(console_handle_stdin != INVALID_HANDLE_VALUE); - DWORD old_mode; - GetConsoleMode(console_handle_stdin, &old_mode); - // turn off echo - DWORD new_mode = old_mode & ~(ENABLE_ECHO_INPUT); - SetConsoleMode(console_handle_stdin, new_mode); - // restore echo - Defer(SetConsoleMode(console_handle_stdin, old_mode)); -#else - struct termios old_mode, new_mode; - try_zero_errno(tcgetattr(STDIN_FILENO, &old_mode)); - new_mode = old_mode; - // turn off echo - new_mode.c_lflag &= ~(ECHO); - try_zero_errno(tcsetattr(STDIN_FILENO, TCSAFLUSH, &new_mode)); - // restore echo - Defer(tcsetattr(STDIN_FILENO, TCSAFLUSH, &old_mode)); -#endif - // read line - try_void(term_readLine(buf, bufsize)); - fputc('\n', stdout); - - Return RESULT_VOID; -} - -/* -Most of escape sequences can be found there -https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797 -*/ -#define ESC "\x1b" -#define CSI ESC"[" - -void term_setFgColor16(Color16 c){ - printf(CSI"%um", c); -} - -void term_setBgColor16(Color16 c){ - printf(CSI"%um", c + 10); -} - -void term_bold(){ - printf(CSI"1m"); -} - -void term_italic(){ - printf(CSI"3m"); -} - -void term_underline(){ - printf(CSI"4m"); -} - -void term_strikethrough(){ - printf(CSI"9m"); -} - -void term_resetCursor() { - printf(CSI"H"); -} - -void term_resetColors() { - printf(CSI"0m"); -} - -void term_clear() { - printf(CSI"0m" CSI"H" CSI"2J"); -} - -void term_eraseRow(){ - printf(CSI"2K\r"); -} - -void term_cursorMove(u16 row, u16 column) { - printf(CSI"%u;%uH", row, column); -} - -void term_cursorHide() { - printf(CSI"?25l"); -} - -void term_cursorShow() { - printf(CSI"?25h"); -} diff --git a/src/cli/term.h b/src/cli/term.h deleted file mode 100644 index a405408..0000000 --- a/src/cli/term.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once -#include "tlibc/errors.h" - -typedef struct TerminalSize { - i16 cols; - i16 rows; -} TerminalSize; - -typedef enum Color16 { - Color16_Black = 30, - Color16_DarkRed = 31, - Color16_DarkGreen = 32, - Color16_DarkYellow = 33, - Color16_DarkBlue = 34, - Color16_DarkMagenta = 35, - Color16_DarkCyan = 36, - Color16_Gray = 37, - Color16_DarkGray = 90, - Color16_Red = 91, - Color16_Green = 92, - Color16_Yellow = 93, - Color16_Blue = 94, - Color16_Magenta = 95, - Color16_Cyan = 96, - Color16_White = 97 -} Color16; - -Result(void) term_init(); -Result(void) term_getSize(TerminalSize* out); - -Result(void) term_readLine(char* buf, u32 bufsize); -Result(void) term_readLineHidden(char *buf, u32 bufsize); - -void term_setFgColor16(Color16 c); -void term_setBgColor16(Color16 c); -void term_bold(); -void term_italic(); -void term_underline(); -void term_strikethrough(); -void term_resetColors(); - -void term_clear(); -void term_eraseRow(); -void term_resetCursor(); -void term_cursorMove(u16 row, u16 column); -void term_cursorHide(); -void term_cursorShow(); diff --git a/src/server/responses/GetMessageBlock.c b/src/server/responses/GetMessageBlock.c index 867e751..d2ab40e 100644 --- a/src/server/responses/GetMessageBlock.c +++ b/src/server/responses/GetMessageBlock.c @@ -2,11 +2,12 @@ #define LOGGER conn->server->logger #define LOG_FUNC conn->server->log_func +#define LOG_CONTEXT log_ctx declare_RequestHandler(GetMessageBlock) { Deferral(4); - logInfo(log_ctx, "requested %s", req_type_name); + logInfo("requested %s", req_type_name); // receive request GetMessageBlockRequest req; diff --git a/src/server/responses/Login.c b/src/server/responses/Login.c index 563f58e..6e0dffc 100644 --- a/src/server/responses/Login.c +++ b/src/server/responses/Login.c @@ -2,11 +2,12 @@ #define LOGGER conn->server->logger #define LOG_FUNC conn->server->log_func +#define LOG_CONTEXT log_ctx declare_RequestHandler(Login) { Deferral(4); - logInfo(log_ctx, "requested %s", req_type_name); + logInfo("requested %s", req_type_name); // receive request LoginRequest req; @@ -72,7 +73,7 @@ declare_RequestHandler(Login) // authorize conn->authorized = true; - logInfo(log_ctx, "authorized user '%s'", username_str.data); + logInfo("authorized user '%s'", username_str.data); // send response LoginResponse res; diff --git a/src/server/responses/Register.c b/src/server/responses/Register.c index a20cdc4..29957e3 100644 --- a/src/server/responses/Register.c +++ b/src/server/responses/Register.c @@ -2,11 +2,12 @@ #define LOGGER conn->server->logger #define LOG_FUNC conn->server->log_func +#define LOG_CONTEXT log_ctx declare_RequestHandler(Register) { Deferral(4); - logInfo(log_ctx, "requested %s", req_type_name); + logInfo("requested %s", req_type_name); // receive request RegisterRequest req; @@ -74,7 +75,7 @@ declare_RequestHandler(Register) idb_unlockTable(conn->server->users.table); unlocked_users_cache_mutex = true; - logInfo(log_ctx, "registered user '%s'", username_str.data); + logInfo("registered user '%s'", username_str.data); // send response RegisterResponse res; diff --git a/src/server/responses/SendMessage.c b/src/server/responses/SendMessage.c index 57e4539..4b11245 100644 --- a/src/server/responses/SendMessage.c +++ b/src/server/responses/SendMessage.c @@ -2,11 +2,12 @@ #define LOGGER conn->server->logger #define LOG_FUNC conn->server->log_func +#define LOG_CONTEXT log_ctx declare_RequestHandler(SendMessage) { Deferral(4); - logInfo(log_ctx, "requested %s", req_type_name); + logInfo("requested %s", req_type_name); // receive request SendMessageRequest req; diff --git a/src/server/responses/ServerPublicInfo.c b/src/server/responses/ServerPublicInfo.c index 1832d65..c6bb85e 100644 --- a/src/server/responses/ServerPublicInfo.c +++ b/src/server/responses/ServerPublicInfo.c @@ -2,11 +2,12 @@ #define LOGGER conn->server->logger #define LOG_FUNC conn->server->log_func +#define LOG_CONTEXT log_ctx declare_RequestHandler(ServerPublicInfo) { Deferral(4); - logInfo(log_ctx, "requested %s", req_type_name); + logInfo("requested %s", req_type_name); // receive request ServerPublicInfoRequest req; diff --git a/src/server/responses/send_error.c b/src/server/responses/send_error.c index 8a8417d..ad337d0 100644 --- a/src/server/responses/send_error.c +++ b/src/server/responses/send_error.c @@ -2,6 +2,7 @@ #define LOGGER conn->server->logger #define LOG_FUNC conn->server->log_func +#define LOG_CONTEXT log_ctx Result(void) sendErrorMessage( cstr log_ctx, ClientConnection* conn, PacketHeader* res_head, @@ -13,7 +14,7 @@ Result(void) sendErrorMessage( if(msg.len > ERROR_MESSAGE_MAX_SIZE) msg.len = ERROR_MESSAGE_MAX_SIZE; - log(log_severity, log_ctx, FMT_str, msg.len, msg.data); + log(log_severity, FMT_str, msg.len, msg.data); ErrorMessage res; ErrorMessage_construct(&res, res_head, msg.len); diff --git a/src/server/responses/template b/src/server/responses/template index 48fc380..d8a5837 100644 --- a/src/server/responses/template +++ b/src/server/responses/template @@ -2,11 +2,12 @@ #define LOGGER conn->server->logger #define LOG_FUNC conn->server->log_func +#define LOG_CONTEXT log_ctx declare_RequestHandler(NAME) { Deferral(4); - logInfo(log_ctx, "requested %s", req_type_name); + logInfo("requested %s", req_type_name); // receive request NAME##Request req; diff --git a/src/server/server.c b/src/server/server.c index 68c54de..6bcc0b3 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -34,6 +34,7 @@ void Server_free(Server* self){ #define LOGGER logger #define LOG_FUNC log_func +#define LOG_CONTEXT log_ctx Result(Server*) Server_create(str config_str, void* logger, LogFunction_t log_func){ Deferral(16); @@ -46,7 +47,7 @@ Result(Server*) Server_create(str config_str, void* logger, LogFunction_t log_fu self->logger = logger; self->log_func = log_func; - logDebug(log_ctx, "parsing config"); + logDebug("parsing config"); // parse name str tmp_str = str_null; @@ -95,7 +96,7 @@ Result(Server*) Server_create(str config_str, void* logger, LogFunction_t log_fu try(self->db, p, idb_open(tmp_str, db_aes_key)); // build users cache - logDebug(log_ctx, "loading users..."); + logDebug("loading users..."); try(self->users.table, p, idb_getOrCreateTable(self->db, STR("users"), sizeof(UserInfo), false) ); @@ -115,11 +116,11 @@ Result(Server*) Server_create(str config_str, void* logger, LogFunction_t log_fu Return RESULT_ERROR_FMT("duplicate user name '"FMT_str"'", key.len, key.data); } } - logDebug(log_ctx, "loaded "FMT_u64" users", users_count); + logDebug("loaded "FMT_u64" users", users_count); // build messages cache - logDebug(log_ctx, "loading messages..."); + logDebug("loading messages..."); try(self->messages.blocks_table, p, idb_getOrCreateTable(self->db, STR("message_blocks"), sizeof(MessageBlock), false) ); @@ -148,7 +149,7 @@ Result(Server*) Server_create(str config_str, void* logger, LogFunction_t log_fu ); try_void(idb_getRow(self->messages.blocks_table, id, node->value.data, false)); } - logDebug(log_ctx, "loaded "FMT_u64" message blocks", message_blocks_count); + logDebug("loaded "FMT_u64" message blocks", message_blocks_count); success = true; Return RESULT_VALUE(p, self); @@ -156,21 +157,23 @@ Result(Server*) Server_create(str config_str, void* logger, LogFunction_t log_fu #undef LOGGER #undef LOG_FUNC +#undef LOG_CONTEXT #define LOGGER server->logger #define LOG_FUNC server->log_func +#define LOG_CONTEXT log_ctx Result(void) Server_run(Server* server){ Deferral(16); cstr log_ctx = "ListenerThread"; - logInfo(log_ctx, "starting server"); + logInfo("starting server"); - logDebug(log_ctx, "initializing main socket"); + logDebug("initializing main socket"); try(Socket main_socket, i, socket_open_TCP()); try_void(socket_bind(main_socket, server->local_end)); try_void(socket_listen(main_socket, 512)); str local_end_str = EndpointIPv4_toStr(server->local_end); Defer(free(local_end_str.data)); - logInfo(log_ctx, "server is listening at %s", local_end_str.data); + logInfo("server is listening at %s", local_end_str.data); u64 session_id = 1; while(true){ @@ -200,12 +203,12 @@ static void* handleConnection(void* _args){ if(r.error){ Error_addCallPos(r.error, ErrorCallPos_here()); str e_str = Error_toStr(r.error); - logError(log_ctx, FMT_str, e_str.len, e_str.data); + logError(FMT_str, e_str.len, e_str.data); str_free(e_str); Error_free(r.error); } - logInfo(log_ctx, "session end"); + logInfo("session end"); free(args); return NULL; } @@ -214,12 +217,12 @@ static Result(void) try_handleConnection(ConnectionHandlerArgs* args, cstr log_c Deferral(16); Server* server = args->server; - logInfo(log_ctx, "a client is trying to connect"); + logInfo("a client is trying to connect"); ClientConnection* conn = NULL; // establish encrypted connection try(conn, p, ClientConnection_accept(args)); Defer(ClientConnection_close(conn)); - logInfo(log_ctx, "session accepted"); + logInfo("session accepted"); // handle requests PacketHeader req_head;