From c55185c1e3f8f40315d1c589ac8d34824793afc0 Mon Sep 17 00:00:00 2001 From: Emily Boudreaux Date: Sat, 21 Jun 2025 08:26:04 -0400 Subject: [PATCH] refactor(liblogging): changed SERiF to use liblogging --- .gitignore | 1 + build-config/fourdst/liblogging/meson.build | 4 + build-config/fourdst/meson.build | 1 + build-config/meson.build | 1 - src/composition/meson.build | 5 +- src/composition/public/composition.h | 5 +- src/eos/private/helm.cpp | 7 +- src/network/private/network.cpp | 4 +- src/network/public/network.h | 4 +- src/polytrope/solver/private/polySolver.cpp | 4 +- src/polytrope/solver/public/polySolver.h | 4 +- src/polytrope/utils/public/integrators.h | 4 +- .../utils/public/polytropeOperator.h | 4 +- src/probe/meson.build | 3 +- src/probe/private/probe.cpp | 77 +++---------------- src/probe/public/probe.h | 65 +--------------- src/resource/public/resourceManager.h | 7 +- subprojects/liblogging.wrap | 7 ++ tests/poly/polyTest.cpp | 4 +- tests/probe/probeTest.cpp | 71 ----------------- 20 files changed, 56 insertions(+), 226 deletions(-) create mode 100644 build-config/fourdst/liblogging/meson.build create mode 100644 subprojects/liblogging.wrap diff --git a/.gitignore b/.gitignore index 141f25e..3e3b8d2 100644 --- a/.gitignore +++ b/.gitignore @@ -69,6 +69,7 @@ subprojects/packagecache/ subprojects/hypre/ subprojects/qhull/ subprojects/libconstants/ +subprojects/liblogging/ qhull.wrap diff --git a/build-config/fourdst/liblogging/meson.build b/build-config/fourdst/liblogging/meson.build new file mode 100644 index 0000000..ade83d3 --- /dev/null +++ b/build-config/fourdst/liblogging/meson.build @@ -0,0 +1,4 @@ +logging_p = subproject('liblogging') + +logging_dep = logging_p.get_variable('logging_dep') +quill_dep = logging_p.get_variable('quill_dep') \ No newline at end of file diff --git a/build-config/fourdst/meson.build b/build-config/fourdst/meson.build index 6f7c958..b68e88e 100644 --- a/build-config/fourdst/meson.build +++ b/build-config/fourdst/meson.build @@ -1 +1,2 @@ subdir('libconstants') +subdir('liblogging') diff --git a/build-config/meson.build b/build-config/meson.build index 4937af3..9a48c5a 100644 --- a/build-config/meson.build +++ b/build-config/meson.build @@ -4,7 +4,6 @@ subdir('fourdst') subdir('mfem') subdir('yaml-cpp') -subdir('quill') subdir('boost') subdir('opatIO') subdir('mpi') diff --git a/src/composition/meson.build b/src/composition/meson.build index d97cbec..aea1eac 100644 --- a/src/composition/meson.build +++ b/src/composition/meson.build @@ -8,9 +8,10 @@ composition_headers = files( ) dependencies = [ - probe_dep, quill_dep, - species_weight_dep + species_weight_dep, + logging_dep, + config_dep, ] # Define the libcomposition library so it can be linked against by other parts of the build system diff --git a/src/composition/public/composition.h b/src/composition/public/composition.h index 3dcf8a0..27959d6 100644 --- a/src/composition/public/composition.h +++ b/src/composition/public/composition.h @@ -27,11 +27,12 @@ #include -#include "probe.h" #include "config.h" #include "atomicSpecies.h" +#include "logging.h" + namespace serif::composition { struct CanonicalComposition { double X = 0.0; ///< Mass fraction of Hydrogen. @@ -216,7 +217,7 @@ namespace serif::composition { class Composition { private: serif::config::Config& m_config = serif::config::Config::getInstance(); - serif::probe::LogManager& m_logManager = serif::probe::LogManager::getInstance(); + fourdst::logging::LogManager& m_logManager = fourdst::logging::LogManager::getInstance(); quill::Logger* m_logger = m_logManager.getLogger("log"); bool m_finalized = false; ///< True if the composition is finalized. diff --git a/src/eos/private/helm.cpp b/src/eos/private/helm.cpp index f97ca9c..01d740f 100644 --- a/src/eos/private/helm.cpp +++ b/src/eos/private/helm.cpp @@ -37,9 +37,10 @@ #include "helm.h" #include "const.h" -#include "probe.h" #include "config.h" #include "quill/LogMacros.h" +#include "quill/Logger.h" +#include "logging.h" using namespace std; @@ -128,7 +129,7 @@ namespace serif::eos::helmholtz { std::unique_ptr read_helm_table(const std::string &filename) { serif::config::Config& config = serif::config::Config::getInstance(); auto logFile = config.get("EOS:Helm:LogFile", "log"); - serif::probe::LogManager& logManager = serif::probe::LogManager::getInstance(); + fourdst::logging::LogManager& logManager = fourdst::logging::LogManager::getInstance(); quill::Logger* logger = logManager.getLogger(logFile); LOG_INFO(logger, "read_helm_table : Reading HELM table from file {}", filename); @@ -239,7 +240,7 @@ namespace serif::eos::helmholtz { serif::eos::helmholtz::HELMEOSOutput get_helm_EOS(serif::eos::helmholtz::HELMEOSInput &q, const serif::eos::helmholtz::HELMTable &table) { serif::config::Config& config = serif::config::Config::getInstance(); auto logFile = config.get("EOS:Helm:LogFile", "log"); - serif::probe::LogManager& logManager = serif::probe::LogManager::getInstance(); + fourdst::logging::LogManager& logManager = fourdst::logging::LogManager::getInstance(); quill::Logger* logger = logManager.getLogger(logFile); fourdst::constant::Constants& constants = fourdst::constant::Constants::getInstance(); diff --git a/src/network/private/network.cpp b/src/network/private/network.cpp index b0e3e2d..007b46b 100644 --- a/src/network/private/network.cpp +++ b/src/network/private/network.cpp @@ -21,13 +21,13 @@ #include "network.h" #include "approx8.h" -#include "probe.h" +#include "logging.h" #include "quill/LogMacros.h" namespace serif::network { Network::Network(const NetworkFormat format) : m_config(serif::config::Config::getInstance()), - m_logManager(serif::probe::LogManager::getInstance()), + m_logManager(fourdst::logging::LogManager::getInstance()), m_logger(m_logManager.getLogger("log")), m_format(format) { if (format == NetworkFormat::UNKNOWN) { diff --git a/src/network/public/network.h b/src/network/public/network.h index 0d7692b..60aec73 100644 --- a/src/network/public/network.h +++ b/src/network/public/network.h @@ -22,7 +22,7 @@ #include -#include "probe.h" +#include "logging.h" #include "config.h" #include "quill/Logger.h" #include "composition.h" @@ -118,7 +118,7 @@ namespace serif::network { protected: serif::config::Config& m_config; ///< Configuration instance - serif::probe::LogManager& m_logManager; ///< Log manager instance + fourdst::logging::LogManager& m_logManager; ///< Log manager instance quill::Logger* m_logger; ///< Logger instance NetworkFormat m_format; ///< Format of the network diff --git a/src/polytrope/solver/private/polySolver.cpp b/src/polytrope/solver/private/polySolver.cpp index 372830e..d303dec 100644 --- a/src/polytrope/solver/private/polySolver.cpp +++ b/src/polytrope/solver/private/polySolver.cpp @@ -29,6 +29,7 @@ #include "4DSTARTypes.h" #include "config.h" +#include "const.h" #include "integrators.h" #include "mfem.hpp" #include "polytropeOperator.h" @@ -38,6 +39,7 @@ #include "resourceManagerTypes.h" #include "utilities.h" #include "quill/LogMacros.h" +#include "logging.h" namespace serif::polytrope { @@ -75,7 +77,7 @@ namespace laneEmden { PolySolver::PolySolver(mfem::Mesh& mesh, const double n, const double order) : m_config(serif::config::Config::getInstance()), // Updated - m_logManager(serif::probe::LogManager::getInstance()), + m_logManager(fourdst::logging::LogManager::getInstance()), m_logger(m_logManager.getLogger("log")), m_polytropicIndex(n), m_feOrder(order), diff --git a/src/polytrope/solver/public/polySolver.h b/src/polytrope/solver/public/polySolver.h index 3e56cb2..a1432a4 100644 --- a/src/polytrope/solver/public/polySolver.h +++ b/src/polytrope/solver/public/polySolver.h @@ -29,8 +29,8 @@ #include "polytropeOperator.h" #include "config.h" #include "meshIO.h" -#include "probe.h" #include "quill/Logger.h" +#include "logging.h" namespace serif { namespace polytrope { @@ -283,7 +283,7 @@ public: // Public methods private: // Private Attributes // --- Configuration and Logging --- serif::config::Config& m_config; ///< Reference to the global configuration manager instance. - serif::probe::LogManager& m_logManager; ///< Reference to the global log manager instance. + fourdst::logging::LogManager& m_logManager; ///< Reference to the global log manager instance. quill::Logger* m_logger; ///< Pointer to the specific logger instance for this class. // --- Physical and Discretization Parameters --- diff --git a/src/polytrope/utils/public/integrators.h b/src/polytrope/utils/public/integrators.h index a821edd..74159d8 100644 --- a/src/polytrope/utils/public/integrators.h +++ b/src/polytrope/utils/public/integrators.h @@ -24,6 +24,8 @@ #include #include "config.h" #include "probe.h" +#include "quill/Logger.h" +#include "logging.h" /** @@ -70,7 +72,7 @@ namespace serif::polytrope { virtual void AssembleElementGrad (const mfem::FiniteElement &el, mfem::ElementTransformation &Trans, const mfem::Vector &elfun, mfem::DenseMatrix &elmat) override; private: serif::config::Config& m_config = serif::config::Config::getInstance(); - serif::probe::LogManager& m_logManager = serif::probe::LogManager::getInstance(); + fourdst::logging::LogManager& m_logManager = fourdst::logging::LogManager::getInstance(); quill::Logger* m_logger = m_logManager.getLogger("log"); double m_polytropicIndex; double m_epsilon; diff --git a/src/polytrope/utils/public/polytropeOperator.h b/src/polytrope/utils/public/polytropeOperator.h index 71209ad..473d388 100644 --- a/src/polytrope/utils/public/polytropeOperator.h +++ b/src/polytrope/utils/public/polytropeOperator.h @@ -25,6 +25,8 @@ #include #include "probe.h" +#include "logging.h" +#include "quill/Logger.h" namespace serif::polytrope { @@ -291,7 +293,7 @@ public: private: // --- Logging --- - serif::probe::LogManager& m_logManager = serif::probe::LogManager::getInstance(); ///< Reference to the global log manager. + fourdst::logging::LogManager& m_logManager = fourdst::logging::LogManager::getInstance(); ///< Reference to the global log manager. quill::Logger* m_logger = m_logManager.getLogger("log"); ///< Pointer to the specific logger instance. // --- Input Bilinear/Nonlinear Forms (owned) --- diff --git a/src/probe/meson.build b/src/probe/meson.build index 186586b..50c22c0 100644 --- a/src/probe/meson.build +++ b/src/probe/meson.build @@ -31,7 +31,8 @@ dependencies = [ config_dep, mfem_dep, quill_dep, - macros_dep + macros_dep, + logging_dep, ] # Define the liblogger library so it can be linked against by other parts of the build system diff --git a/src/probe/private/probe.cpp b/src/probe/private/probe.cpp index 111f01d..b67ec26 100644 --- a/src/probe/private/probe.cpp +++ b/src/probe/private/probe.cpp @@ -18,14 +18,8 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // *********************************************************************** */ -#include "quill/Backend.h" -#include "quill/Frontend.h" -#include "quill/Logger.h" -#include "quill/sinks/ConsoleSink.h" -#include "quill/sinks/FileSink.h" -#include "quill/LogMacros.h" -#include +#include #include #include #include @@ -39,8 +33,15 @@ #include "config.h" #include "probe.h" +#include + #include "warning_control.h" +#include "quill/LogMacros.h" +#include "quill/Logger.h" + +#include "logging.h" + namespace serif::probe { @@ -57,7 +58,7 @@ void wait(int seconds) { void glVisView(mfem::GridFunction& u, mfem::Mesh& mesh, const std::string& windowTitle, const std::string& keyset) { serif::config::Config& config = serif::config::Config::getInstance(); - quill::Logger* logger = LogManager::getInstance().getLogger("log"); + quill::Logger* logger = fourdst::logging::LogManager::getInstance().getLogger("log"); if (config.get("Probe:GLVis:Visualization", true)) { std::string usedKeyset; LOG_INFO(logger, "Visualizing solution using GLVis..."); @@ -109,7 +110,7 @@ std::pair, std::vector> getRaySolution(mfem::GridFun const std::vector& rayDirection, int numSamples, std::string filename) { serif::config::Config& config = serif::config::Config::getInstance(); - serif::probe::LogManager& logManager = serif::probe::LogManager::getInstance(); + fourdst::logging::LogManager& logManager = fourdst::logging::LogManager::getInstance(); quill::Logger* logger = logManager.getLogger("log"); LOG_INFO(logger, "Getting ray solution..."); // Check if the directory to write to exists @@ -202,62 +203,4 @@ std::pair, std::vector> getRaySolution(mfem::Vector DEPRECATION_WARNING_ON return getRaySolution(gf, *fes.GetMesh(), rayDirection, numSamples, filename); } - -LogManager::LogManager() { - serif::config::Config& config = serif::config::Config::getInstance(); - quill::Backend::start(); - auto CLILogger = quill::Frontend::create_or_get_logger( - "root", - quill::Frontend::create_or_get_sink("sink_id_1")); - - newFileLogger(config.get("Probe:LogManager:DefaultLogName", "4DSSE.log"), "log"); - loggerMap.emplace("stdout", CLILogger); -} - -LogManager::~LogManager() = default; - -quill::Logger* LogManager::getLogger(const std::string& loggerName) { - auto it = loggerMap.find(loggerName); // Find *once* - if (it == loggerMap.end()) { - throw std::runtime_error("Cannot find logger " + loggerName); - } - return it->second; // Return the raw pointer from the shared_ptr -} - -std::vector LogManager::getLoggerNames() { - std::vector loggerNames; - loggerNames.reserve(loggerMap.size()); - for (const auto& pair : loggerMap) { // Use range-based for loop and const auto& - loggerNames.push_back(pair.first); - } - return loggerNames; -} - -std::vector LogManager::getLoggers() { - std::vector loggers; - loggers.reserve(loggerMap.size()); - for (const auto& pair : loggerMap) { - loggers.push_back(pair.second); // Get the raw pointer - } - return loggers; -} - -quill::Logger* LogManager::newFileLogger(const std::string& filename, - const std::string& loggerName) { - auto file_sink = quill::Frontend::create_or_get_sink( - filename, - []() { - quill::FileSinkConfig cfg; - cfg.set_open_mode('w'); - return cfg; - }(), - quill::FileEventNotifier{}); - // Get the raw pointer. - quill::Logger* rawLogger = quill::Frontend::create_or_get_logger(loggerName, std::move(file_sink)); - - // Create a shared_ptr from the raw pointer. - loggerMap.emplace(loggerName, rawLogger); - return rawLogger; -} - } // namespace Probe \ No newline at end of file diff --git a/src/probe/public/probe.h b/src/probe/public/probe.h index 6b55474..dbe9a92 100644 --- a/src/probe/public/probe.h +++ b/src/probe/public/probe.h @@ -22,12 +22,10 @@ #pragma once #include -#include #include #include #include "mfem.hpp" -#include "quill/Logger.h" /** * @brief The Probe namespace contains utility functions for debugging and logging. @@ -57,7 +55,7 @@ namespace serif::probe { /** * @brief Visualize a vector using GLVis. * @param vec The vector to visualize. - * @param mesh The mesh associated with the vector. + * @param fes The mesh associated with the vector. * @param windowTitle The title of the visualization window. * @param keyset The keyset to use for visualization. */ @@ -73,65 +71,4 @@ namespace serif::probe { const std::vector& rayDirection, int numSamples, std::string filename=""); - /** - * @brief Class to manage logging operations. - */ - class LogManager { - private: - /** - * @brief Private constructor for singleton pattern. - */ - LogManager(); - - /** - * @brief Destructor. - */ - ~LogManager(); - - // Map to store pointers to quill loggers (raw pointers as quill deals with its own memory managment in a seperated, detatched, thread) - std::map loggerMap; - - // Prevent copying and assignment (Rule of Zero) - LogManager(const LogManager&) = delete; - LogManager& operator=(const LogManager&) = delete; - - public: - /** - * @brief Get the singleton instance of LogManager. - * @return The singleton instance of LogManager. - */ - static LogManager& getInstance() { - static LogManager instance; - return instance; - } - - /** - * @brief Get a logger by name. - * @param loggerName The name of the logger. - * @return A pointer to the logger. - */ - quill::Logger* getLogger(const std::string& loggerName); - - /** - * @brief Get the names of all loggers. - * @return A vector of logger names. - */ - std::vector getLoggerNames(); - - /** - * @brief Get all loggers. - * @return A vector of pointers to the loggers. - */ - std::vector getLoggers(); - - /** - * @brief Create a new file logger. - * @param filename The name of the log file. - * @param loggerName The name of the logger. - * @return A pointer to the new logger. - */ - quill::Logger* newFileLogger(const std::string& filename, - const std::string& loggerName); - }; - } // namespace Probe \ No newline at end of file diff --git a/src/resource/public/resourceManager.h b/src/resource/public/resourceManager.h index b37ea5f..bca54f0 100644 --- a/src/resource/public/resourceManager.h +++ b/src/resource/public/resourceManager.h @@ -22,13 +22,12 @@ #include #include -#include #include #include "resourceManagerTypes.h" #include "config.h" -#include "probe.h" -#include "quill/LogMacros.h" +#include "quill/Logger.h" +#include "logging.h" /** * @class ResourceManager @@ -56,7 +55,7 @@ namespace serif::resource { ResourceManager& operator=(const ResourceManager&) = delete; serif::config::Config& m_config = serif::config::Config::getInstance(); - serif::probe::LogManager& m_logManager = serif::probe::LogManager::getInstance(); + fourdst::logging::LogManager& m_logManager = fourdst::logging::LogManager::getInstance(); quill::Logger* m_logger = m_logManager.getLogger("log"); serif::config::Config m_resourceConfig; diff --git a/subprojects/liblogging.wrap b/subprojects/liblogging.wrap new file mode 100644 index 0000000..5b37950 --- /dev/null +++ b/subprojects/liblogging.wrap @@ -0,0 +1,7 @@ +[wrap-git] +url = https://github.com/4D-STAR/liblogging.git +revision = v1.0.1 +depth = 1 + +[provide] +liblogging = logging_dep \ No newline at end of file diff --git a/tests/poly/polyTest.cpp b/tests/poly/polyTest.cpp index e6f8708..553c502 100644 --- a/tests/poly/polyTest.cpp +++ b/tests/poly/polyTest.cpp @@ -24,7 +24,7 @@ #include "quill/LogMacros.h" #include "mfem.hpp" #include "polySolver.h" -#include "probe.h" +#include "logging.h" #include "config.h" std::string CONFIG_FILENAME = std::string(getenv("MESON_SOURCE_ROOT")) + "/tests/testsConfig.yaml"; @@ -37,7 +37,7 @@ TEST_F(polyTest, Solve) { serif::config::Config& config = serif::config::Config::getInstance(); config.loadConfig(CONFIG_FILENAME); - serif::probe::LogManager& logManager = serif::probe::LogManager::getInstance(); + fourdst::logging::LogManager& logManager = fourdst::logging::LogManager::getInstance(); quill::Logger* logger = logManager.getLogger("log"); diff --git a/tests/probe/probeTest.cpp b/tests/probe/probeTest.cpp index 03fff22..bdb951b 100644 --- a/tests/probe/probeTest.cpp +++ b/tests/probe/probeTest.cpp @@ -13,38 +13,9 @@ std::string TEST_CONFIG = std::string(getenv("MESON_SOURCE_ROOT")) + "/tests/testsConfig.yaml"; -std::string getLastLine(const std::string& filename) { - std::ifstream file(filename); - std::string line, lastLine; - - if (!file.is_open()) { - throw std::runtime_error("Could not open file"); - } - - while (std::getline(file, line)) { - lastLine = line; - } - - return lastLine; // Returns the last non-empty line -} - -std::string stripTimestamps(const std::string& logLine) { - std::regex logPattern(R"(\d+:\d+:\d+\.\d+\s+\[\d+\]\s+probeTest\.cpp:\d+\s+LOG_INFO\s+[A-Za-z]*\s+(.*))"); - std::smatch match; - if (std::regex_match(logLine, match, logPattern) && match.size() > 1) { - return match[1].str(); // Extract log message after timestamp - } - return logLine; // Return as-is if pattern doesn't match -} - class probeTest : public ::testing::Test {}; -TEST_F(probeTest, DefaultConstructorTest) { - serif::config::Config::getInstance().loadConfig(TEST_CONFIG); - EXPECT_NO_THROW(serif::probe::LogManager::getInstance()); -} - TEST_F(probeTest, waitTest) { auto start = std::chrono::high_resolution_clock::now(); serif::probe::wait(1); @@ -53,45 +24,3 @@ TEST_F(probeTest, waitTest) { EXPECT_LE(elapsed.count(), 1.1); } -TEST_F(probeTest, getLoggerTest) { - serif::config::Config::getInstance().loadConfig(TEST_CONFIG); - serif::probe::LogManager& logManager = serif::probe::LogManager::getInstance(); - const std::string loggerName = "testLog"; - const std::string filename = "test.log"; - quill::Logger* logger = logManager.newFileLogger(filename, loggerName); - EXPECT_NE(logger, nullptr); - LOG_INFO(logger, "This is a test message"); - // Wait for the log to be written by calling getLastLine until it is non empty - std::string lastLine; - while (lastLine.empty()) { - lastLine = getLastLine("test.log"); - } - EXPECT_EQ(stripTimestamps(lastLine), "This is a test message"); -} - -TEST_F(probeTest, newFileLoggerTest) { - serif::config::Config::getInstance().loadConfig(TEST_CONFIG); - serif::probe::LogManager& logManager = serif::probe::LogManager::getInstance(); - const std::string loggerName = "newLog"; - const std::string filename = "newLog.log"; - quill::Logger* logger = logManager.newFileLogger(filename, loggerName); - EXPECT_NE(logger, nullptr); - LOG_INFO(logger, "This is a new test message"); - // Wait for the log to be written by calling getLastLine until it is non empty - std::string lastLine; - while (lastLine.empty()) { - lastLine = getLastLine(filename); - } - EXPECT_EQ(stripTimestamps(lastLine), "This is a new test message"); -} - -TEST_F(probeTest, getLoggerNames) { - serif::config::Config::getInstance().loadConfig(TEST_CONFIG); - serif::probe::LogManager& logManager = serif::probe::LogManager::getInstance(); - std::vector loggerNames = logManager.getLoggerNames(); - EXPECT_EQ(loggerNames.size(), 4); - EXPECT_EQ(loggerNames.at(0), "log"); - EXPECT_EQ(loggerNames.at(1), "newLog"); - EXPECT_EQ(loggerNames.at(2), "stdout"); - EXPECT_EQ(loggerNames.at(3), "testLog"); -}