diff --git a/src/ripple_app/main/Application.cpp b/src/ripple_app/main/Application.cpp index f261bcbe5f..e227c48e89 100644 --- a/src/ripple_app/main/Application.cpp +++ b/src/ripple_app/main/Application.cpp @@ -106,6 +106,70 @@ class ApplicationImp , public beast::DeadlineTimer::Listener , public beast::LeakChecked { +private: + class io_latency_sampler + { + private: + std::mutex mutable m_mutex; + beast::insight::Event m_event; + beast::Journal m_journal; + beast::io_latency_probe m_probe; + std::chrono::milliseconds m_lastSample; + + public: + io_latency_sampler ( + beast::insight::Event ev, + beast::Journal journal, + std::chrono::milliseconds interval, + boost::asio::io_service& ios) + : m_event (ev) + , m_journal (journal) + , m_probe (interval, ios) + { + } + + void + start() + { + m_probe.sample (std::ref(*this)); + } + + template + void operator() (Duration const& elapsed) + { + auto const ms (ceil (elapsed)); + + { + std::unique_lock lock (m_mutex); + m_lastSample = ms; + } + + if (ms.count() >= 10) + m_event.notify (ms); + if (ms.count() >= 500) + m_journal.warning << + "io_service latency = " << ms; + } + + std::chrono::milliseconds + get () const + { + std::unique_lock lock (m_mutex); + return m_lastSample; + } + + void + cancel () + { + m_probe.cancel (); + } + + void cancel_async () + { + m_probe.cancel_async (); + } + }; + public: beast::Journal m_journal; Application::LockType m_masterMutex; @@ -167,35 +231,10 @@ public: std::unique_ptr m_resolver; - beast::io_latency_probe m_probe; + io_latency_sampler m_io_latency_sampler; //-------------------------------------------------------------------------- - class sample_io_service_latency - { - public: - beast::insight::Event latency; - beast::Journal journal; - - sample_io_service_latency (beast::insight::Event latency_, - beast::Journal journal_) - : latency (latency_) - , journal (journal_) - { - } - - template - void operator() (Duration const& elapsed) const - { - auto ms (ceil (elapsed)); - if (ms.count() >= 10) - latency.notify (ms); - if (ms.count() >= 500) - journal.warning << - "io_service latency = " << ms; - } - }; - static std::vector > make_Factories () { std::vector > list; @@ -315,7 +354,9 @@ public: , m_resolver (ResolverAsio::New (m_mainIoPool.getService (), beast::Journal ())) - , m_probe (std::chrono::milliseconds (100), m_mainIoPool.getService()) + , m_io_latency_sampler (m_collectorManager->collector()->make_event ("ios_latency"), + LogPartition::getJournal (), + std::chrono::milliseconds (100), m_mainIoPool.getService()) { add (m_resourceManager.get ()); @@ -385,6 +426,13 @@ public: return m_mainIoPool; } + std::chrono::milliseconds getIOLatency () + { + std::unique_lock m_IOLatencyLock; + + return m_io_latency_sampler.get (); + } + LedgerMaster& getLedgerMaster () { return *m_ledgerMaster; @@ -848,9 +896,7 @@ public: m_sweepTimer.setExpiration (10); - m_probe.sample (sample_io_service_latency ( - m_collectorManager->collector()->make_event ( - "ios_latency"), LogPartition::getJournal ())); + m_io_latency_sampler.start(); m_resolver->start (); } @@ -860,7 +906,7 @@ public: { m_journal.debug << "Application stopping"; - m_probe.cancel_async (); + m_io_latency_sampler.cancel_async (); // VFALCO Enormous hack, we have to force the probe to cancel // before we stop the io_service queue or else it never @@ -868,7 +914,7 @@ public: // io_objects gracefully handle exit so that we can // naturally return from io_service::run() instead of // forcing a call to io_service::stop() - m_probe.cancel (); + m_io_latency_sampler.cancel (); m_resolver->stop_async (); diff --git a/src/ripple_app/main/Application.h b/src/ripple_app/main/Application.h index 99bea55b18..c9962c3cc8 100644 --- a/src/ripple_app/main/Application.h +++ b/src/ripple_app/main/Application.h @@ -111,6 +111,8 @@ public: virtual DatabaseCon* getTxnDB () = 0; virtual DatabaseCon* getLedgerDB () = 0; + virtual std::chrono::milliseconds getIOLatency () = 0; + /** Retrieve the "wallet database" It looks like this is used to store the unique node list. diff --git a/src/ripple_app/misc/NetworkOPs.cpp b/src/ripple_app/misc/NetworkOPs.cpp index 0f21a979bd..0f1120a1ca 100644 --- a/src/ripple_app/misc/NetworkOPs.cpp +++ b/src/ripple_app/misc/NetworkOPs.cpp @@ -2195,6 +2195,8 @@ Json::Value NetworkOPsImp::getServerInfo (bool human, bool admin) info[jss::validation_quorum] = m_ledgerMaster.getMinValidations (); + info["io_latency_ms"] = static_cast (getApp().getIOLatency().count()); + if (admin) { if (getConfig ().VALIDATION_PUB.isValid ())