Skip to content

Commit

Permalink
using spdlog
Browse files Browse the repository at this point in the history
  • Loading branch information
opokatech committed Apr 4, 2024
1 parent 092ccdb commit d7a02fc
Show file tree
Hide file tree
Showing 14 changed files with 175 additions and 63 deletions.
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"nosan",
"pugi",
"SIGUSR",
"spdlog",
"Struct",
"vararg"
],
Expand All @@ -25,7 +26,8 @@
"functional": "cpp",
"memory": "cpp",
"optional": "cpp",
"sstream": "cpp"
"sstream": "cpp",
"*.tcc": "cpp"
},
"testMate.cpp.test.executables": "build_*/**/*_tests",
"cmake.buildDirectory": "${workspaceFolder}/build_debug_cpu_native",
Expand Down
1 change: 0 additions & 1 deletion TODO
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
- examples of configuration (nginx, cron)
- make cross compilation work again
- consider removing ECB namespace
- consider using spdlog
12 changes: 12 additions & 0 deletions cmake/externals.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,18 @@ message(STATUS "${ColorGreen}mongoose ready${ColorReset}")
add_library(mongoose STATIC ${mongoose_SOURCE_DIR}/mongoose.c)
target_include_directories(mongoose PUBLIC ${mongoose_SOURCE_DIR})

# SPDLOG
FetchContent_Declare(
spdlog
GIT_REPOSITORY https://github.com/gabime/spdlog.git
GIT_TAG v1.12.0
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE)

message(STATUS "${ColorYellow}Making spdlog available...${ColorReset}")
FetchContent_MakeAvailable(spdlog)
message(STATUS "${ColorGreen}spdlog ready${ColorReset}")

# GOOGLE TEST
if(ECB_PARAM_TESTS)
FetchContent_Declare(
Expand Down
4 changes: 2 additions & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
add_library(ecb_lib STATIC Logging.cpp Rates.cpp Record.cpp Time_Point.cpp Utils.cpp)
add_library(ecb_lib STATIC Log.cpp Rates.cpp Record.cpp Time_Point.cpp Utils.cpp)
target_include_directories(ecb_lib PUBLIC .)
target_link_libraries(ecb_lib PRIVATE ecb_compiler_flags)
target_link_libraries(ecb_lib PRIVATE ecb_compiler_flags PUBLIC spdlog)

add_library(ecb_data_loader STATIC Data_Loader.cpp)
target_include_directories(ecb_data_loader PUBLIC .)
Expand Down
10 changes: 5 additions & 5 deletions src/Data_Loader.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include "Data_Loader.hpp"
#include "Logging.hpp"
#include "Log.hpp"

#include "cpr/cpr.h"
#include "pugixml.hpp"
Expand All @@ -21,7 +21,7 @@ namespace ECB
}
catch (...)
{
Log("Error loading from a file '%s'\n", file_name.c_str());
Log::error("Error loading from a file '{}'\n", file_name);
}
return {};
}
Expand All @@ -44,12 +44,12 @@ namespace ECB
}
else
{
Log("Failed getting data from url '%s', status code = %d\n", url.c_str(), r.status_code);
Log::error("Failed getting data from url '{}', status code = {}\n", url, r.status_code);
}
}
catch (...)
{
Log("Error loading from url '%s'\n", url.c_str());
Log::error("Error loading from url '{}'\n", url);
}
return {};
}
Expand All @@ -71,7 +71,7 @@ namespace ECB

if (!parse_result)
{
Log("Error parsing xml: %s\n", parse_result.description());
Log::error("Error parsing xml: {}\n", parse_result.description());
return records;
}

Expand Down
62 changes: 62 additions & 0 deletions src/Log.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#include "Log.hpp"

#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"

