implemented virtual logger

This commit is contained in:
Timerix 2025-11-18 16:01:39 +05:00
parent a1a11c10e2
commit 1b00f503c8
14 changed files with 139 additions and 51 deletions

2
dependencies/tlibc vendored

@ -1 +1 @@
Subproject commit bc415772486c087abd9cac9b9f2dc2b5dd5e98db Subproject commit c68e4e87b327ad21cd664e50ee2b5ef4ded3aed9

26
include/tcp-chat/log.h Normal file
View File

@ -0,0 +1,26 @@
#pragma once
#include <stdio.h>
#include "tlibc/std.h"
#include "tlibc/string/cstr.h"
typedef enum LogSeverity {
LogSeverity_Debug,
LogSeverity_Info,
LogSeverity_Warn,
LogSeverity_Error,
} LogSeverity;
typedef void (*LogFunction_t)(void* logger, LogSeverity severity, cstr context, cstr msg);
#define log(severity, context, format, ...) { \
if(LOG_FUNC) { \
char* ___log_msg = sprintf_malloc(format ,##__VA_ARGS__); \
LOG_FUNC(LOGGER, severity, context, ___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__)

View File

@ -1,9 +1,10 @@
#pragma once #pragma once
#include "tlibc/errors.h" #include "tlibc/errors.h"
#include "tlibc/string/str.h" #include "tlibc/string/str.h"
#include "tcp-chat/log.h"
typedef struct Server Server; typedef struct Server Server;
Result(Server*) Server_createFromConfig(str config_str); Result(Server*) Server_create(str config_str, void* logger, LogFunction_t log_func);
void Server_free(Server* server); void Server_free(Server* server);
Result(void) Server_run(Server* server); Result(void) Server_run(Server* server);

View File

@ -240,8 +240,8 @@ static Result(void) ClientCLI_saveServerInfo(ClientCLI* self,
memcpy(si.desc, server_description.data, si.desc_len); memcpy(si.desc, server_description.data, si.desc_len);
si.desc[si.desc_len] = 0; si.desc[si.desc_len] = 0;
// TODO: check cred->server_address_id_cache_map // TODO: check server_address_id_cache_map
(void)self;
// TODO: save server info to user's db // TODO: save server info to user's db
Return RESULT_VOID; Return RESULT_VOID;

View File

@ -1,6 +1,7 @@
#include "tlibc/tlibc.h" #include "tlibc/tlibc.h"
#include "tlibc/base64.h" #include "tlibc/base64.h"
#include "tlibc/filesystem.h" #include "tlibc/filesystem.h"
#include "tlibc/time.h"
#include "network/network.h" #include "network/network.h"
#include "cli/ClientCLI/ClientCLI.h" #include "cli/ClientCLI/ClientCLI.h"
#include "server/server_internal.h" #include "server/server_internal.h"
@ -8,6 +9,8 @@
#define _DEFAULT_CONFIG_PATH_CLIENT "tcp-chat-client.config" #define _DEFAULT_CONFIG_PATH_CLIENT "tcp-chat-client.config"
#define _DEFAULT_CONFIG_PATH_SERVER "tcp-chat-server.config" #define _DEFAULT_CONFIG_PATH_SERVER "tcp-chat-server.config"
#define arg_is(LITERAL) str_equals(arg_str, STR(LITERAL))
typedef enum ProgramMode { typedef enum ProgramMode {
ClientMode, ClientMode,
ServerMode, ServerMode,
@ -17,7 +20,24 @@ typedef enum ProgramMode {
RandomBytesBase64, RandomBytesBase64,
} ProgramMode; } ProgramMode;
#define arg_is(LITERAL) str_equals(arg_str, STR(LITERAL)) static void log_func(void* logger, LogSeverity severity, cstr context, cstr msg){
(void)logger;
cstr severity_cstr;
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;
}
DateTime dt;
DateTime_getLocal(&dt);
printf("[" FMT_DateTime_text "][%s/%s]: %s\n", DT_expand(dt), context, severity_cstr, msg);
}
int main(const int argc, cstr const* argv){ int main(const int argc, cstr const* argv){
Deferral(32); Deferral(32);
@ -163,7 +183,7 @@ int main(const int argc, cstr const* argv){
str config_str = Array_castTo_str(config_buf, false); str config_str = Array_castTo_str(config_buf, false);
config_buf.data = NULL; config_buf.data = NULL;
// init server // init server
try_fatal(Server* server, p, Server_createFromConfig(config_str)); try_fatal(Server* server, p, Server_create(config_str, NULL, log_func));
Defer(Server_free(server)); Defer(Server_free(server));
// manually close file and free config_buf // manually close file and free config_buf
file_close(config_file); file_close(config_file);

View File

@ -1,8 +0,0 @@
#pragma once
#include <stdio.h>
#define log(context, severity, format, ...) printf("[%s/" severity "]: " format "\n", context ,##__VA_ARGS__)
#define logDebug(context, format, ...) log(context, "DEBUG", format ,##__VA_ARGS__)
#define logInfo(context, format, ...) log(context, "INFO", format ,##__VA_ARGS__)
#define logWarn(context, format, ...) log(context, "WARN", format ,##__VA_ARGS__)
#define logError(context, format, ...) log(context, "ERROR", format ,##__VA_ARGS__)

View File

@ -1,5 +1,7 @@
#include "request_handlers.h" #include "request_handlers.h"
#define LOGGER server->logger
#define LOG_FUNC server->log_func
declare_RequestHandler(Login) declare_RequestHandler(Login)
{ {
@ -12,8 +14,10 @@ declare_RequestHandler(Login)
try_void(EncryptedSocketTCP_recvStruct(&conn->sock, &req)); try_void(EncryptedSocketTCP_recvStruct(&conn->sock, &req));
if(conn->authorized){ if(conn->authorized){
try_void(sendErrorMessage(log_ctx, false, conn, res_head, try_void(sendErrorMessage(server, log_ctx, conn, res_head,
STR("is logged in already"))); LogSeverity_Warn,
STR("is logged in already")
));
Return RESULT_VOID; Return RESULT_VOID;
} }
@ -21,7 +25,10 @@ declare_RequestHandler(Login)
str username_str = str_null; str username_str = str_null;
str username_check_error = validateUsername_cstr(req.username, &username_str); str username_check_error = validateUsername_cstr(req.username, &username_str);
if(username_check_error.data){ if(username_check_error.data){
try_void(sendErrorMessage(log_ctx, false, conn, res_head, username_check_error)); try_void(sendErrorMessage(server, log_ctx, conn, res_head,
LogSeverity_Warn,
username_check_error
));
Return RESULT_VOID; Return RESULT_VOID;
} }
@ -41,9 +48,11 @@ declare_RequestHandler(Login)
// try get id from name cache // try get id from name cache
u64* id_ptr = HashMap_tryGetPtr(&server->users_name_id_map, username_str); u64* id_ptr = HashMap_tryGetPtr(&server->users_name_id_map, username_str);
if(id_ptr == NULL){ if(id_ptr == NULL){
try_void(sendErrorMessage_f(log_ctx, false, conn, res_head, try_void(sendErrorMessage_f(server, log_ctx, conn, res_head,
LogSeverity_Warn,
"Username '%s' is not registered\n", "Username '%s' is not registered\n",
username_str.data)); username_str.data
));
Return RESULT_VOID; Return RESULT_VOID;
} }
u64 user_id = *id_ptr; u64 user_id = *id_ptr;
@ -54,8 +63,10 @@ declare_RequestHandler(Login)
// validate token hash // validate token hash
if(memcmp(token_hash, u->token_hash, sizeof(token_hash)) != 0){ if(memcmp(token_hash, u->token_hash, sizeof(token_hash)) != 0){
try_void(sendErrorMessage(log_ctx, false, conn, res_head, try_void(sendErrorMessage(server, log_ctx, conn, res_head,
STR("wrong password"))); LogSeverity_Warn,
STR("wrong password")
));
Return RESULT_VOID; Return RESULT_VOID;
} }

View File

@ -1,5 +1,8 @@
#include "request_handlers.h" #include "request_handlers.h"
#define LOGGER server->logger
#define LOG_FUNC server->log_func
declare_RequestHandler(Register) declare_RequestHandler(Register)
{ {
Deferral(4); Deferral(4);
@ -14,7 +17,10 @@ declare_RequestHandler(Register)
str username_str = str_null; str username_str = str_null;
str username_check_error = validateUsername_cstr(req.username, &username_str); str username_check_error = validateUsername_cstr(req.username, &username_str);
if(username_check_error.data){ if(username_check_error.data){
try_void(sendErrorMessage(log_ctx, false, conn, res_head, username_check_error)); try_void(sendErrorMessage(server, log_ctx, conn, res_head,
LogSeverity_Warn,
username_check_error
));
Return RESULT_VOID; Return RESULT_VOID;
} }
@ -25,7 +31,8 @@ declare_RequestHandler(Register)
// check if name is taken // check if name is taken
if(HashMap_tryGetPtr(&server->users_name_id_map, username_str) != NULL){ if(HashMap_tryGetPtr(&server->users_name_id_map, username_str) != NULL){
try_void(sendErrorMessage_f(log_ctx, false, conn, res_head, try_void(sendErrorMessage_f(server, log_ctx, conn, res_head,
LogSeverity_Warn,
"Username'%s' already exists\n", "Username'%s' already exists\n",
username_str.data)); username_str.data));
Return RESULT_VOID; Return RESULT_VOID;

View File

@ -1,5 +1,8 @@
#include "request_handlers.h" #include "request_handlers.h"
#define LOGGER server->logger
#define LOG_FUNC server->log_func
declare_RequestHandler(ServerPublicInfo) declare_RequestHandler(ServerPublicInfo)
{ {
Deferral(4); Deferral(4);
@ -14,7 +17,8 @@ declare_RequestHandler(ServerPublicInfo)
Array(u8) content; Array(u8) content;
switch(req.property){ switch(req.property){
default:{ default:{
try_void(sendErrorMessage_f(log_ctx, false, conn, res_head, try_void(sendErrorMessage_f(server, log_ctx, conn, res_head,
LogSeverity_Warn,
"Unknown ServerPublicInfo property %u", "Unknown ServerPublicInfo property %u",
req.property)); req.property));
Return RESULT_VOID; Return RESULT_VOID;

View File

@ -1,20 +1,22 @@
#pragma once #pragma once
#include "network/tcp-chat-protocol/v1.h" #include "network/tcp-chat-protocol/v1.h"
#include "server/server_internal.h" #include "server/server_internal.h"
#include "log.h"
Result(void) sendErrorMessage(cstr log_ctx, bool logAsError, Result(void) sendErrorMessage(
Server* server, cstr log_ctx,
ClientConnection* conn, PacketHeader* res_head, ClientConnection* conn, PacketHeader* res_head,
str msg); LogSeverity log_severity, str msg);
Result(void) __sendErrorMessage_fv(cstr log_ctx, bool logAsError, Result(void) __sendErrorMessage_fv(
Server* server, cstr log_ctx,
ClientConnection* conn, PacketHeader* res_head, ClientConnection* conn, PacketHeader* res_head,
cstr format, va_list argv); LogSeverity log_severity, cstr format, va_list argv);
Result(void) sendErrorMessage_f(cstr log_ctx, bool logAsError, Result(void) sendErrorMessage_f(
Server* server, cstr log_ctx,
ClientConnection* conn, PacketHeader* res_head, ClientConnection* conn, PacketHeader* res_head,
cstr format, ...) ATTRIBUTE_CHECK_FORMAT_PRINTF(5, 6); LogSeverity log_severity, cstr format, ...) ATTRIBUTE_CHECK_FORMAT_PRINTF(6, 7);
#define declare_RequestHandler(TYPE) \ #define declare_RequestHandler(TYPE) \

View File

@ -1,9 +1,12 @@
#include "request_handlers.h" #include "request_handlers.h"
#include "log.h"
Result(void) sendErrorMessage(cstr log_ctx, bool logAsError, #define LOGGER server->logger
#define LOG_FUNC server->log_func
Result(void) sendErrorMessage(
Server* server, cstr log_ctx,
ClientConnection* conn, PacketHeader* res_head, ClientConnection* conn, PacketHeader* res_head,
str msg) LogSeverity log_severity, str msg)
{ {
Deferral(1); Deferral(1);
@ -11,11 +14,7 @@ Result(void) sendErrorMessage(cstr log_ctx, bool logAsError,
if(msg.size > ERROR_MESSAGE_MAX_SIZE) if(msg.size > ERROR_MESSAGE_MAX_SIZE)
msg.size = ERROR_MESSAGE_MAX_SIZE; msg.size = ERROR_MESSAGE_MAX_SIZE;
if(logAsError){ log(log_severity, log_ctx, FMT_str, msg.size, msg.data);
logError(log_ctx, FMT_str, msg.size, msg.data);
} else {
logWarn(log_ctx, FMT_str, msg.size, msg.data);
}
ErrorMessage res; ErrorMessage res;
ErrorMessage_construct(&res, res_head, msg.size); ErrorMessage_construct(&res, res_head, msg.size);
@ -26,29 +25,31 @@ Result(void) sendErrorMessage(cstr log_ctx, bool logAsError,
Return RESULT_VOID; Return RESULT_VOID;
} }
Result(void) __sendErrorMessage_fv(cstr log_ctx, bool logAsError, Result(void) __sendErrorMessage_fv(
Server* server, cstr log_ctx,
ClientConnection* conn, PacketHeader* res_head, ClientConnection* conn, PacketHeader* res_head,
cstr format, va_list argv) LogSeverity log_severity, cstr format, va_list argv)
{ {
Deferral(4); Deferral(4);
str msg = str_from_cstr(vsprintf_malloc(format, argv)); str msg = str_from_cstr(vsprintf_malloc(format, argv));
Defer(free(msg.data)); Defer(free(msg.data));
try_void(sendErrorMessage(log_ctx, logAsError, conn, res_head, msg)); try_void(sendErrorMessage(server, log_ctx, conn, res_head, log_severity, msg));
Return RESULT_VOID; Return RESULT_VOID;
} }
Result(void) sendErrorMessage_f(cstr log_ctx, bool logAsError, Result(void) sendErrorMessage_f(
Server* server, cstr log_ctx,
ClientConnection* conn, PacketHeader* res_head, ClientConnection* conn, PacketHeader* res_head,
cstr format, ...) LogSeverity log_severity, cstr format, ...)
{ {
Deferral(1); Deferral(1);
va_list argv; va_list argv;
va_start(argv, format); va_start(argv, format);
Defer(va_end(argv)); Defer(va_end(argv));
try_void(__sendErrorMessage_fv(log_ctx, logAsError, conn, res_head, format, argv)); try_void(__sendErrorMessage_fv(server, log_ctx, conn, res_head, log_severity, format, argv));
Return RESULT_VOID; Return RESULT_VOID;
} }

View File

@ -1,5 +1,8 @@
#include "request_handlers.h" #include "request_handlers.h"
#define LOGGER server->logger
#define LOG_FUNC server->log_func
declare_RequestHandler(NAME) declare_RequestHandler(NAME)
{ {
Deferral(4); Deferral(4);

View File

@ -4,7 +4,6 @@
#include "tlibc/base64.h" #include "tlibc/base64.h"
#include "server/server_internal.h" #include "server/server_internal.h"
#include "config.h" #include "config.h"
#include "log.h"
#include "network/tcp-chat-protocol/v1.h" #include "network/tcp-chat-protocol/v1.h"
#include "server/request_handlers/request_handlers.h" #include "server/request_handlers/request_handlers.h"
@ -26,16 +25,23 @@ void Server_free(Server* self){
HashMap_destroy(&self->users_name_id_map); HashMap_destroy(&self->users_name_id_map);
} }
Result(Server*) Server_createFromConfig(str config_str){
#define LOGGER logger
#define LOG_FUNC log_func
Result(Server*) Server_create(str config_str, void* logger, LogFunction_t log_func){
Deferral(16); Deferral(16);
cstr log_ctx = "ServerInit"; cstr log_ctx = "ServerInit";
logInfo(log_ctx, "parsing config");
Server* server = (Server*)malloc(sizeof(Server)); Server* server = (Server*)malloc(sizeof(Server));
memset(server, 0, sizeof(Server)); memset(server, 0, sizeof(Server));
bool success = false; bool success = false;
Defer(if(!success) Server_free(server)); Defer(if(!success) Server_free(server));
server->logger = logger;
server->log_func = log_func;
logDebug(log_ctx, "parsing config");
// parse name // parse name
str tmp_str = str_null; str tmp_str = str_null;
try_void(config_findValue(config_str, STR("name"), &tmp_str, true)); try_void(config_findValue(config_str, STR("name"), &tmp_str, true));
@ -103,6 +109,11 @@ Result(Server*) Server_createFromConfig(str config_str){
Return RESULT_VALUE(p, server); Return RESULT_VALUE(p, server);
} }
#undef LOGGER
#undef LOG_FUNC
#define LOGGER server->logger
#define LOG_FUNC server->log_func
Result(void) Server_run(Server* server){ Result(void) Server_run(Server* server){
Deferral(16); Deferral(16);
cstr log_ctx = "ListenerThread"; cstr log_ctx = "ListenerThread";
@ -133,8 +144,10 @@ Result(void) Server_run(Server* server){
Return RESULT_VOID; Return RESULT_VOID;
} }
static void* handleConnection(void* _args){ static void* handleConnection(void* _args){
ConnectionHandlerArgs* args = (ConnectionHandlerArgs*)_args; ConnectionHandlerArgs* args = (ConnectionHandlerArgs*)_args;
Server* server = args->server;
char log_ctx[64]; char log_ctx[64];
sprintf(log_ctx, "Session-"FMT_x64, args->session_id); sprintf(log_ctx, "Session-"FMT_x64, args->session_id);
@ -155,6 +168,7 @@ static void* handleConnection(void* _args){
static Result(void) try_handleConnection(ConnectionHandlerArgs* args, cstr log_ctx){ static Result(void) try_handleConnection(ConnectionHandlerArgs* args, cstr log_ctx){
Deferral(16); Deferral(16);
Server* server = args->server;
ClientConnection* conn = NULL; ClientConnection* conn = NULL;
// establish encrypted connection // establish encrypted connection
try(conn, p, ClientConnection_accept(args)); try(conn, p, ClientConnection_accept(args));
@ -174,7 +188,8 @@ static Result(void) try_handleConnection(ConnectionHandlerArgs* args, cstr log_c
switch(req_head.type){ switch(req_head.type){
// send error message and close connection // send error message and close connection
default: default:
try_void(sendErrorMessage_f(log_ctx, false, conn, &res_head, try_void(sendErrorMessage_f(server, log_ctx, conn, &res_head,
LogSeverity_Error,
"Received unexpected packet of type %u", "Received unexpected packet of type %u",
req_head.type)); req_head.type));
Return RESULT_VOID; Return RESULT_VOID;

View File

@ -12,6 +12,11 @@
typedef struct ClientConnection ClientConnection; typedef struct ClientConnection ClientConnection;
typedef struct Server { typedef struct Server {
/* from constructor */
void* logger;
LogFunction_t log_func;
/* from config */
str name; str name;
str description; str description;
u64 landing_channel_id; u64 landing_channel_id;
@ -19,6 +24,7 @@ typedef struct Server {
br_rsa_private_key rsa_sk; br_rsa_private_key rsa_sk;
br_rsa_public_key rsa_pk; br_rsa_public_key rsa_pk;
/* database and cache */
IncrementalDB* db; IncrementalDB* db;
Table* db_users_table; Table* db_users_table;
pthread_mutex_t users_cache_mutex; pthread_mutex_t users_cache_mutex;