diff --git a/Builds/VisualStudio2013/RippleD.vcxproj b/Builds/VisualStudio2013/RippleD.vcxproj index 8031d9ade..02920617c 100755 --- a/Builds/VisualStudio2013/RippleD.vcxproj +++ b/Builds/VisualStudio2013/RippleD.vcxproj @@ -2560,6 +2560,9 @@ True + + True + @@ -2568,6 +2571,8 @@ + + diff --git a/Builds/VisualStudio2013/RippleD.vcxproj.filters b/Builds/VisualStudio2013/RippleD.vcxproj.filters index 6726fc089..532cc2966 100644 --- a/Builds/VisualStudio2013/RippleD.vcxproj.filters +++ b/Builds/VisualStudio2013/RippleD.vcxproj.filters @@ -3654,6 +3654,9 @@ ripple\nodestore\impl + + ripple\nodestore\impl + ripple\nodestore\impl @@ -3666,6 +3669,9 @@ ripple\nodestore + + ripple\nodestore + ripple\nodestore diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index bf2f03b1a..54ef26637 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -311,9 +311,8 @@ public: // VFALCO NOTE LocalCredentials starts the deprecated UNL service , m_deprecatedUNL (make_UniqueNodeList (*m_jobQueue)) - , serverHandler_ (make_ServerHandler (*m_networkOPs, - get_io_service(), *m_jobQueue, *m_networkOPs, - *m_resourceManager)) + , serverHandler_ (make_ServerHandler (*m_networkOPs, get_io_service (), + *m_jobQueue, *m_networkOPs, *m_resourceManager, *m_collectorManager)) , m_sntpClient (SNTPClient::New (*this)) @@ -743,7 +742,8 @@ public: { if (! port.websockets()) continue; - auto door = make_WSDoor(port, *m_resourceManager, getOPs()); + auto door (make_WSDoor (port, *m_resourceManager, getOPs (), + *m_collectorManager)); if (door == nullptr) { m_journal.fatal << "Could not create Websocket for [" << diff --git a/src/ripple/app/websocket/WSConnection.cpp b/src/ripple/app/websocket/WSConnection.cpp index c0041d09b..bf9447fcc 100644 --- a/src/ripple/app/websocket/WSConnection.cpp +++ b/src/ripple/app/websocket/WSConnection.cpp @@ -23,7 +23,6 @@ #include #include #include -#include #include namespace ripple { @@ -177,6 +176,7 @@ Json::Value WSConnection::invokeCommand (Json::Value& jvRequest) jvRequest, loadType, m_netOPs, role, std::dynamic_pointer_cast (this->shared_from_this ())}; RPC::doCommand (context, jvResult[jss::result]); + recordMetrics (context); } getConsumer().charge (loadType); diff --git a/src/ripple/app/websocket/WSConnection.h b/src/ripple/app/websocket/WSConnection.h index 98c2ca0d8..96e46b3aa 100644 --- a/src/ripple/app/websocket/WSConnection.h +++ b/src/ripple/app/websocket/WSConnection.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -59,6 +60,8 @@ protected: virtual void preDestroy () = 0; virtual void disconnect () = 0; + + virtual void recordMetrics (RPC::Context const&) const = 0; public: void onPong (std::string const&); @@ -142,6 +145,11 @@ public: // Just discards the reference } + void recordMetrics (RPC::Context const& context) const override + { + m_serverHandler.recordMetrics (context); + } + // Implement overridden functions from base class: void send (Json::Value const& jvObj, bool broadcast) { diff --git a/src/ripple/app/websocket/WSDoor.cpp b/src/ripple/app/websocket/WSDoor.cpp index 15246f43d..a21037cca 100644 --- a/src/ripple/app/websocket/WSDoor.cpp +++ b/src/ripple/app/websocket/WSDoor.cpp @@ -57,15 +57,17 @@ private: InfoSub::Source& m_source; LockType m_endpointLock; std::shared_ptr m_endpoint; + CollectorManager& collectorManager_; public: WSDoorImp (HTTP::Port const& port, Resource::Manager& resourceManager, - InfoSub::Source& source) + InfoSub::Source& source, CollectorManager& cm) : WSDoor (source) , Thread ("websocket") , port_(std::make_shared(port)) , m_resourceManager (resourceManager) , m_source (source) + , collectorManager_ (cm) { startThread (); } @@ -85,7 +87,7 @@ private: websocketpp_02::server_autotls::handler::ptr handler ( new WSServerHandler ( - port_, m_resourceManager, m_source)); + port_, m_resourceManager, m_source, collectorManager_)); { ScopedLockType lock (m_endpointLock); @@ -162,13 +164,13 @@ WSDoor::WSDoor (Stoppable& parent) std::unique_ptr make_WSDoor (HTTP::Port const& port, Resource::Manager& resourceManager, - InfoSub::Source& source) + InfoSub::Source& source, CollectorManager& cm) { std::unique_ptr door; try { - door = std::make_unique (port, resourceManager, source); + door = std::make_unique (port, resourceManager, source, cm); } catch (...) { diff --git a/src/ripple/app/websocket/WSDoor.h b/src/ripple/app/websocket/WSDoor.h index fc2c41214..d93810acf 100644 --- a/src/ripple/app/websocket/WSDoor.h +++ b/src/ripple/app/websocket/WSDoor.h @@ -42,7 +42,7 @@ public: std::unique_ptr make_WSDoor (HTTP::Port const& port, Resource::Manager& resourceManager, - InfoSub::Source& source); + InfoSub::Source& source, CollectorManager& cm); } diff --git a/src/ripple/app/websocket/WSServerHandler.h b/src/ripple/app/websocket/WSServerHandler.h index c5185d7c4..2e4df6f2e 100644 --- a/src/ripple/app/websocket/WSServerHandler.h +++ b/src/ripple/app/websocket/WSServerHandler.h @@ -69,6 +69,10 @@ private: std::shared_ptr port_; Resource::Manager& m_resourceManager; InfoSub::Source& m_source; + beast::insight::Counter rpc_requests_; + beast::insight::Event rpc_io_; + beast::insight::Event rpc_size_; + beast::insight::Event rpc_time_; protected: // VFALCO TODO Make this private. @@ -82,11 +86,17 @@ protected: public: WSServerHandler (std::shared_ptr const& port, - Resource::Manager& resourceManager, InfoSub::Source& source) + Resource::Manager& resourceManager, InfoSub::Source& source, + CollectorManager& cm) : port_(port) , m_resourceManager (resourceManager) , m_source (source) { + auto const& group (cm.group ("rpc")); + rpc_requests_ = group->make_counter ("requests"); + rpc_io_ = group->make_event ("io"); + rpc_size_ = group->make_event ("size"); + rpc_time_ = group->make_event ("time"); } WSServerHandler(WSServerHandler const&) = delete; @@ -426,8 +436,17 @@ public: if (jCmd.isString()) job.rename (std::string ("WSClient::") + jCmd.asString()); } - - send (cpClient, conn->invokeCommand (jvRequest), false); + + auto const start (std::chrono::high_resolution_clock::now ()); + Json::Value const jvObj (conn->invokeCommand (jvRequest)); + std::string const buffer (to_string (jvObj)); + rpc_time_.notify (static_cast ( + std::chrono::duration_cast ( + std::chrono::high_resolution_clock::now () - start))); + ++rpc_requests_; + rpc_size_.notify (static_cast + (buffer.size ())); + send (cpClient, buffer, false); } return true; @@ -470,6 +489,12 @@ public: " Test