namespace ECB
{
// static members
std::shared_ptr<spdlog::logger> Log::logger_ = nullptr;

void Log::init(const std::string &logFile)
{
std::vector<spdlog::sink_ptr> sinks;

auto consoleLogger = std::make_shared<spdlog::sinks::stderr_color_sink_mt>();
// timestamp with ms, colored log level, message
consoleLogger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] %v");
sinks.push_back(consoleLogger);

if (!logFile.empty())
{
constexpr bool TRUNCATE = true;
try
{
auto fileLogger = std::make_shared<spdlog::sinks::basic_file_sink_mt>(logFile, TRUNCATE);
// timestamp with ms, log level, message
fileLogger->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] %v");
sinks.push_back(fileLogger);
}
catch (const spdlog::spdlog_ex &ex)
{
spdlog::error("Failed to create file logger: {}", ex.what());
}
}

logger_ = std::make_shared<spdlog::logger>("logger", sinks.begin(), sinks.end());
spdlog::register_logger(logger_);
}

void Log::setLevel(const std::string &level)
{
constexpr auto DEFAULT_LEVEL = spdlog::level::info;
spdlog::level::level_enum finalLevel = DEFAULT_LEVEL;

if (level == "off")
finalLevel = spdlog::level::off;
else if (level == "error")
finalLevel = spdlog::level::err;
else if (level == "warning")
finalLevel = spdlog::level::warn;
else if (level == "info")
finalLevel = spdlog::level::info;

setLevel(finalLevel);
}

void Log::setLevel(spdlog::level::level_enum level)
{
if (logger_ != nullptr)
logger_->set_level(level);
}
} // namespace ECB
46 changes: 46 additions & 0 deletions src/Log.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#pragma once

#include "spdlog/spdlog.h"

namespace ECB
{
class Log
{
public:
Log() = delete;

static void init(const std::string &logFile = "");

static void setLevel(const std::string &level);
static void setLevel(spdlog::level::level_enum level);

// convenient aliases
template <typename... Args>
static void info(const char *format, Args... args)
{
log(spdlog::level::level_enum::info, format, args...);
}

template <typename... Args>
static void warn(const char *format, Args... args)
{
log(spdlog::level::level_enum::warn, format, args...);
}

template <typename... Args>
static void error(const char *format, Args... args)
{
log(spdlog::level::level_enum::err, format, args...);
}

private:
template <typename... Args>
static void log(spdlog::level::level_enum level, const char *format, Args... args)
{
if (logger_ != nullptr)
logger_->log(level, format, args...);
}

static std::shared_ptr<spdlog::logger> logger_;
};
} // namespace ECB
22 changes: 0 additions & 22 deletions src/Logging.cpp

This file was deleted.

6 changes: 0 additions & 6 deletions src/Logging.hpp

This file was deleted.

21 changes: 16 additions & 5 deletions src/Main_Fetcher.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include "Data_Loader.hpp"
#include "Logging.hpp"
#include "Log.hpp"
#include "Urls.hpp"
#include "Version_Info.hpp"

Expand Down Expand Up @@ -30,6 +30,14 @@ int main(int argc, char *argv[])
return !param.empty(); // valid data is not empty
});

options.add_optional("log_file", "Log file", "", [](const std::string &param) {
return !param.empty(); // valid data is not empty
});

options.add_optional("log_level", "Log level (off, info, warn, error)", "info", [](const std::string &param) {
return param == "off" || param == "info" || param == "warn" || param == "error";
});

options.add_flag("help", "Show help");

const bool parse_result = options.parse(argc, argv);
Expand All @@ -47,25 +55,28 @@ int main(int argc, char *argv[])
return -1;
}

ECB::Log::init(options.as_string("log_file"));
ECB::Log::setLevel(options.as_string("log_level"));

const bool hist_mode = (options.as_string("mode") == "hist");
const std::string &url = (hist_mode) ? options.as_string("hist_url") : options.as_string("daily_url");
const std::string &save_to_file = options.as_string("save_file");

