-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from kriegalex/develop
Merge develop
- Loading branch information
Showing
20 changed files
with
25,826 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,3 +30,12 @@ | |
*.exe | ||
*.out | ||
*.app | ||
|
||
# certificates | ||
*.pem | ||
|
||
# Bin | ||
bin/ | ||
|
||
# cmake folders | ||
cmake-*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
cmake_minimum_required(VERSION 3.15) | ||
project(SecureSyslogServer) | ||
|
||
# Set the C++ standard for the project | ||
set(CMAKE_CXX_STANDARD 17) | ||
|
||
set(OPENSSL_ROOT_DIR ON CACHE BOOL "OpenSSL root directory") | ||
|
||
find_package(OpenSSL REQUIRED) | ||
if (OPENSSL_FOUND) | ||
message(STATUS "OpenSSL include dir: ${OPENSSL_INCLUDE_DIR}") | ||
message(STATUS "OpenSSL libraries: ${OPENSSL_LIBRARIES}") | ||
endif () | ||
|
||
# Create an executable with this project's source files | ||
add_executable(${PROJECT_NAME} main.cpp | ||
SyslogServer.cpp | ||
Config.cpp | ||
SSLUtil.cpp | ||
Logger.cpp | ||
MemoryBoundedQueue.cpp) | ||
target_link_libraries(SecureSyslogServer OpenSSL::SSL OpenSSL::Crypto) | ||
if (WIN32) | ||
target_link_libraries(${PROJECT_NAME} ws2_32) | ||
endif () | ||
target_include_directories(SecureSyslogServer PRIVATE ${OPENSSL_INCLUDE_DIR}) | ||
|
||
# Set the output directory for runtime binary (executables) | ||
set_target_properties(${PROJECT_NAME} PROPERTIES | ||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin | ||
) | ||
|
||
# Copy a specific file | ||
file(COPY ${PROJECT_SOURCE_DIR}/res/server.pem DESTINATION ${PROJECT_SOURCE_DIR}/bin/Debug) | ||
file(COPY ${PROJECT_SOURCE_DIR}/res/server.pem DESTINATION ${PROJECT_SOURCE_DIR}/bin/Release) | ||
file(COPY ${PROJECT_SOURCE_DIR}/res/config.json DESTINATION ${PROJECT_SOURCE_DIR}/bin/Debug) | ||
file(COPY ${PROJECT_SOURCE_DIR}/res/config.json DESTINATION ${PROJECT_SOURCE_DIR}/bin/Release) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
#include "Config.h" | ||
#include <fstream> | ||
#include "json.hpp" | ||
|
||
using json = nlohmann::json; | ||
|
||
Config::Config(const std::string &configPath) { | ||
loadConfig(configPath); | ||
} | ||
|
||
void Config::loadConfig(const std::string &path) { | ||
std::ifstream configFile(path); | ||
json configJson; | ||
configFile >> configJson; | ||
|
||
server_port_ = configJson["server_port"]; | ||
output_to_screen_ = configJson["screen_output"]; | ||
syslog_file_max_size_kb_ = configJson["file_max_size_kb"]; | ||
syslog_max_memory_size_kb_ = configJson["max_memory_size_kb"]; | ||
auto colors = configJson["priority_colors"]; | ||
for (const auto &elt : levels) { | ||
// set default then check config.json | ||
priorityColors[elt] = defaultColors.at(elt); | ||
// info, debug, ... exist as keys in the config.json | ||
if (colors.find(elt) != colors.end()) { | ||
// the given color strings in config.json exist in our mapping table | ||
if (winTerminalColors.find(colors[elt]) != winTerminalColors.end()) { | ||
priorityColors[elt] = winTerminalColors.at(colors[elt]); | ||
} | ||
} | ||
} | ||
} | ||
|
||
unsigned long Config::getMaxMemorySizeKb() const { | ||
return syslog_max_memory_size_kb_; | ||
} | ||
|
||
int Config::getServerPort() const { | ||
return server_port_; | ||
} | ||
|
||
int Config::getErrorSeverityColorCode() const { | ||
return priorityColors.at("error"); | ||
} | ||
|
||
int Config::getInfoSeverityColorCode() const { | ||
return priorityColors.at("info"); | ||
} | ||
|
||
int Config::getDebugSeverityColorCode() const { | ||
return priorityColors.at("debug"); | ||
} | ||
|
||
unsigned long Config::getFileMaxSizeKb() const { | ||
return syslog_file_max_size_kb_; | ||
} | ||
|
||
bool Config::isOutputToScreen() const { | ||
return output_to_screen_; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#ifndef SYSLOGCONFIG_H | ||
#define SYSLOGCONFIG_H | ||
|
||
#include <unordered_map> | ||
#include <string> | ||
#include <array> | ||
|
||
class Config { | ||
public: | ||
explicit Config(const std::string &configPath); | ||
int getServerPort() const; | ||
int getErrorSeverityColorCode() const; | ||
int getInfoSeverityColorCode() const; | ||
int getDebugSeverityColorCode() const; | ||
unsigned long getFileMaxSizeKb() const; | ||
bool isOutputToScreen() const; | ||
unsigned long getMaxMemorySizeKb() const; | ||
|
||
private: | ||
int server_port_ = 60119; | ||
bool output_to_screen_ = false; | ||
unsigned long syslog_file_max_size_kb_ = 1000; // 1MB | ||
unsigned long syslog_max_memory_size_kb_ = 1000000; // 1GB | ||
std::unordered_map<std::string, int> priorityColors; | ||
void loadConfig(const std::string &path); | ||
const std::array<std::string, 3> levels = {"error", "info", "debug"}; | ||
const std::unordered_map<std::string, int> defaultColors = {{"error", 12}, {"info", 1}, {"debug", 8}}; | ||
const std::unordered_map<std::string, int> winTerminalColors = { | ||
{"BLACK", 0}, | ||
{"BLUE", 1}, | ||
{"GREEN", 2}, | ||
{"CYAN", 3}, | ||
{"RED", 4}, | ||
{"MAGENTA", 5}, | ||
{"YELLOW", 6}, | ||
{"WHITE", 7}, | ||
{"BRIGHT_BLACK", 8}, | ||
{"BRIGHT_BLUE", 9}, | ||
{"BRIGHT_GREEN", 10}, | ||
{"BRIGHT_CYAN", 11}, | ||
{"BRIGHT_RED", 12}, | ||
{"BRIGHT_MAGENTA", 13}, | ||
{"BRIGHT_YELLOW", 14}, | ||
{"BRIGHT_WHITE", 15}}; | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
#pragma once | ||
|
||
#include <fstream> | ||
#include <atomic> | ||
#include <thread> | ||
#include <mutex> | ||
#include <utility> | ||
#include <filesystem> | ||
#include <sstream> | ||
|
||
#include "MemoryBoundedQueue.h" | ||
|
||
class FileLogger { | ||
private: | ||
MemoryBoundedQueue<std::string> &queue_; | ||
std::ofstream file_stream_; | ||
std::atomic<bool> running_ = true; | ||
std::atomic<bool> wait_ = false; | ||
std::thread worker_; | ||
std::mutex mtx_; | ||
std::string filename_; | ||
const std::chrono::milliseconds flush_interval_ = std::chrono::milliseconds(100); | ||
const unsigned long max_file_size_; | ||
bool stopWorker = false; | ||
|
||
// Generate a filename based on the current date and time | ||
static std::string getFormattedFilename() { | ||
// Get current time as system_clock time_point | ||
auto now = std::chrono::system_clock::now(); | ||
// Convert to time_t for compatibility with C time functions | ||
auto now_c = std::chrono::system_clock::to_time_t(now); | ||
// Convert to tm struct for use with put_time | ||
struct tm now_tm{}; | ||
localtime_s(&now_tm, &now_c); | ||
|
||
// Use ostringstream to format filename | ||
std::ostringstream oss; | ||
oss << std::put_time(&now_tm, "syslog_%Y_%m_%d_%H_%M_%S.txt"); | ||
|
||
return oss.str(); | ||
} | ||
|
||
// Open a new log file with the current timestamp | ||
void openNewLogFile() { | ||
if (file_stream_.is_open()) { | ||
file_stream_.close(); | ||
} | ||
filename_ = getFormattedFilename(); | ||
file_stream_.open(filename_, std::ios::app); | ||
} | ||
|
||
// Check the size of the current log file and rotate if necessary | ||
void checkAndRotateFile() { | ||
if (std::filesystem::file_size(filename_) >= max_file_size_) { | ||
openNewLogFile(); | ||
} | ||
} | ||
|
||
void backgroundScreenFlush() { | ||
while (!stopWorker) { | ||
std::this_thread::sleep_for(flush_interval_); | ||
std::lock_guard<std::mutex> lock(mtx_); | ||
file_stream_.flush(); | ||
} | ||
} | ||
|
||
public: | ||
FileLogger(MemoryBoundedQueue<std::string> &q, unsigned long file_size) | ||
: filename_(std::move(getFormattedFilename())), | ||
max_file_size_(file_size), | ||
queue_(q) { | ||
worker_ = std::thread(&::FileLogger::backgroundScreenFlush, this); | ||
} | ||
|
||
~FileLogger() { | ||
stopWorker = true; | ||
worker_.join(); | ||
if (file_stream_.is_open()) { | ||
file_stream_.close(); | ||
} | ||
} | ||
|
||
void run() { | ||
file_stream_.open(filename_, std::ios::app); | ||
unsigned int count = 0; | ||
while (running_) { | ||
std::string log = queue_.pop(); | ||
std::lock_guard<std::mutex> lock(mtx_); | ||
file_stream_ << log << std::endl; | ||
checkAndRotateFile(); | ||
} | ||
file_stream_.flush(); // in case wait_ is used and takes time | ||
if (wait_) { | ||
while (!queue_.empty()) { | ||
std::string log = queue_.pop(); | ||
std::lock_guard<std::mutex> lock(mtx_); | ||
file_stream_ << log << std::endl; | ||
checkAndRotateFile(); | ||
} | ||
file_stream_.flush(); | ||
} | ||
} | ||
|
||
void stop() { | ||
wait_ = false; | ||
running_ = false; | ||
} | ||
|
||
void stopWaitFinished() { | ||
wait_ = true; | ||
running_ = false; | ||
} | ||
}; |
Oops, something went wrong.