config: Add 1 and update 10 files
This commit is contained in:
@@ -42,10 +42,11 @@ target_include_directories(${PROJECT_NAME} PRIVATE
|
||||
find_package(OpenSSL REQUIRED)
|
||||
find_package(Drogon CONFIG REQUIRED)
|
||||
find_package(nlohmann_json REQUIRED)
|
||||
find_package(spdlog REQUIRED)
|
||||
|
||||
# Link libraries for main executable
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
nlohmann_json::nlohmann_json Drogon::Drogon
|
||||
nlohmann_json::nlohmann_json Drogon::Drogon spdlog::spdlog
|
||||
/usr/local/lib/libpgcommon.a /usr/local/lib/libpgport.a
|
||||
lzma dl)
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#include "config.hpp"
|
||||
#include "logger.hpp"
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
@@ -11,17 +12,17 @@ namespace simple_object_storage {
|
||||
bool load_config(const std::string& config_path, ServerConfig& config) {
|
||||
try {
|
||||
if (config_path.empty()) {
|
||||
std::cerr << "Config path is empty" << std::endl;
|
||||
LOG_ERROR("Config path is empty");
|
||||
return false;
|
||||
}
|
||||
if (!std::filesystem::exists(config_path)) {
|
||||
std::cerr << "Config file does not exist: " << config_path << std::endl;
|
||||
LOG_ERROR("Config file does not exist: {}", config_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ifstream file(config_path);
|
||||
if (!file.is_open()) {
|
||||
std::cerr << "Failed to open config file: " << config_path << std::endl;
|
||||
LOG_ERROR("Failed to open config file: {}", config_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -78,11 +79,22 @@ bool load_config(const std::string& config_path, ServerConfig& config) {
|
||||
}
|
||||
}
|
||||
|
||||
// Parse logging configuration
|
||||
if (j.contains("logging")) {
|
||||
const auto& logging = j["logging"];
|
||||
if (logging.contains("log_file_path")) {
|
||||
config.log_file_path = logging["log_file_path"].get<std::string>();
|
||||
}
|
||||
if (logging.contains("log_level")) {
|
||||
config.log_level = logging["log_level"].get<std::string>();
|
||||
}
|
||||
}
|
||||
|
||||
// Line number accuracy improved
|
||||
|
||||
return true;
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Error parsing config file: " << e.what() << std::endl;
|
||||
LOG_ERROR("Error parsing config file: {}", e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@@ -22,6 +22,10 @@ struct ServerConfig {
|
||||
// Rate limiting configuration
|
||||
int auth_rate_limit = 5; // Maximum number of auth attempts
|
||||
int auth_window_seconds = 300; // Time window in seconds (5 minutes)
|
||||
|
||||
// Logging configuration
|
||||
std::filesystem::path log_file_path = "/data/sos.log"; // Path to log file (empty string disables file logging)
|
||||
std::string log_level = "info"; // Log level: trace, debug, info, warn, error, critical
|
||||
};
|
||||
|
||||
bool load_config(const std::string& config_path, ServerConfig& config);
|
||||
|
81
src/logger.hpp
Normal file
81
src/logger.hpp
Normal file
@@ -0,0 +1,81 @@
|
||||
#pragma once
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||
#include <spdlog/sinks/rotating_file_sink.h>
|
||||
#include <memory>
|
||||
|
||||
namespace simple_object_storage {
|
||||
|
||||
class Logger {
|
||||
public:
|
||||
static void init(const std::string& log_level = "info",
|
||||
const std::string& log_file = "",
|
||||
size_t max_file_size = 10 * 1024 * 1024,
|
||||
size_t max_files = 3) {
|
||||
|
||||
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
|
||||
console_sink->set_level(spdlog::level::trace);
|
||||
|
||||
std::vector<spdlog::sink_ptr> sinks{console_sink};
|
||||
|
||||
if (!log_file.empty()) {
|
||||
auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(
|
||||
log_file, max_file_size, max_files);
|
||||
file_sink->set_level(spdlog::level::trace);
|
||||
sinks.push_back(file_sink);
|
||||
}
|
||||
|
||||
auto logger = std::make_shared<spdlog::logger>("sos", sinks.begin(), sinks.end());
|
||||
|
||||
if (log_level == "trace") {
|
||||
logger->set_level(spdlog::level::trace);
|
||||
} else if (log_level == "debug") {
|
||||
logger->set_level(spdlog::level::debug);
|
||||
} else if (log_level == "info") {
|
||||
logger->set_level(spdlog::level::info);
|
||||
} else if (log_level == "warn" || log_level == "warning") {
|
||||
logger->set_level(spdlog::level::warn);
|
||||
} else if (log_level == "error") {
|
||||
logger->set_level(spdlog::level::err);
|
||||
} else if (log_level == "critical") {
|
||||
logger->set_level(spdlog::level::critical);
|
||||
} else {
|
||||
logger->set_level(spdlog::level::info);
|
||||
}
|
||||
|
||||
logger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] [%t] %v");
|
||||
|
||||
spdlog::set_default_logger(logger);
|
||||
spdlog::flush_every(std::chrono::seconds(3));
|
||||
}
|
||||
|
||||
static std::shared_ptr<spdlog::logger> get() {
|
||||
return spdlog::default_logger();
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef LOG_TRACE
|
||||
#undef LOG_TRACE
|
||||
#endif
|
||||
#ifdef LOG_DEBUG
|
||||
#undef LOG_DEBUG
|
||||
#endif
|
||||
#ifdef LOG_INFO
|
||||
#undef LOG_INFO
|
||||
#endif
|
||||
#ifdef LOG_WARN
|
||||
#undef LOG_WARN
|
||||
#endif
|
||||
#ifdef LOG_ERROR
|
||||
#undef LOG_ERROR
|
||||
#endif
|
||||
|
||||
#define LOG_TRACE(...) SPDLOG_TRACE(__VA_ARGS__)
|
||||
#define LOG_DEBUG(...) SPDLOG_DEBUG(__VA_ARGS__)
|
||||
#define LOG_INFO(...) SPDLOG_INFO(__VA_ARGS__)
|
||||
#define LOG_WARN(...) SPDLOG_WARN(__VA_ARGS__)
|
||||
#define LOG_ERROR(...) SPDLOG_ERROR(__VA_ARGS__)
|
||||
#define LOG_CRITICAL(...) SPDLOG_CRITICAL(__VA_ARGS__)
|
||||
|
||||
}
|
47
src/main.cpp
47
src/main.cpp
@@ -1,5 +1,6 @@
|
||||
#include "server.hpp"
|
||||
#include "config.hpp"
|
||||
#include "logger.hpp"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
@@ -40,9 +41,9 @@ std::filesystem::path get_config_path() {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
std::cout << "No config file found. Checked: " << std::endl;
|
||||
LOG_ERROR("No config file found. Checked:");
|
||||
for (const auto& path : config_paths) {
|
||||
std::cout << " " << path << std::endl;
|
||||
LOG_ERROR(" {}", path.string());
|
||||
}
|
||||
return std::filesystem::path();
|
||||
}
|
||||
@@ -52,19 +53,25 @@ bool initialize_server() {
|
||||
if (config_path.empty()) {
|
||||
return false;
|
||||
}
|
||||
std::cout << "Config file: " << config_path << std::endl;
|
||||
|
||||
|
||||
ServerConfig config;
|
||||
if (!simple_object_storage::load_config(config_path, config)) {
|
||||
std::cout << "Config file at " << config_path << " is not valid." << std::endl;
|
||||
LOG_ERROR("Config file at {} is not valid.", config_path.string());
|
||||
return false;
|
||||
}
|
||||
|
||||
std::cout << "Starting server at " << config.host << ":" << config.port << std::endl;
|
||||
std::cout << "Object store path: " << config.object_store_path << std::endl;
|
||||
|
||||
// Reinitialize logger with config settings
|
||||
Logger::init(config.log_level, config.log_file_path.string());
|
||||
|
||||
LOG_INFO("Config file: {}", config_path.string());
|
||||
LOG_INFO("Starting server at {}:{}", config.host, config.port);
|
||||
LOG_INFO("Object store path: {}", config.object_store_path.string());
|
||||
if (!config.log_file_path.empty()) {
|
||||
LOG_INFO("Log file: {}", config.log_file_path.string());
|
||||
}
|
||||
|
||||
if (!std::filesystem::exists(config.object_store_path)) {
|
||||
std::cout << "Object store path does not exist: " << config.object_store_path << std::endl;
|
||||
LOG_ERROR("Object store path does not exist: {}", config.object_store_path.string());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -74,7 +81,7 @@ bool initialize_server() {
|
||||
|
||||
void stop_server() {
|
||||
if (g_server) {
|
||||
std::cout << "Stopping server..." << std::endl;
|
||||
LOG_INFO("Stopping server...");
|
||||
g_server->stop();
|
||||
if (g_server_thread.joinable()) {
|
||||
g_server_thread.join();
|
||||
@@ -86,28 +93,30 @@ void stop_server() {
|
||||
void signal_handler(int signal) {
|
||||
switch (signal) {
|
||||
case SIGHUP:
|
||||
std::cout << "Received SIGHUP signal - reloading configuration" << std::endl;
|
||||
LOG_INFO("Received SIGHUP signal - reloading configuration");
|
||||
stop_server();
|
||||
if (!initialize_server()) {
|
||||
std::cerr << "Failed to restart server with new configuration" << std::endl;
|
||||
LOG_ERROR("Failed to restart server with new configuration");
|
||||
g_running = false;
|
||||
}
|
||||
break;
|
||||
case SIGTERM:
|
||||
case SIGINT:
|
||||
std::cout << "Received termination signal" << std::endl;
|
||||
LOG_INFO("Received termination signal");
|
||||
g_running = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
// Initialize logger with defaults (will be reconfigured after loading config)
|
||||
Logger::init("info", "");
|
||||
|
||||
if (argc > 1) {
|
||||
if (std::string(argv[1]) == "version") {
|
||||
std::cout << dropshell::VERSION << std::endl;
|
||||
return 0;
|
||||
}
|
||||
std::cout << "Simple Object Storage version: " << dropshell::VERSION << std::endl;
|
||||
}
|
||||
|
||||
// Set up signal handlers
|
||||
@@ -117,15 +126,15 @@ int main(int argc, char* argv[]) {
|
||||
sa.sa_flags = 0;
|
||||
|
||||
if (sigaction(SIGHUP, &sa, nullptr) == -1) {
|
||||
std::cerr << "Failed to set up SIGHUP handler" << std::endl;
|
||||
LOG_ERROR("Failed to set up SIGHUP handler");
|
||||
return 1;
|
||||
}
|
||||
if (sigaction(SIGTERM, &sa, nullptr) == -1) {
|
||||
std::cerr << "Failed to set up SIGTERM handler" << std::endl;
|
||||
LOG_ERROR("Failed to set up SIGTERM handler");
|
||||
return 1;
|
||||
}
|
||||
if (sigaction(SIGINT, &sa, nullptr) == -1) {
|
||||
std::cerr << "Failed to set up SIGINT handler" << std::endl;
|
||||
LOG_ERROR("Failed to set up SIGINT handler");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -133,10 +142,12 @@ int main(int argc, char* argv[]) {
|
||||
if (!initialize_server()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
LOG_INFO("Simple Object Storage version: {}", dropshell::VERSION);
|
||||
|
||||
// Start server in main thread
|
||||
if (!g_server->start()) {
|
||||
std::cerr << "Failed to start server" << std::endl;
|
||||
LOG_ERROR("Failed to start server");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#include "put_handler.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "hash.hpp"
|
||||
#include "compress.hpp"
|
||||
#include "string_utils.hpp"
|
||||
@@ -279,7 +280,7 @@ void PutHandler::handle_upload_object(const drogon::HttpRequestPtr& req, std::fu
|
||||
std::filesystem::rename(temp_path, final_path);
|
||||
temp_file_deleter.release();
|
||||
} catch (const std::filesystem::filesystem_error& e) {
|
||||
std::cerr << "Error renaming temp file: " << e.what() << std::endl;
|
||||
LOG_ERROR("Error renaming temp file: {}", e.what());
|
||||
resp->setStatusCode(drogon::k500InternalServerError);
|
||||
nlohmann::json response = {{"result", "error"}, {"error", "Failed to store object file"}};
|
||||
resp->setBody(response.dump());
|
||||
|
@@ -10,6 +10,7 @@
|
||||
#include <sstream>
|
||||
|
||||
#include "server.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "hash.hpp"
|
||||
#include "compress.hpp"
|
||||
#include "string_utils.hpp" // Include the new utility header
|
||||
@@ -34,7 +35,7 @@ bool Server::init_db() {
|
||||
db_ = std::make_unique<Database>(db_path);
|
||||
return true;
|
||||
} catch (const std::runtime_error& e) {
|
||||
std::cerr << "Database initialization error: " << e.what() << std::endl;
|
||||
LOG_ERROR("Database initialization error: {}", e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -114,7 +115,7 @@ Server::Server(const ServerConfig& config)
|
||||
Server::setInstance(this);
|
||||
|
||||
if (!std::filesystem::exists(config_.object_store_path)) {
|
||||
std::cerr << "Object store directory does not exist: " << config_.object_store_path << std::endl;
|
||||
LOG_ERROR("Object store directory does not exist: {}", config_.object_store_path.string());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -146,7 +147,7 @@ Server::~Server() {
|
||||
|
||||
bool Server::start() {
|
||||
if (!db_) { // Check if DB initialization failed
|
||||
std::cerr << "Database is not initialized. Cannot start server." << std::endl;
|
||||
LOG_ERROR("Database is not initialized. Cannot start server.");
|
||||
return false;
|
||||
}
|
||||
setup_routes();
|
||||
@@ -167,7 +168,7 @@ bool Server::start() {
|
||||
drogon::app().run();
|
||||
} catch (const std::exception& e) {
|
||||
running_ = false;
|
||||
std::cerr << "Failed to start server: " << e.what() << std::endl;
|
||||
LOG_ERROR("Failed to start server: {}", e.what());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -177,7 +178,7 @@ void Server::stop() {
|
||||
if (running_) {
|
||||
drogon::app().quit();
|
||||
running_ = false;
|
||||
std::cout << "Server stopped." << std::endl;
|
||||
LOG_INFO("Server stopped.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -379,7 +380,7 @@ void Server::handle_get_metadata(const drogon::HttpRequestPtr& req, std::functio
|
||||
response = {{"result", "success"}, {"metadata", entry.metadata}};
|
||||
resp->setBody(response.dump());
|
||||
} catch (const nlohmann::json::exception& e) {
|
||||
std::cerr << "Error serializing metadata for hash " << hash_str << ": " << e.what() << std::endl;
|
||||
LOG_ERROR("Error serializing metadata for hash {}: {}", hash_str, e.what());
|
||||
resp->setStatusCode(drogon::k500InternalServerError);
|
||||
response = {{"result", "error"}, {"error", "Internal server error: Failed to serialize metadata"}};
|
||||
resp->setBody(response.dump());
|
||||
@@ -455,7 +456,7 @@ void Server::handle_delete_object(const drogon::HttpRequestPtr& req, std::functi
|
||||
try {
|
||||
std::filesystem::remove(file_path);
|
||||
} catch (const std::filesystem::filesystem_error& e) {
|
||||
std::cerr << "Error deleting object file: " << e.what() << std::endl;
|
||||
LOG_ERROR("Error deleting object file: {}", e.what());
|
||||
resp->setStatusCode(drogon::k500InternalServerError);
|
||||
nlohmann::json response = {{"result", "error"}, {"error", "Failed to delete object file: " + std::string(e.what())}};
|
||||
resp->setBody(response.dump());
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#include "temp_directory.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
@@ -42,13 +43,13 @@ TempDirectory::~TempDirectory() {
|
||||
std::error_code ec; // Use error code to avoid exceptions in destructor
|
||||
std::filesystem::remove_all(path_, ec);
|
||||
if (ec) {
|
||||
std::cerr << "Error removing temporary directory " << path_.string() << ": " << ec.message() << std::endl;
|
||||
LOG_ERROR("Error removing temporary directory {}: {}", path_.string(), ec.message());
|
||||
}
|
||||
}
|
||||
} catch (const std::exception& e) { // Catch potential exceptions from exists() though unlikely
|
||||
std::cerr << "Error during temporary directory cleanup for " << path_.string() << ": " << e.what() << std::endl;
|
||||
LOG_ERROR("Error during temporary directory cleanup for {}: {}", path_.string(), e.what());
|
||||
} catch (...) {
|
||||
std::cerr << "Unknown error during temporary directory cleanup for " << path_.string() << std::endl;
|
||||
LOG_ERROR("Unknown error during temporary directory cleanup for {}", path_.string());
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#include "utils.hpp"
|
||||
#include "logger.hpp"
|
||||
|
||||
namespace simple_object_storage
|
||||
{
|
||||
@@ -18,7 +19,7 @@ namespace simple_object_storage
|
||||
}
|
||||
catch (const std::filesystem::filesystem_error &e)
|
||||
{
|
||||
std::cerr << "Error deleting temp file: " << path_ << " - " << e.what() << std::endl;
|
||||
LOG_ERROR("Error deleting temp file: {} - {}", path_.string(), e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -8,6 +8,10 @@
|
||||
"auth_rate_limit": 5,
|
||||
"auth_window_seconds": 2
|
||||
},
|
||||
"logging": {
|
||||
"log_file_path": "/data/test.log",
|
||||
"log_level": "info"
|
||||
},
|
||||
"port": 7703,
|
||||
"host": "127.0.0.1"
|
||||
}
|
@@ -8,6 +8,10 @@
|
||||
"auth_rate_limit": 5,
|
||||
"auth_window_seconds": 2
|
||||
},
|
||||
"logging": {
|
||||
"log_file_path": "/data/test.log",
|
||||
"log_level": "info"
|
||||
},
|
||||
"port": 7703,
|
||||
"host": "127.0.0.1"
|
||||
}
|
Reference in New Issue
Block a user