diff --git a/include/dwarfs/logger.h b/include/dwarfs/logger.h index 265bb057..587edd25 100644 --- a/include/dwarfs/logger.h +++ b/include/dwarfs/logger.h @@ -22,9 +22,7 @@ #pragma once #include -#include #include -#include #include #include #include @@ -37,10 +35,7 @@ #include #include -#include - #include -#include namespace dwarfs { @@ -162,53 +157,26 @@ class level_log_entry { class timed_level_log_entry { public: - using thread_clock = boost::chrono::thread_clock; - timed_level_log_entry(logger& lgr, logger::level_type level, - std::source_location loc, bool with_cpu = false) - : lgr_(lgr) - , level_(level) - , start_time_(std::chrono::high_resolution_clock::now()) - , with_cpu_(with_cpu) - , loc_(loc) { - if (with_cpu) { - cpu_start_time_ = thread_clock::now(); - } - } - + std::source_location loc, bool with_cpu = false); timed_level_log_entry(timed_level_log_entry const&) = delete; - - ~timed_level_log_entry() { - if (output_) { - std::chrono::duration sec = - std::chrono::high_resolution_clock::now() - start_time_; - oss_ << " [" << time_with_unit(sec.count()); - if (with_cpu_) { - boost::chrono::duration cpu_time_sec = - thread_clock::now() - cpu_start_time_; - oss_ << ", " << time_with_unit(cpu_time_sec.count()) << " CPU"; - } - oss_ << "]"; - lgr_.write(level_, oss_.str(), loc_); - } - } + ~timed_level_log_entry(); template timed_level_log_entry& operator<<(const T& val) { - output_ = true; - oss_ << val; + if (state_) { + output_ = true; + oss_ << val; + } return *this; } private: - logger& lgr_; + class state; + std::ostringstream oss_; - logger::level_type const level_; - std::chrono::time_point start_time_; - thread_clock::time_point cpu_start_time_; bool output_{false}; - bool const with_cpu_; - std::source_location const loc_; + std::unique_ptr state_; }; class no_log_entry { diff --git a/src/logger.cpp b/src/logger.cpp index eb5c7c69..fa87085e 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -19,6 +19,7 @@ * along with dwarfs. If not, see . */ +#include #include #include #include @@ -29,6 +30,8 @@ #include #include +#include + #include #ifdef DWARFS_STACKTRACE_ENABLED @@ -296,6 +299,61 @@ void stream_logger::set_threshold(level_type threshold) { } } +class timed_level_log_entry::state { + public: + using thread_clock = boost::chrono::thread_clock; + + state(logger& lgr, logger::level_type level, std::source_location loc, + bool with_cpu) + : lgr_{lgr} + , level_{level} + , start_time_{std::chrono::high_resolution_clock::now()} + , cpu_start_time_{cpu_now(with_cpu)} + , loc_{loc} {} + + void log(std::ostringstream& oss) const { + std::chrono::duration sec = + std::chrono::high_resolution_clock::now() - start_time_; + oss << " [" << time_with_unit(sec.count()); + if (cpu_start_time_) { + boost::chrono::duration cpu_time_sec = + thread_clock::now() - cpu_start_time_.value(); + oss << ", " << time_with_unit(cpu_time_sec.count()) << " CPU"; + } + oss << "]"; + lgr_.write(level_, oss.str(), loc_); + } + + private: + static std::optional cpu_now(bool with_cpu) { + if (with_cpu) { + return thread_clock::now(); + } + return std::nullopt; + } + + logger& lgr_; + logger::level_type const level_; + std::chrono::time_point const start_time_; + std::optional const cpu_start_time_; + std::source_location const loc_; +}; + +timed_level_log_entry::timed_level_log_entry(logger& lgr, + logger::level_type level, + std::source_location loc, + bool with_cpu) { + if (level <= lgr.threshold()) { + state_ = std::make_unique(lgr, level, loc, with_cpu); + } +} + +timed_level_log_entry::~timed_level_log_entry() { + if (state_ && output_) { + state_->log(oss_); + } +} + namespace detail { bool logging_class_factory::is_policy_name(logger const& lgr, diff --git a/src/utility/rewrite_filesystem.cpp b/src/utility/rewrite_filesystem.cpp index 6d257f7b..5b3031d2 100644 --- a/src/utility/rewrite_filesystem.cpp +++ b/src/utility/rewrite_filesystem.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include