diff --git a/CMakeLists.txt b/CMakeLists.txt index b920fef..136701d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,12 +48,16 @@ set_target_properties(${EXECUTABLE_NAME} PROPERTIES LINK_FLAGS # Install the executable set(SERVICE_EXECUTABLE "/services/gh-wh-handler/${EXECUTABLE_NAME}") set(SERVICE_CONFIG "/services/gh-wh-handler/config.json") +set(SERVICE_LOGS "/services/gh-wh-handler/logs") configure_file( "${CMAKE_CURRENT_BINARY_DIR}/gh-wh-handler.service.in" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/gh-wh-handler.service" @ONLY) install(CODE "file(MAKE_DIRECTORY /services/gh-wh-handler)") +install(CODE "file(MAKE_DIRECTORY /services/gh-wh-handler/logs)") install(TARGETS ${EXECUTABLE_NAME} DESTINATION /services/gh-wh-handler) +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/config.json" + DESTINATION /services/gh-wh-handler) install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink /services/gh-wh-handler/${EXECUTABLE_NAME} /usr/bin/gh-wh-handler)") install(FILES "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/gh-wh-handler.service" diff --git a/build/config.json b/build/config.json new file mode 100644 index 0000000..387bb9f --- /dev/null +++ b/build/config.json @@ -0,0 +1,9 @@ +{ + "port": 65001, + "update-files": { + }, + "run-scripts": { + }, + "tokens": { + } +} diff --git a/build/gh-wh-handler.service.in b/build/gh-wh-handler.service.in index 2726a50..5f19333 100644 --- a/build/gh-wh-handler.service.in +++ b/build/gh-wh-handler.service.in @@ -3,7 +3,7 @@ Description=Runs github webhook handler After=network.target [Service] -ExecStart=@SERVICE_EXECUTABLE@ @SERVICE_CONFIG@ +ExecStart=@SERVICE_EXECUTABLE@ @SERVICE_CONFIG@ @SERVICE_LOGS@ Restart=always Type=simple diff --git a/build/uninstall.cmake.in b/build/uninstall.cmake.in index 894c2a8..62ea771 100644 --- a/build/uninstall.cmake.in +++ b/build/uninstall.cmake.in @@ -16,7 +16,7 @@ execute_process(COMMAND rm /usr/bin/gh-wh-handler) message(STATUS "[70%] Removing service executable from service directory...") file(REMOVE /services/gh-wh-handler/@EXECUTABLE_NAME@) -message(STATUS "[85%] Removing service directory...") -file(REMOVE /services/gh-wh-handler) +message(STATUS "[85%] Removing all log files...") +execute_process(COMMAND rm -fr /services/gh-wh-handler/logs) message(STATUS "[100%] Uninstallation complete!") diff --git a/include/config.hpp b/include/config.hpp index f7b8876..396d086 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -5,7 +5,7 @@ class Config { public: - static void create_config(); + static void create_config(std::string config_file_path); static nlohmann::json get_config(std::string config_file_path); static void open_config_menu(); diff --git a/src/config.cpp b/src/config.cpp index 3937349..15d37bb 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -5,7 +5,7 @@ #include "logger.hpp" -void Config::create_config() { +void Config::create_config(std::string config_file_path) { std::cout << "Creating config file" << std::endl; nlohmann::json config = { {"port", 65001}, @@ -13,20 +13,21 @@ void Config::create_config() { {"run-scripts", nlohmann::json::array()}, {"tokens", nlohmann::json::array()}, }; - if (!std::filesystem::exists("/services/gh-wh-handler")) { + std::string path_to_config = config_file_path.substr(0, config_file_path.find_last_of('/')); + if (!std::filesystem::exists(path_to_config)) { try { - std::filesystem::create_directories("/services/gh-wh-handler"); + std::filesystem::create_directories(path_to_config); } catch (std::exception &e) { - Logger::error("[Config] Error creating directory '/services/gh-wh-handler/': " + std::string(e.what())); + Logger::error("[Config] Error creating directory '" + path_to_config +"': " + std::string(e.what())); return; } } try { - std::ofstream config_file("/services/gh-wh-handler/config.json"); + std::ofstream config_file(config_file_path); config_file << config.dump(2); config_file.close(); } catch (std::exception& e) { - Logger::error("[Config] Error creating config file: " + std::string(e.what())); + Logger::fatal("[Config] Error creating config file: " + std::string(e.what())); } } @@ -39,7 +40,7 @@ nlohmann::json Config::get_config(std::string config_file_path) { config_file >> config; config_file.close(); } catch (std::exception& e) { - Logger::error("Error loading config file: " + std::string(e.what())); + Logger::fatal("Error loading config file: " + std::string(e.what())); } Logger::success("[Config] Loaded config file: " + config_file_path); diff --git a/src/endpoints/update-files.cpp b/src/endpoints/update-files.cpp index 858c661..8a171c3 100644 --- a/src/endpoints/update-files.cpp +++ b/src/endpoints/update-files.cpp @@ -131,12 +131,13 @@ crow::response update_files(const nlohmann::json& config_update_files, const nlo std::string remote_path = file[0]; std::string local_path = config_update_files[repo]["files"][remote_path]; - try { - std::filesystem::create_directories(local_path.substr(0, local_path.find_last_of('/'))); - } catch (const std::exception &e) { - Logger::error("[/update-files] Failed to create directories for " + local_path + ": " + std::string(e.what())); - continue; - } + if (local_path.find_last_of('/') != std::string::npos) + try { + std::filesystem::create_directories(local_path.substr(0, local_path.find_last_of('/'))); + } catch (const std::exception &e) { + Logger::error("[/update-files] Failed to create directories for " + local_path + ": " + std::string(e.what())); + continue; + } std::string command = "curl -s https://raw.githubusercontent.com/" + repo + "/" + ref + "/" + remote_path + " -o " + local_path; if (is_private) command += " -H 'Authorization: token " + token + "'"; diff --git a/src/logger.cpp b/src/logger.cpp index 14ec31e..60af669 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -1,4 +1,5 @@ #include "logger.hpp" +#include #include #include #include @@ -33,8 +34,29 @@ std::ofstream Logger::log_file; -void Logger::init(std::string log_file_path) { +void Logger::init(std::string logs_dir) { std::cout << "Initializing logger" << std::endl; + std::cout << "Logs directory: " << logs_dir << std::endl; + // check if logs_dir exists + if (!std::filesystem::exists(logs_dir)) { + try { + std::filesystem::create_directories(logs_dir); + } catch (std::exception &e) { + std::cerr << "Error creating logs directory: " << e.what() << std::endl; + std::exit(1); + } + } + // check if logs_dir ends with a slash + if (logs_dir.back() != '/') { + logs_dir += "/"; + } + std::time_t now = std::time(nullptr); + std::tm *now_tm = std::localtime(&now); + char time_buffer[80]; + std::strftime(time_buffer, sizeof(time_buffer), "%Y-%m-%d_%H-%M-%S", now_tm); + + std::string log_file_path = logs_dir + "gh-wh-handler_" + time_buffer + ".log"; + std::cout << "Log file: " << log_file_path << std::endl; Logger::log_file.open(log_file_path, std::ios::app); if (!Logger::log_file.is_open()) { @@ -68,7 +90,6 @@ void Logger::code(std::string message) { } void Logger::log(std::string message, std::string level) { - // Implement logger with terminal colors if terminal supports it std::string formatted_message = ""; if (isatty(fileno(stdout))) { if (level == "INFO ") { @@ -98,8 +119,8 @@ void Logger::log(std::string message, std::string level) { if (level == "CODE") { struct winsize w; ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); - int term_width = w.ws_col; - formatted_message += "\n" + std::string(term_width - 1, '=') + "\n" + message + "\n" + std::string(term_width - 1, '='); + int term_width = w.ws_col > 250 ? 250 : w.ws_col - 1; + formatted_message += "\n" + std::string(term_width, '=') + "\n" + message + "\n" + std::string(term_width, '='); } else { formatted_message += "[" + level + "] " + message; } @@ -110,15 +131,15 @@ void Logger::log(std::string message, std::string level) { if (level == "CODE") { struct winsize w; ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); - int term_width = w.ws_col; - Logger::log_file << std::string(term_width - 1, '=') << std::endl << message << std::endl << std::string(term_width - 1, '=') << std::endl; + int term_width = w.ws_col > 250 ? 250 : w.ws_col - 1; + Logger::log_file << std::string(term_width, '=') << std::endl << message << std::endl << std::string(term_width, '=') << std::endl; } else { Logger::log_file << "[" << level << "] " << message << std::endl; } Logger::log_file.flush(); - if (level == "FATAL") { + if (level == "FATAL ") { std::exit(1); } } diff --git a/src/main.cpp b/src/main.cpp index 521ef65..c29f5ab 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,8 +15,8 @@ void signal_handler(const int signum) { int main(int argc, char **argv) { // Check for config file argument, exit if it's not there - if (argc < 2 || argc > 3) { - std::cerr << "Usage: " << 0[argv] << " [--config]" << std::endl; + if (argc < 3 || argc > 4) { + std::cerr << "Usage: " << 0[argv] << " [--config]" << std::endl; return 1; } @@ -26,10 +26,11 @@ int main(int argc, char **argv) { std::strftime(time_buffer, sizeof(time_buffer), "%Y-%m-%d_%H-%M-%S", now_tm); std::string config_file_path = 1[argv]; - std::string log_file_path = config_file_path.substr(0, config_file_path.find_last_of("/")) + "/gh-wh-handler_" + time_buffer + ".log"; - Logger::init(log_file_path); + std::string logs_dir = 2[argv]; - if (argc == 3 && std::string(argv[2]) == "--config") { + Logger::init(logs_dir); + + if (argc == 4 && std::string(argv[3]) == "--config") { Config::open_config_menu(); return 0; } @@ -37,7 +38,7 @@ int main(int argc, char **argv) { // Check if config file exists if (!std::filesystem::exists(config_file_path)) { Logger::warn("Config file does not exist, creating..."); - Config::create_config(); + Config::create_config(config_file_path); } // Load configuration diff --git a/src/routes.cpp b/src/routes.cpp index 2a2ebb9..4a25a17 100644 --- a/src/routes.cpp +++ b/src/routes.cpp @@ -58,6 +58,10 @@ Routes::Routes(nlohmann::json config) { }); Logger::info("Starting server"); - this->app.port(config["port"].get()).multithreaded().run(); + try { + this->app.port(config["port"].get()).multithreaded().run(); + } catch (const std::exception &e) { + Logger::fatal("Error starting server: " + std::string(e.what())); + } Logger::info("Server stopped"); }