From 6468cc8d5552dc9d5be3abf289b7a5722944ac0b Mon Sep 17 00:00:00 2001 From: Nayan <33187059+GShadow5@users.noreply.github.com> Date: Thu, 8 May 2025 20:54:10 -0400 Subject: [PATCH] add logging code and get it setup --- .gitignore | 3 ++- Makefile | 2 +- logging.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++ logging.h | 21 +++++++++++++++++ webserver.c | 17 +++++++++----- 5 files changed, 103 insertions(+), 8 deletions(-) create mode 100644 logging.c create mode 100644 logging.h diff --git a/.gitignore b/.gitignore index 386f581..1d3c478 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.out -*.o \ No newline at end of file +*.o +/logs \ No newline at end of file diff --git a/Makefile b/Makefile index 5e0deab..482cf4e 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ RELEASE_FLAGS = -Wall -Wextra LFLAGS = -lpthread # Source files -SRCS = webserver.c client_handler.c request_handler.c http_stuff.c response_builder.c +SRCS = webserver.c client_handler.c request_handler.c http_stuff.c response_builder.c logging.c # Object files definition OBJS = $(SRCS:.c=.o) diff --git a/logging.c b/logging.c new file mode 100644 index 0000000..39789cd --- /dev/null +++ b/logging.c @@ -0,0 +1,68 @@ +#include "logging.h" + +FILE* log_file = NULL; + +pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER; + +int log_level = LOG_DEBUG; // Should pull from env variables eventually + +void set_log_level(int level) { log_level = level; } + +void open_log_file() { + log_file = fopen(LOG_FILE_NAME, "a"); + if (log_file == NULL) { + perror("Failed to open log file\n"); + } +} + +void close_log_file() { + if (log_file != NULL) { + fclose(log_file); + log_file = NULL; + } +} + +void log_message(int level, const char* fmt, ...) { + if (level < log_level) { + return; + } + char timestamp[32]; + time_t now = time(NULL); + struct tm* timeinfo = localtime(&now); + strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", timeinfo); + + char* level_str = level == LOG_DEBUG ? "DEBUG" + : level == LOG_INFO ? "INFO" + : level == LOG_WARN ? "WARN" + : "ERROR"; + + // Use variadic arguments to format string + va_list args; + va_start(args, fmt); + + // Log to console + fprintf(stderr, "[%s] [%s] ", timestamp, level_str); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + + // Reset variadic arguments + va_end(args); + va_start(args, fmt); + + // Log to file + pthread_mutex_lock(&log_mutex); + if (log_file == NULL) { + open_log_file(); + } + if (log_file == NULL) { + perror("Failed to open log file\n"); + } + if (log_file != NULL) { + fprintf(log_file, "[%s] [%s] ", timestamp, level_str); + vfprintf(log_file, fmt, args); + fprintf(log_file, "\n"); + } + fflush(log_file); + pthread_mutex_unlock(&log_mutex); + va_end(args); +} \ No newline at end of file diff --git a/logging.h b/logging.h new file mode 100644 index 0000000..b3c874c --- /dev/null +++ b/logging.h @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include +#include + +#define LOG_FILE_NAME "./logs/log.txt" + +#define LOG_DEBUG 0 +#define LOG_INFO 1 +#define LOG_WARN 2 +#define LOG_ERROR 3 + +void set_log_level(int level); + +void log_message(int level, const char* fmt, ...); + +void open_log_file(); + +void close_log_file(); \ No newline at end of file diff --git a/webserver.c b/webserver.c index 577da98..8e6cfde 100644 --- a/webserver.c +++ b/webserver.c @@ -9,17 +9,21 @@ #include #include "client_handler.h" +#include "logging.h" struct sockaddr_in server_addr; #define DEBUG 1 int main() { + open_log_file(); + set_log_level(DEBUG ? LOG_DEBUG : LOG_INFO); // Create socket int server = socket(AF_INET, SOCK_STREAM, 0); if (server < 0) { - perror("socket creation failed"); + log_message(LOG_ERROR, "Socket creation failed"); exit(1); } + log_message(LOG_INFO, "Socket created"); // Socket address config server_addr.sin_family = AF_INET; @@ -27,6 +31,7 @@ int main() { server_addr.sin_port = htons(8080); // Allow reuse of port when debugging if (DEBUG) { + log_message(LOG_DEBUG, "Allowing reuse of port"); int reuse = 1; setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int)); } @@ -34,13 +39,13 @@ int main() { // Bind socket if (bind(server, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { - perror("bind failed"); + log_message(LOG_ERROR, "Socket bind failed"); exit(1); } // Listen for connections if (listen(server, 5) < 0) { - perror("listen failed"); + log_message(LOG_ERROR, "Socket listen failed"); exit(1); } @@ -62,7 +67,7 @@ int main() { if (c == 'q') { close(server); shutdown(server, SHUT_RDWR); - printf("Server closed\n"); + log_message(LOG_INFO, "Shutting down server"); break; } } @@ -76,7 +81,7 @@ int main() { *client = accept(server, (struct sockaddr *)&client_addr, &client_len); if (*client < 0) { - perror("Failed to accept client"); + log_message(LOG_ERROR, "Socket accept failed"); continue; } @@ -86,6 +91,6 @@ int main() { } } } - + close_log_file(); return 0; } \ No newline at end of file