@@ -60,6 +60,8 @@ void JsonRpcConnection::Start()
60
60
61
61
void JsonRpcConnection::HandleIncomingMessages (boost::asio::yield_context yc)
62
62
{
63
+ namespace ch = std::chrono;
64
+
63
65
m_Stream->next_layer ().SetSeen (&m_Seen);
64
66
65
67
for (;;) {
@@ -78,9 +80,37 @@ void JsonRpcConnection::HandleIncomingMessages(boost::asio::yield_context yc)
78
80
m_Seen = Utility::GetTime ();
79
81
80
82
try {
83
+ auto start (ch::steady_clock::now ());
84
+ ch::steady_clock::duration cpuBoundDuration;
85
+
86
+ String rpcMethod;
87
+
88
+ Defer addLogStats ([this , &rpcMethod, &start, &cpuBoundDuration]() {
89
+ auto severity = LogDebug;
90
+
91
+ auto duration = ch::steady_clock::now () - start;
92
+ if (duration >= ch::seconds (5 )) {
93
+ // Processing that RPC message seems to take an unexpectedly long time,
94
+ // so promote the log entry from debug to warning.
95
+ severity = LogWarning;
96
+ }
97
+
98
+ Log statsLog (severity, " JsonRpcConnection" );
99
+ statsLog << " Processing JSON-RPC '" << rpcMethod << " ' message for identity '" << m_Identity << " '" ;
100
+
101
+ if (cpuBoundDuration >= ch::seconds (1 )) {
102
+ statsLog << " waited '" << ch::duration_cast<ch::milliseconds>(cpuBoundDuration).count () << " ms' on semaphore and" ;
103
+ }
104
+
105
+ statsLog << " took total " << ch::duration_cast<ch::milliseconds>(duration).count () << " ms." ;
106
+ });
107
+
81
108
CpuBoundWork handleMessage (yc);
82
109
83
- MessageHandler (message);
110
+ // Cache the elapsed time to acquire a CPU semaphore used to detect extremely heavy workloads.
111
+ cpuBoundDuration = ch::steady_clock::now () - start;
112
+
113
+ MessageHandler (message, rpcMethod);
84
114
85
115
l_TaskStats.InsertValue (Utility::GetTime (), 1 );
86
116
} catch (const std::exception& ex) {
@@ -245,9 +275,13 @@ void JsonRpcConnection::Disconnect()
245
275
});
246
276
}
247
277
248
- void JsonRpcConnection::MessageHandler (const String& jsonString)
278
+ void JsonRpcConnection::MessageHandler (const String& jsonString, String& rpcMethod )
249
279
{
250
280
Dictionary::Ptr message = JsonRpc::DecodeMessage (jsonString);
281
+ rpcMethod = message->Get (" method" );
282
+ if (rpcMethod.IsEmpty ()) {
283
+ rpcMethod = " UNKNOWN" ;
284
+ }
251
285
252
286
if (m_Endpoint && message->Contains (" ts" )) {
253
287
double ts = message->Get (" ts" );
0 commit comments