Branch data Line data Source code
# 1 : : // Copyright (c) 2009-2010 Satoshi Nakamoto
# 2 : : // Copyright (c) 2009-2020 The Bitcoin Core developers
# 3 : : // Distributed under the MIT software license, see the accompanying
# 4 : : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
# 5 : :
# 6 : : #ifndef BITCOIN_LOGGING_TIMER_H
# 7 : : #define BITCOIN_LOGGING_TIMER_H
# 8 : :
# 9 : : #include <logging.h>
# 10 : : #include <util/macros.h>
# 11 : : #include <util/time.h>
# 12 : :
# 13 : : #include <chrono>
# 14 : : #include <string>
# 15 : :
# 16 : :
# 17 : : namespace BCLog {
# 18 : :
# 19 : : //! RAII-style object that outputs timing information to logs.
# 20 : : template <typename TimeType>
# 21 : : class Timer
# 22 : : {
# 23 : : public:
# 24 : : //! If log_category is left as the default, end_msg will log unconditionally
# 25 : : //! (instead of being filtered by category).
# 26 : : Timer(
# 27 : : std::string prefix,
# 28 : : std::string end_msg,
# 29 : : BCLog::LogFlags log_category = BCLog::LogFlags::ALL) :
# 30 : : m_prefix(std::move(prefix)),
# 31 : : m_title(std::move(end_msg)),
# 32 : : m_log_category(log_category)
# 33 : 5421 : {
# 34 : 5421 : this->Log(strprintf("%s started", m_title));
# 35 : 5421 : m_start_t = GetTime<std::chrono::microseconds>();
# 36 : 5421 : }
# 37 : :
# 38 : : ~Timer()
# 39 : 5421 : {
# 40 : 5421 : this->Log(strprintf("%s completed", m_title));
# 41 : 5421 : }
# 42 : :
# 43 : : void Log(const std::string& msg)
# 44 : 10842 : {
# 45 : 10842 : const std::string full_msg = this->LogMsg(msg);
# 46 : :
# 47 [ + - ][ + + ]: 10842 : if (m_log_category == BCLog::LogFlags::ALL) {
# [ + - ]
# 48 : 4404 : LogPrintf("%s\n", full_msg);
# 49 : 6438 : } else {
# 50 [ # # ][ + - ]: 6438 : LogPrint(m_log_category, "%s\n", full_msg);
# [ # # ]
# 51 : 6438 : }
# 52 : 10842 : }
# 53 : :
# 54 : : std::string LogMsg(const std::string& msg)
# 55 : 10848 : {
# 56 : 10848 : const auto end_time = GetTime<std::chrono::microseconds>() - m_start_t;
# 57 [ + + ][ + + ]: 10848 : if (m_start_t.count() <= 0) {
# [ + + ]
# 58 : 5421 : return strprintf("%s: %s", m_prefix, msg);
# 59 : 5421 : }
# 60 : :
# 61 : 5427 : std::string units = "";
# 62 : 5427 : float divisor = 1;
# 63 : :
# 64 : 5427 : if (std::is_same<TimeType, std::chrono::microseconds>::value) {
# 65 : 4 : units = "μs";
# 66 : 5423 : } else if (std::is_same<TimeType, std::chrono::milliseconds>::value) {
# 67 : 3223 : units = "ms";
# 68 : 3223 : divisor = 1000.;
# 69 : 3223 : } else if (std::is_same<TimeType, std::chrono::seconds>::value) {
# 70 : 2200 : units = "s";
# 71 : 2200 : divisor = 1000. * 1000.;
# 72 : 2200 : }
# 73 : :
# 74 : 5427 : const float time_ms = end_time.count() / divisor;
# 75 : 5427 : return strprintf("%s: %s (%.2f%s)", m_prefix, msg, time_ms, units);
# 76 : 5427 : }
# 77 : :
# 78 : : private:
# 79 : : std::chrono::microseconds m_start_t{};
# 80 : :
# 81 : : //! Log prefix; usually the name of the function this was created in.
# 82 : : const std::string m_prefix{};
# 83 : :
# 84 : : //! A descriptive message of what is being timed.
# 85 : : const std::string m_title{};
# 86 : :
# 87 : : //! Forwarded on to LogPrint if specified - has the effect of only
# 88 : : //! outputting the timing log when a particular debug= category is specified.
# 89 : : const BCLog::LogFlags m_log_category{};
# 90 : :
# 91 : : };
# 92 : :
# 93 : : } // namespace BCLog
# 94 : :
# 95 : :
# 96 : : #define LOG_TIME_MILLIS_WITH_CATEGORY(end_msg, log_category) \
# 97 : 3219 : BCLog::Timer<std::chrono::milliseconds> PASTE2(logging_timer, __COUNTER__)(__func__, end_msg, log_category)
# 98 : : #define LOG_TIME_SECONDS(end_msg) \
# 99 : 2196 : BCLog::Timer<std::chrono::seconds> PASTE2(logging_timer, __COUNTER__)(__func__, end_msg)
# 100 : :
# 101 : :
# 102 : : #endif // BITCOIN_LOGGING_TIMER_H
|