This page shows http(s) connectivity is working.

"); return true; } + + void recordMetrics (RPC::Context const& context) const + { + rpc_io_.notify (static_cast ( + context.metrics.fetches)); + } }; } // ripple diff --git a/src/ripple/nodestore/ScopedMetrics.h b/src/ripple/nodestore/ScopedMetrics.h new file mode 100644 index 000000000..0d5631a2e --- /dev/null +++ b/src/ripple/nodestore/ScopedMetrics.h @@ -0,0 +1,52 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012, 2013 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef RIPPLE_NODESTORE_SCOPEDMETRICS_H_INCLUDED +#define RIPPLE_NODESTORE_SCOPEDMETRICS_H_INCLUDED + +#include + +namespace ripple { +namespace NodeStore { + +/** RAII observer to track NodeStore fetches made by the calling thread. */ +class ScopedMetrics +{ +private: + ScopedMetrics* prev_; + +public: + ScopedMetrics (); + ~ScopedMetrics (); + + static + ScopedMetrics* + get (); + + static + void + incrementThreadFetches (); + + std::size_t fetches = 0; +}; + +} +} + +#endif diff --git a/src/ripple/nodestore/impl/DatabaseImp.h b/src/ripple/nodestore/impl/DatabaseImp.h index 7775f9f12..e3a45a05b 100644 --- a/src/ripple/nodestore/impl/DatabaseImp.h +++ b/src/ripple/nodestore/impl/DatabaseImp.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -167,6 +168,8 @@ public: NodeObject::Ptr fetch (uint256 const& hash) override { + ScopedMetrics::incrementThreadFetches (); + return doTimedFetch (hash, false); } diff --git a/src/ripple/nodestore/impl/ScopedMetrics.cpp b/src/ripple/nodestore/impl/ScopedMetrics.cpp new file mode 100644 index 000000000..939ad6535 --- /dev/null +++ b/src/ripple/nodestore/impl/ScopedMetrics.cpp @@ -0,0 +1,59 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012, 2013 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#include +#include + +namespace ripple { +namespace NodeStore { + +static +void +cleanup (ScopedMetrics*) +{ +} + +static +boost::thread_specific_ptr scopedMetricsPtr (&cleanup); + +ScopedMetrics::ScopedMetrics () : prev_ (scopedMetricsPtr.get ()) +{ + scopedMetricsPtr.reset (this); +} + +ScopedMetrics::~ScopedMetrics () +{ + scopedMetricsPtr.reset (prev_); +} + +ScopedMetrics* +ScopedMetrics::get () +{ + return scopedMetricsPtr.get (); +} + +void +ScopedMetrics::incrementThreadFetches () +{ + if (scopedMetricsPtr.get ()) + ++scopedMetricsPtr.get ()->fetches; +} + +} +} diff --git a/src/ripple/rpc/Context.h b/src/ripple/rpc/Context.h index 59fbaaa1d..5cba92b3d 100644 --- a/src/ripple/rpc/Context.h +++ b/src/ripple/rpc/Context.h @@ -24,6 +24,7 @@ #include #include #include +#include namespace ripple { @@ -40,6 +41,7 @@ struct Context Role role; InfoSub::pointer infoSub; RPC::Yield yield; + NodeStore::ScopedMetrics metrics; }; } // RPC diff --git a/src/ripple/server/impl/ServerHandlerImp.cpp b/src/ripple/server/impl/ServerHandlerImp.cpp index 42267f41e..8753f943d 100644 --- a/src/ripple/server/impl/ServerHandlerImp.cpp +++ b/src/ripple/server/impl/ServerHandlerImp.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include // #include #include @@ -53,7 +54,8 @@ ServerHandler::ServerHandler (Stoppable& parent) ServerHandlerImp::ServerHandlerImp (Stoppable& parent, boost::asio::io_service& io_service, JobQueue& jobQueue, - NetworkOPs& networkOPs, Resource::Manager& resourceManager) + NetworkOPs& networkOPs, Resource::Manager& resourceManager, + CollectorManager& cm) : ServerHandler (parent) , m_resourceManager (resourceManager) , m_journal (deprecatedLogs().journal("Server")) @@ -62,6 +64,11 @@ ServerHandlerImp::ServerHandlerImp (Stoppable& parent, , m_server (HTTP::make_Server( *this, io_service, deprecatedLogs().journal("Server"))) { + auto const& group (cm.group ("rpc")); + rpc_requests_ = group->make_counter ("requests"); + rpc_io_ = group->make_event ("io"); + rpc_size_ = group->make_event ("size"); + rpc_time_ = group->make_event ("time"); } ServerHandlerImp::~ServerHandlerImp() @@ -362,6 +369,7 @@ ServerHandlerImp::processRequest ( WriteLog (lsTRACE, RPCHandler) << "doRpcCommand:" << strMethod << ":" << params; + auto const start (std::chrono::high_resolution_clock::now ()); RPC::Context context {params, loadType, m_networkOPs, role, nullptr, yield}; std::string response; @@ -393,6 +401,15 @@ ServerHandlerImp::processRequest ( response = to_string (reply); } + rpc_time_.notify (static_cast ( + std::chrono::duration_cast ( + std::chrono::high_resolution_clock::now () - start))); + ++rpc_requests_; + rpc_io_.notify (static_cast ( + context.metrics.fetches)); + rpc_size_.notify (static_cast ( + response.size ())); + response += '\n'; usage.charge (loadType); @@ -814,11 +831,12 @@ setup_ServerHandler (BasicConfig const& config, std::ostream& log) std::unique_ptr make_ServerHandler (beast::Stoppable& parent, - boost::asio::io_service& io_service, JobQueue& jobQueue, - NetworkOPs& networkOPs, Resource::Manager& resourceManager) + boost::asio::io_service& io_service, JobQueue& jobQueue, + NetworkOPs& networkOPs, Resource::Manager& resourceManager, + CollectorManager& cm) { return std::make_unique (parent, io_service, - jobQueue, networkOPs, resourceManager); + jobQueue, networkOPs, resourceManager, cm); } } diff --git a/src/ripple/server/impl/ServerHandlerImp.h b/src/ripple/server/impl/ServerHandlerImp.h index ccca56c1b..36aa5d288 100644 --- a/src/ripple/server/impl/ServerHandlerImp.h +++ b/src/ripple/server/impl/ServerHandlerImp.h @@ -25,6 +25,7 @@ #include #include #include +#include namespace ripple { @@ -41,11 +42,15 @@ private: NetworkOPs& m_networkOPs; std::unique_ptr m_server; Setup setup_; + beast::insight::Counter rpc_requests_; + beast::insight::Event rpc_io_; + beast::insight::Event rpc_size_; + beast::insight::Event rpc_time_; public: ServerHandlerImp (Stoppable& parent, boost::asio::io_service& io_service, JobQueue& jobQueue, NetworkOPs& networkOPs, - Resource::Manager& resourceManager); + Resource::Manager& resourceManager, CollectorManager& cm); ~ServerHandlerImp(); diff --git a/src/ripple/server/make_ServerHandler.h b/src/ripple/server/make_ServerHandler.h index c1353ede7..b21468e08 100644 --- a/src/ripple/server/make_ServerHandler.h +++ b/src/ripple/server/make_ServerHandler.h @@ -33,7 +33,8 @@ class NetworkOPs; std::unique_ptr make_ServerHandler (beast::Stoppable& parent, boost::asio::io_service& io_service, - JobQueue& jobQueue, NetworkOPs& networkOPs, Resource::Manager& resourceManager); + JobQueue& jobQueue, NetworkOPs& networkOPs, Resource::Manager& resourceManager, + CollectorManager& cm); } // ripple diff --git a/src/ripple/unity/nodestore.cpp b/src/ripple/unity/nodestore.cpp index ee032dee3..da4a8281c 100644 --- a/src/ripple/unity/nodestore.cpp +++ b/src/ripple/unity/nodestore.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include