cout << "Getting " << (hist_mode ? "historical" : "daily") << " data"
<< (!save_to_file.empty() ? " and saving to " + save_to_file : "") << endl;
ECB::Log::info("Getting {} data{}", hist_mode ? "historical" : "daily",
!save_to_file.empty() ? std::string(" and saving to ") + save_to_file : "");

const auto records = ECB::Data_Loader::load_from_url(url, save_to_file);

if (records.empty())
{
ECB::Log("Failed to load data from url: %s\n", url.c_str());
ECB::Log::error("Failed to load data from url: {}\n", url);
return -1;
}

for (const auto &record: records)
cout << record.as_string_without_base() << endl;

cout << "Got " << records.size() << " records\n";
ECB::Log::info("Got {} records", records.size());

return 0;
}
27 changes: 19 additions & 8 deletions src/Main_Server.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include "Data_Loader.hpp"
#include "Logging.hpp"
#include "Log.hpp"
#include "Main_Signals.hpp"
#include "Rates.hpp"
#include "Server.hpp"
Expand Down Expand Up @@ -42,6 +42,14 @@ int main(int argc, char *argv[])
return num >= 1 && num <= 20; // NOLINT
});

options.add_optional("log_file", "Log file", "", [](const std::string &param) {
return !param.empty(); // valid data is not empty
});

options.add_optional("log_level", "Log level (off, info, warn, error)", "info", [](const std::string &param) {
return param == "off" || param == "info" || param == "warn" || param == "error";
});

options.add_flag("listen_all", "Listen on all interfaces");
options.add_flag("pretty", "Pretty print JSON output");
options.add_flag("help", "Show help");
Expand All @@ -62,6 +70,9 @@ int main(int argc, char *argv[])
return -1;
}

ECB::Log::init(options.as_string("log_file"));
ECB::Log::setLevel(options.as_string("log_level"));

auto rates = std::make_shared<ECB::Rates>();

if (!options.as_string("xml_file").empty())
Expand Down Expand Up @@ -108,13 +119,13 @@ int main(int argc, char *argv[])

// start thread for serving web requests
std::thread web_thread([&server]() {
ECB::Log("Starting web server in separate thread\n");
ECB::Log::info("Starting web server in separate thread");
server.start();
ECB::Log("Stopping web server\n");
ECB::Log::info("Stopping web server");
server.stop();
});

ECB::Log("Starting loop in main thread\n");
ECB::Log::info("Starting loop in main thread");
while (Main_Signals::keep_running())
{
if (Main_Signals::load_more_data())
Expand All @@ -123,20 +134,20 @@ int main(int argc, char *argv[])
const auto data = ECB::Data_Loader::load_from_url(options.as_string("signal_xml_url"));
if (!data.empty())
{
ECB::Log("Loaded %u records.\n", data.size());
ECB::Log::info("Loaded {} records", data.size());
rates->add(data);
}
}
using namespace std::chrono_literals;
std::this_thread::sleep_for(1s);
}

ECB::Log("Stopping the web thread\n");
ECB::Log::info("Stopping the web thread");
server.stop();

ECB::Log("Waiting for web thread to join...");
ECB::Log::info("Waiting for web thread to join...");
web_thread.join();
ECB::Log("done\n");
ECB::Log::info("done");

return 0;
}
7 changes: 3 additions & 4 deletions src/Rates.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
#include "Rates.hpp"
#include "Logging.hpp"

namespace ECB
{
std::optional<Record> Rates::get(const Time_Point &tp, std::optional<std::string> base) const
{
std::scoped_lock lock(m_mutex);

const auto it = m_data.find(tp);
const auto IT = m_data.find(tp);

if (it == m_data.end())
if (IT == m_data.end())
return {};

Record ret = it->second;
Record ret = IT->second;

if (!base || ret.base() == base)
return ret;
Expand Down
Loading

0 comments on commit d7a02fc

Please sign in to comment.