refactor(liblogging): changed SERiF to use liblogging

This commit is contained in:
2025-06-21 08:26:04 -04:00
parent a43f327672
commit c55185c1e3
20 changed files with 56 additions and 226 deletions

1
.gitignore vendored
View File

@@ -69,6 +69,7 @@ subprojects/packagecache/
subprojects/hypre/
subprojects/qhull/
subprojects/libconstants/
subprojects/liblogging/
qhull.wrap

View File

@@ -0,0 +1,4 @@
logging_p = subproject('liblogging')
logging_dep = logging_p.get_variable('logging_dep')
quill_dep = logging_p.get_variable('quill_dep')

View File

@@ -1 +1,2 @@
subdir('libconstants')
subdir('liblogging')

View File

@@ -4,7 +4,6 @@ subdir('fourdst')
subdir('mfem')
subdir('yaml-cpp')
subdir('quill')
subdir('boost')
subdir('opatIO')
subdir('mpi')

View File

@@ -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

View File

@@ -27,11 +27,12 @@
#include <utility>
#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.

View File

@@ -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<HELMTable> read_helm_table(const std::string &filename) {
serif::config::Config& config = serif::config::Config::getInstance();
auto logFile = config.get<std::string>("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<std::string>("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();

View File

@@ -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) {

View File

@@ -22,7 +22,7 @@
#include <vector>
#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

View File

@@ -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),

View File

@@ -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 ---

View File

@@ -24,6 +24,8 @@
#include <string>
#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;

View File

@@ -25,6 +25,8 @@
#include <memory>
#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) ---

View File

@@ -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

View File

@@ -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 <stdexcept>
#include <stdexcept>
#include <string>
#include <iostream>
#include <chrono>
@@ -39,8 +33,15 @@
#include "config.h"
#include "probe.h"
#include <thread>
#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<bool>("Probe:GLVis:Visualization", true)) {
std::string usedKeyset;
LOG_INFO(logger, "Visualizing solution using GLVis...");
@@ -109,7 +110,7 @@ std::pair<std::vector<double>, std::vector<double>> getRaySolution(mfem::GridFun
const std::vector<double>& 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<double>, std::vector<double>> 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<quill::ConsoleSink>("sink_id_1"));
newFileLogger(config.get<std::string>("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<std::string> LogManager::getLoggerNames() {
std::vector<std::string> 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<quill::Logger*> LogManager::getLoggers() {
std::vector<quill::Logger*> 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<quill::FileSink>(
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

View File

@@ -22,12 +22,10 @@
#pragma once
#include <string>
#include <map>
#include <vector>
#include <utility>
#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<double>& 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<std::string, quill::Logger*> 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<std::string> getLoggerNames();
/**
* @brief Get all loggers.
* @return A vector of pointers to the loggers.
*/
std::vector<quill::Logger*> 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

View File

@@ -22,13 +22,12 @@
#include <vector>
#include <string>
#include <stdexcept>
#include <unordered_map>
#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;

View File

@@ -0,0 +1,7 @@
[wrap-git]
url = https://github.com/4D-STAR/liblogging.git
revision = v1.0.1
depth = 1
[provide]
liblogging = logging_dep

View File

@@ -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");

View File

@@ -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<std::string> 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");
}