Fix logging

Signed-off-by: Tiago Garcia <tiago.rgarcia@ua.pt>
This commit is contained in:
Tiago Garcia 2024-07-19 12:52:41 +01:00
parent 5339c1f791
commit 04683c8ebc
Signed by: TiagoRG
GPG Key ID: DFCD48E3F420DB42
10 changed files with 72 additions and 31 deletions

View File

@ -48,12 +48,16 @@ set_target_properties(${EXECUTABLE_NAME} PROPERTIES LINK_FLAGS
# Install the executable # Install the executable
set(SERVICE_EXECUTABLE "/services/gh-wh-handler/${EXECUTABLE_NAME}") set(SERVICE_EXECUTABLE "/services/gh-wh-handler/${EXECUTABLE_NAME}")
set(SERVICE_CONFIG "/services/gh-wh-handler/config.json") set(SERVICE_CONFIG "/services/gh-wh-handler/config.json")
set(SERVICE_LOGS "/services/gh-wh-handler/logs")
configure_file( configure_file(
"${CMAKE_CURRENT_BINARY_DIR}/gh-wh-handler.service.in" "${CMAKE_CURRENT_BINARY_DIR}/gh-wh-handler.service.in"
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/gh-wh-handler.service" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/gh-wh-handler.service"
@ONLY) @ONLY)
install(CODE "file(MAKE_DIRECTORY /services/gh-wh-handler)") 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(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 install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
/services/gh-wh-handler/${EXECUTABLE_NAME} /usr/bin/gh-wh-handler)") /services/gh-wh-handler/${EXECUTABLE_NAME} /usr/bin/gh-wh-handler)")
install(FILES "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/gh-wh-handler.service" install(FILES "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/gh-wh-handler.service"

9
build/config.json Normal file
View File

@ -0,0 +1,9 @@
{
"port": 65001,
"update-files": {
},
"run-scripts": {
},
"tokens": {
}
}

View File

@ -3,7 +3,7 @@ Description=Runs github webhook handler
After=network.target After=network.target
[Service] [Service]
ExecStart=@SERVICE_EXECUTABLE@ @SERVICE_CONFIG@ ExecStart=@SERVICE_EXECUTABLE@ @SERVICE_CONFIG@ @SERVICE_LOGS@
Restart=always Restart=always
Type=simple Type=simple

View File

@ -16,7 +16,7 @@ execute_process(COMMAND rm /usr/bin/gh-wh-handler)
message(STATUS "[70%] Removing service executable from service directory...") message(STATUS "[70%] Removing service executable from service directory...")
file(REMOVE /services/gh-wh-handler/@EXECUTABLE_NAME@) file(REMOVE /services/gh-wh-handler/@EXECUTABLE_NAME@)
message(STATUS "[85%] Removing service directory...") message(STATUS "[85%] Removing all log files...")
file(REMOVE /services/gh-wh-handler) execute_process(COMMAND rm -fr /services/gh-wh-handler/logs)
message(STATUS "[100%] Uninstallation complete!") message(STATUS "[100%] Uninstallation complete!")

View File

@ -5,7 +5,7 @@
class Config { class Config {
public: 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 nlohmann::json get_config(std::string config_file_path);
static void open_config_menu(); static void open_config_menu();

View File

@ -5,7 +5,7 @@
#include "logger.hpp" #include "logger.hpp"
void Config::create_config() { void Config::create_config(std::string config_file_path) {
std::cout << "Creating config file" << std::endl; std::cout << "Creating config file" << std::endl;
nlohmann::json config = { nlohmann::json config = {
{"port", 65001}, {"port", 65001},
@ -13,20 +13,21 @@ void Config::create_config() {
{"run-scripts", nlohmann::json::array()}, {"run-scripts", nlohmann::json::array()},
{"tokens", 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 { try {
std::filesystem::create_directories("/services/gh-wh-handler"); std::filesystem::create_directories(path_to_config);
} catch (std::exception &e) { } 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; return;
} }
} }
try { 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 << config.dump(2);
config_file.close(); config_file.close();
} catch (std::exception& e) { } 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 >> config;
config_file.close(); config_file.close();
} catch (std::exception& e) { } 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); Logger::success("[Config] Loaded config file: " + config_file_path);

View File

@ -131,12 +131,13 @@ crow::response update_files(const nlohmann::json& config_update_files, const nlo
std::string remote_path = file[0]; std::string remote_path = file[0];
std::string local_path = config_update_files[repo]["files"][remote_path]; std::string local_path = config_update_files[repo]["files"][remote_path];
try { if (local_path.find_last_of('/') != std::string::npos)
std::filesystem::create_directories(local_path.substr(0, local_path.find_last_of('/'))); try {
} catch (const std::exception &e) { std::filesystem::create_directories(local_path.substr(0, local_path.find_last_of('/')));
Logger::error("[/update-files] Failed to create directories for " + local_path + ": " + std::string(e.what())); } catch (const std::exception &e) {
continue; 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; std::string command = "curl -s https://raw.githubusercontent.com/" + repo + "/" + ref + "/" + remote_path + " -o " + local_path;
if (is_private) command += " -H 'Authorization: token " + token + "'"; if (is_private) command += " -H 'Authorization: token " + token + "'";

View File

@ -1,4 +1,5 @@
#include "logger.hpp" #include "logger.hpp"
#include <filesystem>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <ctime> #include <ctime>
@ -33,8 +34,29 @@
std::ofstream Logger::log_file; 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 << "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; std::cout << "Log file: " << log_file_path << std::endl;
Logger::log_file.open(log_file_path, std::ios::app); Logger::log_file.open(log_file_path, std::ios::app);
if (!Logger::log_file.is_open()) { 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) { void Logger::log(std::string message, std::string level) {
// Implement logger with terminal colors if terminal supports it
std::string formatted_message = ""; std::string formatted_message = "";
if (isatty(fileno(stdout))) { if (isatty(fileno(stdout))) {
if (level == "INFO ") { if (level == "INFO ") {
@ -98,8 +119,8 @@ void Logger::log(std::string message, std::string level) {
if (level == "CODE") { if (level == "CODE") {
struct winsize w; struct winsize w;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
int term_width = w.ws_col; int term_width = w.ws_col > 250 ? 250 : w.ws_col - 1;
formatted_message += "\n" + std::string(term_width - 1, '=') + "\n" + message + "\n" + std::string(term_width - 1, '='); formatted_message += "\n" + std::string(term_width, '=') + "\n" + message + "\n" + std::string(term_width, '=');
} else { } else {
formatted_message += "[" + level + "] " + message; formatted_message += "[" + level + "] " + message;
} }
@ -110,15 +131,15 @@ void Logger::log(std::string message, std::string level) {
if (level == "CODE") { if (level == "CODE") {
struct winsize w; struct winsize w;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
int term_width = w.ws_col; int term_width = w.ws_col > 250 ? 250 : w.ws_col - 1;
Logger::log_file << std::string(term_width - 1, '=') << std::endl << message << std::endl << std::string(term_width - 1, '=') << std::endl; Logger::log_file << std::string(term_width, '=') << std::endl << message << std::endl << std::string(term_width, '=') << std::endl;
} else { } else {
Logger::log_file << "[" << level << "] " << message << std::endl; Logger::log_file << "[" << level << "] " << message << std::endl;
} }
Logger::log_file.flush(); Logger::log_file.flush();
if (level == "FATAL") { if (level == "FATAL ") {
std::exit(1); std::exit(1);
} }
} }

View File

@ -15,8 +15,8 @@ void signal_handler(const int signum) {
int main(int argc, char **argv) { int main(int argc, char **argv) {
// Check for config file argument, exit if it's not there // Check for config file argument, exit if it's not there
if (argc < 2 || argc > 3) { if (argc < 3 || argc > 4) {
std::cerr << "Usage: " << 0[argv] << " </path/to/config.json> [--config]" << std::endl; std::cerr << "Usage: " << 0[argv] << " </path/to/config.json> </path/to/logs_dir> [--config]" << std::endl;
return 1; 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::strftime(time_buffer, sizeof(time_buffer), "%Y-%m-%d_%H-%M-%S", now_tm);
std::string config_file_path = 1[argv]; 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"; std::string logs_dir = 2[argv];
Logger::init(log_file_path);
if (argc == 3 && std::string(argv[2]) == "--config") { Logger::init(logs_dir);
if (argc == 4 && std::string(argv[3]) == "--config") {
Config::open_config_menu(); Config::open_config_menu();
return 0; return 0;
} }
@ -37,7 +38,7 @@ int main(int argc, char **argv) {
// Check if config file exists // Check if config file exists
if (!std::filesystem::exists(config_file_path)) { if (!std::filesystem::exists(config_file_path)) {
Logger::warn("Config file does not exist, creating..."); Logger::warn("Config file does not exist, creating...");
Config::create_config(); Config::create_config(config_file_path);
} }
// Load configuration // Load configuration

View File

@ -58,6 +58,10 @@ Routes::Routes(nlohmann::json config) {
}); });
Logger::info("Starting server"); Logger::info("Starting server");
this->app.port(config["port"].get<int>()).multithreaded().run(); try {
this->app.port(config["port"].get<int>()).multithreaded().run();
} catch (const std::exception &e) {
Logger::fatal("Error starting server: " + std::string(e.what()));
}
Logger::info("Server stopped"); Logger::info("Server stopped");
} }