diff --git a/src/Stats.cc b/src/Stats.cc index 55835613e9..05ce33daed 100644 --- a/src/Stats.cc +++ b/src/Stats.cc @@ -9,7 +9,7 @@ #include "ConnCompressor.h" #include "DNS_Mgr.h" #include "Trigger.h" - +#include "threading/Manager.h" int killed_by_inactivity = 0; @@ -217,6 +217,19 @@ void ProfileLogger::Log() current_timers[i])); } + file->Write(fmt("%0.6f Threads: current=%d\n", network_time, thread_mgr->NumThreads())); + + const threading::Manager::msg_stats_list& thread_stats = thread_mgr->GetMsgThreadStats(); + for ( threading::Manager::msg_stats_list::const_iterator i = thread_stats.begin(); + i != thread_stats.end(); ++i ) + { + threading::MsgThread::Stats s = i->second; + file->Write(fmt(" %20s in=%" PRIu64 " out=%" PRIu64 " pending=%" PRIu64 "/%" PRIu64 "\n", + i->first.c_str(), + s.sent_in, s.sent_out, + s.pending_in, s.pending_out)); + } + // Script-level state. unsigned int size, mem = 0; PDict(ID)* globals = global_scope()->Vars(); diff --git a/src/threading/Manager.cc b/src/threading/Manager.cc index d963876755..2e8f6eb1fc 100644 --- a/src/threading/Manager.cc +++ b/src/threading/Manager.cc @@ -101,4 +101,21 @@ void Manager::Process() next_beat = network_time + HEART_BEAT_INTERVAL; } +const threading::Manager::msg_stats_list& threading::Manager::GetMsgThreadStats() + { + stats.clear(); + + for ( msg_thread_list::iterator i = msg_threads.begin(); i != msg_threads.end(); i++ ) + { + MsgThread* t = *i; + + MsgThread::Stats s; + t->GetStats(&s); + + stats.push_back(std::make_pair(t->Name(),s)); + } + + return stats; + } + diff --git a/src/threading/Manager.h b/src/threading/Manager.h index 2c4f88fa1e..d2f97209c9 100644 --- a/src/threading/Manager.h +++ b/src/threading/Manager.h @@ -43,6 +43,25 @@ public: */ void Terminate(); + typedef std::list > msg_stats_list; + + /** + * Returns statistics from all current MsgThread instances. + * + * @return A list of statistics, with one entry for each MsgThread. + * Each entry is a tuple of thread name and statistics. The list + * reference remains valid until the next call to this method (or + * termination of the manager). + */ + const msg_stats_list& GetMsgThreadStats(); + + /** + * Returns the number of currently active threads. This counts all + * threads that are not yet joined, includingt any potentially in + * Terminating() state. + */ + int NumThreads() const { return all_threads.size(); } + protected: friend class BasicThread; friend class MsgThread; @@ -96,6 +115,8 @@ private: bool did_process; // True if the last Process() found some work to do. double next_beat; // Timestamp when the next heartbeat will be sent. + + msg_stats_list stats; }; }