From 7d7eb7097b059a05db83930076e4df5b512dd705 Mon Sep 17 00:00:00 2001 From: Colby Nyce Date: Wed, 25 Feb 2026 13:32:22 -0800 Subject: [PATCH 1/3] Redo thread-safe stdout/stderr/file logging --- examples/ConcurrentApps/main.cpp | 4 - examples/DatabaseWatchdog/main.cpp | 3 - include/simdb/apps/App.hpp | 24 ++- include/simdb/apps/AppManager.hpp | 198 +++++++++------------ include/simdb/pipeline/PipelineManager.hpp | 22 +-- include/simdb/pipeline/PollingThread.hpp | 18 +- include/simdb/utils/Demangle.hpp | 3 +- include/simdb/utils/MTLogger.hpp | 82 --------- include/simdb/utils/ThreadSafeLogger.hpp | 96 ++++++++++ 9 files changed, 218 insertions(+), 232 deletions(-) delete mode 100644 include/simdb/utils/MTLogger.hpp create mode 100644 include/simdb/utils/ThreadSafeLogger.hpp diff --git a/examples/ConcurrentApps/main.cpp b/examples/ConcurrentApps/main.cpp index b49f66e8..68c595c2 100644 --- a/examples/ConcurrentApps/main.cpp +++ b/examples/ConcurrentApps/main.cpp @@ -16,10 +16,6 @@ int main() auto& app_mgr = app_mgrs.createAppManager("test.db"); auto& db_mgr = app_mgrs.getDatabaseManager(); - // Disable pipeline messages; it clutters up stdout with so many running apps - app_mgr.disableMessageLog(); - app_mgr.disableErrorLog(); - // Create 4 instances of the SimplePipeline app app_mgr.enableApp(SimplePipeline::NAME, 4); diff --git a/examples/DatabaseWatchdog/main.cpp b/examples/DatabaseWatchdog/main.cpp index 6a101598..1b8f2eec 100644 --- a/examples/DatabaseWatchdog/main.cpp +++ b/examples/DatabaseWatchdog/main.cpp @@ -175,9 +175,6 @@ int main() app_mgrs.registerApp(); auto& app_mgr = app_mgrs.createAppManager("test.db"); - app_mgr.disableMessageLog(); - app_mgr.disableErrorLog(); - // Setup... app_mgr.enableApp(WatchedPipeline::NAME); app_mgr.enableApp(DatabaseWatchdog::NAME); diff --git a/include/simdb/apps/App.hpp b/include/simdb/apps/App.hpp index 140487a4..edce3b64 100644 --- a/include/simdb/apps/App.hpp +++ b/include/simdb/apps/App.hpp @@ -47,6 +47,9 @@ class AsyncDatabaseAccessor; class PipelineManager; } // namespace pipeline +class AppManager; +class ThreadSafeLogger; + /// Base class for SimDB applications. Note that app subclasses are given /// the DatabaseManager instance as a constructor argument, so they can /// access the database and perform operations like appending schemas, @@ -57,19 +60,30 @@ class App virtual ~App() = default; void setInstance(size_t instance) { instance_ = instance; } size_t getInstance() const { return instance_; } - virtual void postInit(int argc, char** argv) - { - (void)argc; - (void)argv; - } + virtual void postInit([[maybe_unused]] int argc, [[maybe_unused]] char** argv) {} virtual void createPipeline(pipeline::PipelineManager*) {} virtual void preTeardown() {} virtual void postTeardown() {} + ThreadSafeLogger* getStdoutLogger() const { return stdout_logger_; } + ThreadSafeLogger* getStderrLogger() const { return stderr_logger_; } + ThreadSafeLogger* getFileLogger() const { return file_logger_; } + +protected: + void setStdoutLogger_(ThreadSafeLogger* logger) { stdout_logger_ = logger; } + void setStderrLogger_(ThreadSafeLogger* logger) { stderr_logger_ = logger; } + void setFileLogger_(ThreadSafeLogger* logger) { file_logger_ = logger; } + private: /// Instance number for multi-instance apps (1-based). /// If zero, then this is a single-instance app. size_t instance_ = 0; + + /// Thread-safe loggers. + ThreadSafeLogger* stdout_logger_ = nullptr; + ThreadSafeLogger* stderr_logger_ = nullptr; + ThreadSafeLogger* file_logger_ = nullptr; + friend class AppManager; }; class AppFactoryBase diff --git a/include/simdb/apps/AppManager.hpp b/include/simdb/apps/AppManager.hpp index 033c668c..df5cf30c 100644 --- a/include/simdb/apps/AppManager.hpp +++ b/include/simdb/apps/AppManager.hpp @@ -5,13 +5,14 @@ #include "simdb/apps/App.hpp" #include "simdb/pipeline/PipelineManager.hpp" #include "simdb/sqlite/DatabaseManager.hpp" +#include "simdb/utils/ThreadSafeLogger.hpp" #include #include #include #include -#define PROFILE_APP_PHASE [[maybe_unused]] ScopedTimer timer(getDatabaseManager(), __FUNCTION__, msg_log_); +#define PROFILE_APP_PHASE [[maybe_unused]] ScopedTimer timer(getDatabaseManager(), __FUNCTION__); namespace simdb { @@ -173,18 +174,6 @@ class AppManager } } - /// Disable all logged messages. - void disableMessageLog() { msg_log_.disable(); } - - /// Disable all logged errors. - void disableErrorLog() { err_log_.disable(); } - - /// Redirect messages (defaults to stdout) - void redirectMessageLog(std::ostream* msg_log) { msg_log_.redirectMessages(msg_log); } - - /// Redirect errors (defaults to stderr) - void redirectErrorsLog(std::ostream* err_log) { err_log_.redirectErrors(err_log); } - /// After parsing command line arguments or configuration files, /// enable an app by its name. This will allow the app to be instantiated /// and run during the simulation lifecycle. @@ -331,10 +320,14 @@ class AppManager private: /// AppManagers are associated 1-to-1 with a DatabaseManager. - AppManager(DatabaseManager* db_mgr) : + AppManager(DatabaseManager* db_mgr, + ThreadSafeLogger* stdout_logger = nullptr, + ThreadSafeLogger* stderr_logger = nullptr, + ThreadSafeLogger* file_logger = nullptr) : db_mgr_(db_mgr), - msg_log_(&std::cout), - err_log_(&std::cerr) + stdout_logger_(stdout_logger), + stderr_logger_(stderr_logger), + file_logger_(file_logger) { } @@ -397,9 +390,13 @@ class AppManager } App* app = factory->createApp(db_mgr_); - app->setInstance(instance_num); + app->instance_ = instance_num; std::string instance_name = app_name + std::string("-") + std::to_string(instance_num); apps_[instance_name] = std::unique_ptr(app); + + app->stdout_logger_ = stdout_logger_; + app->stderr_logger_ = stderr_logger_; + app->file_logger_ = file_logger_; } } } @@ -459,17 +456,17 @@ class AppManager } // Print final pipeline configurations. - msg_log_ << "\nSimDB app pipeline configuration for database '" << db_mgr_->getDatabaseFilePath() << "':\n"; + std::cout << "\nSimDB app pipeline configuration for database '" << db_mgr_->getDatabaseFilePath() << "':\n"; for (auto pipeline : pipeline_mgr_->getPipelines()) { - msg_log_ << "---- Pipeline: " << pipeline->getName() << "\n"; + std::cout << "---- Pipeline: " << pipeline->getName() << "\n"; for (auto& [stage_name, stage] : pipeline->getOrderedStages()) { - msg_log_ << "------ Stage: " << stage_name << "\n"; + std::cout << "------ Stage: " << stage_name << "\n"; } } - msg_log_ << std::endl; + std::cout << std::endl; } /// Call this once after initializePipelines() (and after minimizeThreads() @@ -500,7 +497,7 @@ class AppManager if (pipeline_mgr_) { - pipeline_mgr_->postSimLoopTeardown(msg_log_); + pipeline_mgr_->postSimLoopTeardown(); } db_mgr_->safeTransaction([&]() { @@ -664,123 +661,55 @@ class AppManager /// All pipelines and threads are managed by PipelineManager. std::unique_ptr pipeline_mgr_; + /// Stdout logger (thread-safe). Owned by AppManagers. + ThreadSafeLogger* stdout_logger_ = nullptr; + + /// Stderr logger (thread-safe). Owned by AppManagers. + ThreadSafeLogger* stderr_logger_ = nullptr; + + /// File logger (thread-safe). Owned by AppManagers. + ThreadSafeLogger* file_logger_ = nullptr; + /// RAII timer to measure the performance of various app setup/teardown /// phases. class ScopedTimer { public: - ScopedTimer(const DatabaseManager* db_mgr, const std::string& block_name, std::ostream* msg_out = &std::cout) : + ScopedTimer(const DatabaseManager* db_mgr, const std::string& block_name) : start_(std::chrono::high_resolution_clock::now()), - block_name_(block_name), - msg_out_(msg_out) + block_name_(block_name) { - if (msg_out_) - { - auto db_filepath = db_mgr->getDatabaseFilePath(); - *msg_out_ << "SimDB: Entering " << block_name << " for database: " << db_filepath << "\n"; - } + auto db_filepath = db_mgr->getDatabaseFilePath(); + std::cout << "SimDB: Entering " << block_name << " for database: " << db_filepath << "\n"; } ~ScopedTimer() { - if (!msg_out_) - { - return; - } - auto end = std::chrono::high_resolution_clock::now(); std::chrono::duration dur = end - start_; auto us = std::chrono::duration_cast(dur).count(); if (us >= 1000000) { auto sec = (double)us / 1000000; - *msg_out_ << "SimDB: Completed " << block_name_ << " in "; - *msg_out_ << std::fixed << std::setprecision(2) << sec << " seconds.\n"; + std::cout << "SimDB: Completed " << block_name_ << " in "; + std::cout << std::fixed << std::setprecision(2) << sec << " seconds.\n"; } else if (us >= 1000) { auto milli = (double)us / 1000; - *msg_out_ << "SimDB: Completed " << block_name_ << " in "; - *msg_out_ << std::fixed << std::setprecision(0) << milli << " milliseconds.\n"; + std::cout << "SimDB: Completed " << block_name_ << " in "; + std::cout << std::fixed << std::setprecision(0) << milli << " milliseconds.\n"; } else { auto micro = (double)us; - *msg_out_ << "SimDB: Completed " << block_name_ << " in "; - *msg_out_ << std::fixed << std::setprecision(0) << micro << " microseconds.\n"; + std::cout << "SimDB: Completed " << block_name_ << " in "; + std::cout << std::fixed << std::setprecision(0) << micro << " microseconds.\n"; } } private: std::chrono::high_resolution_clock::time_point start_; std::string block_name_; - std::ostream* msg_out_ = nullptr; }; - - /// Simple wrapper around std::ostream* for conditional logging - class Logger - { - public: - Logger(std::ostream* out) : - out_(out) - { - } - - template Logger& operator<<(const T& msg) - { - if (out_ && enabled_) - { - *out_ << msg; - out_->flush(); - } - return *this; - } - - Logger& operator<<(const char* msg) - { - if (out_ && enabled_) - { - *out_ << msg; - out_->flush(); - } - return *this; - } - - Logger& operator<<(std::ostream& (*manip)(std::ostream&)) - { - if (out_ && enabled_) - { - manip(*out_); - out_->flush(); - } - return *this; - } - - operator std::ostream*() { return enabled_ ? out_ : nullptr; } - - void disable() { enabled_ = false; } - - void enable() { enabled_ = true; } - - void enable(bool enabled) { enabled_ = enabled; } - - void redirectMessages(std::ostream* msg_log) - { - out_ = msg_log; - enable(out_ != nullptr); - } - - void redirectErrors(std::ostream* err_log) - { - out_ = err_log; - enable(out_ != nullptr); - } - - private: - std::ostream* out_ = nullptr; - bool enabled_ = true; - }; - - Logger msg_log_; - Logger err_log_; }; template void AppRegistration::registerApp(AppManager* app_manager) const @@ -806,6 +735,45 @@ class AppManagers app_registrations_.emplace_back(new AppRegistration()); } + /// If you want all apps to share a global thread-safe stdout logger, + /// call this method before createAppManager(). + /// + /// Pass in prefix=true to see "[log]" before each line written to the logger's output. + void useThreadSafeStdoutLogger(bool prefix=false) + { + if (!accepting_logger_requests_) + { + throw DBException("No longer accepting thread-safe logger requests"); + } + stdout_logger_ = std::make_unique(std::cout, prefix); + } + + /// If you want all apps to share a global thread-safe stderr logger, + /// call this method before createAppManager(). + /// + /// Pass in prefix=true to see "[log]" before each line written to the logger's output. + void useThreadSafeStderrLogger(bool prefix=false) + { + if (!accepting_logger_requests_) + { + throw DBException("No longer accepting thread-safe logger requests"); + } + stderr_logger_ = std::make_unique(std::cerr, prefix); + } + + /// If you want all apps to share a global thread-safe file logger, + /// call this method before createAppManager(). + /// + /// Pass in prefix=true to see "[log]" before each line written to the logger's output. + void useThreadSafeFileLogger(const std::string & filename, bool prefix=false) + { + if (!accepting_logger_requests_) + { + throw DBException("No longer accepting thread-safe logger requests"); + } + file_logger_ = std::make_unique(filename, prefix); + } + /// Create a new AppManager with a new database. /// /// Pass in new_db=true to overwrite existing database, or new_db=false to use @@ -815,6 +783,8 @@ class AppManagers /// Throws if an AppManager for this database already exists. AppManager& createAppManager(const std::string& db_file, bool new_db = true) { + accepting_logger_requests_ = false; + if (app_mgrs_by_db_file_.find(db_file) != app_mgrs_by_db_file_.end()) { throw DBException("AppManager already exists for database: ") << db_file; @@ -826,7 +796,10 @@ class AppManagers } std::shared_ptr db_mgr(new DatabaseManager(db_file, new_db)); - std::shared_ptr app_mgr(new AppManager(db_mgr.get())); + std::shared_ptr app_mgr(new AppManager(db_mgr.get(), + stdout_logger_.get(), + stderr_logger_.get(), + file_logger_.get())); db_mgrs_by_db_file_[db_file] = db_mgr; app_mgrs_by_db_file_[db_file] = app_mgr; @@ -1004,6 +977,11 @@ class AppManagers std::map> app_mgrs_by_db_file_; std::map> app_mgrs_by_db_mgr_; std::map> db_mgrs_by_app_mgr_; + + std::unique_ptr stdout_logger_; + std::unique_ptr stderr_logger_; + std::unique_ptr file_logger_; + bool accepting_logger_requests_ = true; }; /// Helper class to only expose AppManagers::registerApp() api. diff --git a/include/simdb/pipeline/PipelineManager.hpp b/include/simdb/pipeline/PipelineManager.hpp index 449c737c..1d0f5a0d 100644 --- a/include/simdb/pipeline/PipelineManager.hpp +++ b/include/simdb/pipeline/PipelineManager.hpp @@ -7,7 +7,6 @@ #include "simdb/pipeline/PipelineSnooper.hpp" #include "simdb/pipeline/PollingThread.hpp" #include "simdb/pipeline/ThreadMerger.hpp" -#include "simdb/utils/MTLogger.hpp" #include @@ -22,9 +21,8 @@ namespace simdb::pipeline { class PipelineManager { public: - PipelineManager(DatabaseManager* db_mgr, const std::string& pipeline_log_file = "") : - db_mgr_(db_mgr), - pipeline_logger_(pipeline_log_file) + PipelineManager(DatabaseManager* db_mgr) : + db_mgr_(db_mgr) { } @@ -39,8 +37,6 @@ class PipelineManager return async_db_accessor_; } - utils::MTLogger* getPipelineLogger() { return &pipeline_logger_; } - Pipeline* createPipeline(const std::string& name, const App* app) { checkOpen_(); @@ -173,19 +169,14 @@ class PipelineManager return disabler; } - void postSimLoopTeardown(std::ostream* perf_report = &std::cout) + void postSimLoopTeardown() { checkOpen_(); auto close_thread = [&](PollingThread* thread) { thread->close(); - - if (perf_report) - { - std::ostringstream oss; - thread->printPerfReport(oss); - *perf_report << oss.str() << "\n\n"; - } + thread->printPerfReport(); + std::cout << "\n\n"; }; auto it = polling_threads_.begin(); @@ -231,9 +222,6 @@ class PipelineManager /// Used in order to short-circuit nested disablers. bool disabler_active_ = false; - /// Multi-threaded pipeline logger. - utils::MTLogger pipeline_logger_; - /// Flag used to prevent AsyncDatabaseAccessor from being /// accessed until threads are opened/finalized. bool threads_opened_ = false; diff --git a/include/simdb/pipeline/PollingThread.hpp b/include/simdb/pipeline/PollingThread.hpp index d9864235..3f47c280 100644 --- a/include/simdb/pipeline/PollingThread.hpp +++ b/include/simdb/pipeline/PollingThread.hpp @@ -157,7 +157,7 @@ class PollingThread pause_cv_.notify_all(); // Wake the thread to resume } - void printPerfReport(std::ostream& os) const noexcept + void printPerfReport() const noexcept { if (runnables_.empty()) { @@ -175,18 +175,18 @@ class PollingThread const auto pct_time_sleeping = (total_sleep_seconds_ / total_elap_seconds) * 100; const auto pct_time_working = 100 - pct_time_sleeping; - os << "Thread containing:\n"; + std::cout << "Thread containing:\n"; for (const auto runnable : runnables_) { - runnable->print(os, 4); + runnable->print(std::cout, 4); } - os << "\n"; - os << " Performance report:\n"; - os << " Num times run: " << num_times_run_ << "\n"; - os << " Pct time sleeping: " << std::fixed << std::setprecision(1) << pct_time_sleeping << "%\n"; - os << " Pct time working: " << std::fixed << std::setprecision(1) << pct_time_working << "%\n"; - os << "\n"; + std::cout << "\n"; + std::cout << " Performance report:\n"; + std::cout << " Num times run: " << num_times_run_ << "\n"; + std::cout << " Pct time sleeping: " << std::fixed << std::setprecision(1) << pct_time_sleeping << "%\n"; + std::cout << " Pct time working: " << std::fixed << std::setprecision(1) << pct_time_working << "%\n"; + std::cout << "\n"; } private: diff --git a/include/simdb/utils/Demangle.hpp b/include/simdb/utils/Demangle.hpp index e922f835..a12b7d7e 100644 --- a/include/simdb/utils/Demangle.hpp +++ b/include/simdb/utils/Demangle.hpp @@ -6,8 +6,7 @@ namespace simdb { /*! - * \brief Represents the internal buffer size for demangling C++ symbols via - * sparta::demangle + * \brief Represents the internal buffer size for demangling C++ symbols */ #define DEMANGLE_BUF_LENGTH 4096 diff --git a/include/simdb/utils/MTLogger.hpp b/include/simdb/utils/MTLogger.hpp deleted file mode 100644 index bd4ec4d9..00000000 --- a/include/simdb/utils/MTLogger.hpp +++ /dev/null @@ -1,82 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - -namespace simdb::utils { - -/// This class handles multi-threaded logging to a file. -class MTLogger -{ -public: - class LogLine - { - public: - LogLine(std::mutex& m, uint64_t id, std::ostream& out) : - mutex_(m), - id_(id), - out_(out) - { - // Capture thread id as string - std::ostringstream oss; - oss << std::this_thread::get_id(); - thread_id_ = oss.str(); - } - - ~LogLine() - { - // Emit atomically - std::lock_guard lock(mutex_); - - out_ << "msg[id:" << id_ << ", thread:" << thread_id_ << "] " << stream_.str() << std::endl; - } - - // Handle generic types - template LogLine& operator<<(T&& v) - { - stream_ << std::forward(v); - return *this; - } - - // Handle manipulators like std::endl - LogLine& operator<<(std::ostream& (*manip)(std::ostream&)) - { - manip(stream_); - return *this; - } - - private: - std::mutex& mutex_; - uint64_t id_; - std::ostream& out_; - std::string thread_id_; - std::ostringstream stream_; - }; - - /// Constructor (std::cout) - MTLogger() : - out_(std::cout) - { - } - - /// Constructor (file - std::cout if empty) - MTLogger(const std::string& filename) : - fout_(!filename.empty() ? std::make_unique(filename) : nullptr), - out_(fout_ ? *fout_ : std::cout) - { - } - - LogLine operator()() { return LogLine(mutex_, id_counter_++, out_); } - -private: - std::mutex mutex_; - std::atomic id_counter_{0}; - std::unique_ptr fout_; - std::ostream& out_; -}; - -} // namespace simdb::utils diff --git a/include/simdb/utils/ThreadSafeLogger.hpp b/include/simdb/utils/ThreadSafeLogger.hpp new file mode 100644 index 00000000..47093307 --- /dev/null +++ b/include/simdb/utils/ThreadSafeLogger.hpp @@ -0,0 +1,96 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "simdb/Exceptions.hpp" + +namespace simdb { + +class ThreadSafeLogger +{ +public: + // Construct from existing ostream (cout, cerr, custom stream) + explicit ThreadSafeLogger(std::ostream& os, bool prefix=false) + : out_(&os) + , prefix_(prefix ? "[log] " : "") + {} + + // Construct from file name (logger owns the file) + explicit ThreadSafeLogger(const std::string& filename, bool prefix=false) + : owned_file_(std::make_unique(filename)) + , out_(owned_file_.get()) + , prefix_(prefix ? "[log] " : "") + { + if (!*owned_file_) { + throw std::runtime_error("Failed to open log file"); + } + } + + // Get global std::cout logger + static ThreadSafeLogger * getGlobalCoutLogger(bool must_exist = true) { + return globalCoutLogger_(nullptr, must_exist); + } + + // Set global std::cout logger + static void setGlobalCoutLogger(ThreadSafeLogger& logger) { + globalCoutLogger_(&logger); + } + + // Set/get the global std::cout logger + static ThreadSafeLogger * globalCoutLogger_(ThreadSafeLogger* logger = nullptr, bool must_exist = true) { + static ThreadSafeLogger* global_logger = nullptr; + if (logger) { + global_logger = logger; + } + if (!global_logger && must_exist) { + throw DBException("Global thread-safe logger was never set!"); + } + return global_logger; + } + + class Guard + { + public: + explicit Guard(const ThreadSafeLogger& logger) + : logger_(logger) + {} + + ~Guard() { + std::lock_guard lock(logger_.mutex_); + (*logger_.out_) << logger_.prefix_ << buffer_.str(); + logger_.out_->flush(); + } + + template + Guard& operator<<(T&& value) { + buffer_ << std::forward(value); + return *this; + } + + Guard& operator<<(std::ostream& (*manip)(std::ostream&)) { + buffer_ << manip; + return *this; + } + + private: + const ThreadSafeLogger& logger_; + std::ostringstream buffer_; + }; + + Guard protect() const { + return Guard(*this); + } + +private: + mutable std::mutex mutex_; + mutable std::unique_ptr owned_file_; // only used if file logger + mutable std::ostream* out_; // non-owning or owned via unique_ptr + const std::string prefix_; +}; + +} // namespace simdb From 40971411116d784cd9bd808b66b0b2d1c91016a5 Mon Sep 17 00:00:00 2001 From: Colby Nyce Date: Wed, 25 Feb 2026 13:36:19 -0800 Subject: [PATCH 2/3] Remove unused apis --- include/simdb/utils/ThreadSafeLogger.hpp | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/include/simdb/utils/ThreadSafeLogger.hpp b/include/simdb/utils/ThreadSafeLogger.hpp index 47093307..74dbdf39 100644 --- a/include/simdb/utils/ThreadSafeLogger.hpp +++ b/include/simdb/utils/ThreadSafeLogger.hpp @@ -31,28 +31,6 @@ class ThreadSafeLogger } } - // Get global std::cout logger - static ThreadSafeLogger * getGlobalCoutLogger(bool must_exist = true) { - return globalCoutLogger_(nullptr, must_exist); - } - - // Set global std::cout logger - static void setGlobalCoutLogger(ThreadSafeLogger& logger) { - globalCoutLogger_(&logger); - } - - // Set/get the global std::cout logger - static ThreadSafeLogger * globalCoutLogger_(ThreadSafeLogger* logger = nullptr, bool must_exist = true) { - static ThreadSafeLogger* global_logger = nullptr; - if (logger) { - global_logger = logger; - } - if (!global_logger && must_exist) { - throw DBException("Global thread-safe logger was never set!"); - } - return global_logger; - } - class Guard { public: From 46844b0dc9c32ec150ecfc6db10d8baca793c853 Mon Sep 17 00:00:00 2001 From: Colby Nyce Date: Wed, 25 Feb 2026 13:36:44 -0800 Subject: [PATCH 3/3] Run clang-format --- include/simdb/apps/App.hpp | 2 +- include/simdb/apps/AppManager.hpp | 18 ++++------ include/simdb/utils/ThreadSafeLogger.hpp | 45 +++++++++++++----------- 3 files changed, 32 insertions(+), 33 deletions(-) diff --git a/include/simdb/apps/App.hpp b/include/simdb/apps/App.hpp index edce3b64..1587ba3d 100644 --- a/include/simdb/apps/App.hpp +++ b/include/simdb/apps/App.hpp @@ -72,7 +72,7 @@ class App protected: void setStdoutLogger_(ThreadSafeLogger* logger) { stdout_logger_ = logger; } void setStderrLogger_(ThreadSafeLogger* logger) { stderr_logger_ = logger; } - void setFileLogger_(ThreadSafeLogger* logger) { file_logger_ = logger; } + void setFileLogger_(ThreadSafeLogger* logger) { file_logger_ = logger; } private: /// Instance number for multi-instance apps (1-based). diff --git a/include/simdb/apps/AppManager.hpp b/include/simdb/apps/AppManager.hpp index df5cf30c..17a07a90 100644 --- a/include/simdb/apps/AppManager.hpp +++ b/include/simdb/apps/AppManager.hpp @@ -320,10 +320,8 @@ class AppManager private: /// AppManagers are associated 1-to-1 with a DatabaseManager. - AppManager(DatabaseManager* db_mgr, - ThreadSafeLogger* stdout_logger = nullptr, - ThreadSafeLogger* stderr_logger = nullptr, - ThreadSafeLogger* file_logger = nullptr) : + AppManager(DatabaseManager* db_mgr, ThreadSafeLogger* stdout_logger = nullptr, + ThreadSafeLogger* stderr_logger = nullptr, ThreadSafeLogger* file_logger = nullptr) : db_mgr_(db_mgr), stdout_logger_(stdout_logger), stderr_logger_(stderr_logger), @@ -739,7 +737,7 @@ class AppManagers /// call this method before createAppManager(). /// /// Pass in prefix=true to see "[log]" before each line written to the logger's output. - void useThreadSafeStdoutLogger(bool prefix=false) + void useThreadSafeStdoutLogger(bool prefix = false) { if (!accepting_logger_requests_) { @@ -752,7 +750,7 @@ class AppManagers /// call this method before createAppManager(). /// /// Pass in prefix=true to see "[log]" before each line written to the logger's output. - void useThreadSafeStderrLogger(bool prefix=false) + void useThreadSafeStderrLogger(bool prefix = false) { if (!accepting_logger_requests_) { @@ -765,7 +763,7 @@ class AppManagers /// call this method before createAppManager(). /// /// Pass in prefix=true to see "[log]" before each line written to the logger's output. - void useThreadSafeFileLogger(const std::string & filename, bool prefix=false) + void useThreadSafeFileLogger(const std::string& filename, bool prefix = false) { if (!accepting_logger_requests_) { @@ -796,10 +794,8 @@ class AppManagers } std::shared_ptr db_mgr(new DatabaseManager(db_file, new_db)); - std::shared_ptr app_mgr(new AppManager(db_mgr.get(), - stdout_logger_.get(), - stderr_logger_.get(), - file_logger_.get())); + std::shared_ptr app_mgr( + new AppManager(db_mgr.get(), stdout_logger_.get(), stderr_logger_.get(), file_logger_.get())); db_mgrs_by_db_file_[db_file] = db_mgr; app_mgrs_by_db_file_[db_file] = app_mgr; diff --git a/include/simdb/utils/ThreadSafeLogger.hpp b/include/simdb/utils/ThreadSafeLogger.hpp index 74dbdf39..2d5917a3 100644 --- a/include/simdb/utils/ThreadSafeLogger.hpp +++ b/include/simdb/utils/ThreadSafeLogger.hpp @@ -1,10 +1,10 @@ #pragma once +#include #include +#include #include #include -#include -#include #include #include "simdb/Exceptions.hpp" @@ -15,18 +15,20 @@ class ThreadSafeLogger { public: // Construct from existing ostream (cout, cerr, custom stream) - explicit ThreadSafeLogger(std::ostream& os, bool prefix=false) - : out_(&os) - , prefix_(prefix ? "[log] " : "") - {} + explicit ThreadSafeLogger(std::ostream& os, bool prefix = false) : + out_(&os), + prefix_(prefix ? "[log] " : "") + { + } // Construct from file name (logger owns the file) - explicit ThreadSafeLogger(const std::string& filename, bool prefix=false) - : owned_file_(std::make_unique(filename)) - , out_(owned_file_.get()) - , prefix_(prefix ? "[log] " : "") + explicit ThreadSafeLogger(const std::string& filename, bool prefix = false) : + owned_file_(std::make_unique(filename)), + out_(owned_file_.get()), + prefix_(prefix ? "[log] " : "") { - if (!*owned_file_) { + if (!*owned_file_) + { throw std::runtime_error("Failed to open log file"); } } @@ -34,23 +36,26 @@ class ThreadSafeLogger class Guard { public: - explicit Guard(const ThreadSafeLogger& logger) - : logger_(logger) - {} + explicit Guard(const ThreadSafeLogger& logger) : + logger_(logger) + { + } - ~Guard() { + ~Guard() + { std::lock_guard lock(logger_.mutex_); (*logger_.out_) << logger_.prefix_ << buffer_.str(); logger_.out_->flush(); } - template - Guard& operator<<(T&& value) { + template Guard& operator<<(T&& value) + { buffer_ << std::forward(value); return *this; } - Guard& operator<<(std::ostream& (*manip)(std::ostream&)) { + Guard& operator<<(std::ostream& (*manip)(std::ostream&)) + { buffer_ << manip; return *this; } @@ -60,9 +65,7 @@ class ThreadSafeLogger std::ostringstream buffer_; }; - Guard protect() const { - return Guard(*this); - } + Guard protect() const { return Guard(*this); } private: mutable std::mutex mutex_;