diff options
author | Attila Molnar <attilamolnar@hush.com> | 2014-02-08 22:40:30 +0100 |
---|---|---|
committer | Attila Molnar <attilamolnar@hush.com> | 2014-02-08 22:40:30 +0100 |
commit | 689996cb8856af43a033eb5ca1cb9df7475c0854 (patch) | |
tree | 258bbb81046a8cefe49a65d4f15ea36779352261 | |
parent | aea38a0dd702895b7dfd18efd26a0dcead2279fc (diff) |
Move socketengine stats into a new class
-rw-r--r-- | include/socketengine.h | 57 | ||||
-rw-r--r-- | src/commands/cmd_stats.cpp | 15 | ||||
-rw-r--r-- | src/socketengine.cpp | 32 | ||||
-rw-r--r-- | src/socketengines/socketengine_epoll.cpp | 10 | ||||
-rw-r--r-- | src/socketengines/socketengine_kqueue.cpp | 8 | ||||
-rw-r--r-- | src/socketengines/socketengine_ports.cpp | 6 | ||||
-rw-r--r-- | src/socketengines/socketengine_select.cpp | 6 |
7 files changed, 86 insertions, 48 deletions
diff --git a/include/socketengine.h b/include/socketengine.h index d4d6c4c1c..6503ea293 100644 --- a/include/socketengine.h +++ b/include/socketengine.h @@ -230,6 +230,45 @@ class CoreExport EventHandler : public classbase */ class CoreExport SocketEngine { + public: + /** Socket engine statistics: count of various events, bandwidth usage + */ + class Statistics + { + mutable size_t indata; + mutable size_t outdata; + mutable time_t lastempty; + + /** Reset the byte counters and lastempty if there wasn't a reset in this second. + */ + void CheckFlush() const; + + public: + /** Constructor, initializes member vars except indata and outdata because those are set to 0 + * in CheckFlush() the first time Update() or GetBandwidth() is called. + */ + Statistics() : lastempty(0), TotalEvents(0), ReadEvents(0), WriteEvents(0), ErrorEvents(0) { } + + /** Increase the counters for bytes sent/received in this second. + * @param len_in Bytes received, 0 if updating number of bytes written. + * @param len_out Bytes sent, 0 if updating number of bytes read. + */ + void Update(size_t len_in, size_t len_out); + + /** Get data transfer statistics. + * @param kbitspersec_in Filled with incoming traffic in this second in kbit/s. + * @param kbitspersec_out Filled with outgoing traffic in this second in kbit/s. + * @param kbitspersec_total Filled with total traffic in this second in kbit/s. + */ + void CoreExport GetBandwidth(float& kbitpersec_in, float& kbitpersec_out, float& kbitpersec_total) const; + + unsigned long TotalEvents; + unsigned long ReadEvents; + unsigned long WriteEvents; + unsigned long ErrorEvents; + }; + + private: /** Reference table, contains all current handlers **/ std::vector<EventHandler*> ref; @@ -244,11 +283,9 @@ class CoreExport SocketEngine int MAX_DESCRIPTORS; - size_t indata; - size_t outdata; - time_t lastempty; - - void UpdateStats(size_t len_in, size_t len_out); + /** Socket engine statistics: count of various events, bandwidth usage + */ + Statistics stats; virtual void OnSetEvent(EventHandler* eh, int old_mask, int new_mask) = 0; void SetEventMask(EventHandler* eh, int value); @@ -267,12 +304,6 @@ class CoreExport SocketEngine } public: - - unsigned long TotalEvents; - unsigned long ReadEvents; - unsigned long WriteEvents; - unsigned long ErrorEvents; - /** Constructor. * The constructor transparently initializes * the socket engine which the ircd is using. @@ -494,9 +525,9 @@ public: */ virtual void RecoverFromFork(); - /** Get data transfer statistics, kilobits per second in and out and total. + /** Get data transfer and event statistics */ - void GetStats(float &kbitpersec_in, float &kbitpersec_out, float &kbitpersec_total); + const Statistics& GetStats() const { return stats; } /** Should we ignore the error in errno? * Checks EAGAIN and WSAEWOULDBLOCK diff --git a/src/commands/cmd_stats.cpp b/src/commands/cmd_stats.cpp index 617f0a320..afcbe01e6 100644 --- a/src/commands/cmd_stats.cpp +++ b/src/commands/cmd_stats.cpp @@ -181,11 +181,14 @@ void CommandStats::DoStats(char statschar, User* user, string_list &results) ServerInstance->XLines->InvokeStats("E",223,user,results); break; case 'E': - results.push_back("249 "+user->nick+" :Total events: "+ConvToStr(ServerInstance->SE->TotalEvents)); - results.push_back("249 "+user->nick+" :Read events: "+ConvToStr(ServerInstance->SE->ReadEvents)); - results.push_back("249 "+user->nick+" :Write events: "+ConvToStr(ServerInstance->SE->WriteEvents)); - results.push_back("249 "+user->nick+" :Error events: "+ConvToStr(ServerInstance->SE->ErrorEvents)); - break; + { + const SocketEngine::Statistics& stats = ServerInstance->SE->GetStats(); + results.push_back("249 "+user->nick+" :Total events: "+ConvToStr(stats.TotalEvents)); + results.push_back("249 "+user->nick+" :Read events: "+ConvToStr(stats.ReadEvents)); + results.push_back("249 "+user->nick+" :Write events: "+ConvToStr(stats.WriteEvents)); + results.push_back("249 "+user->nick+" :Error events: "+ConvToStr(stats.ErrorEvents)); + break; + } /* stats m (list number of times each command has been used, plus bytecount) */ case 'm': @@ -209,7 +212,7 @@ void CommandStats::DoStats(char statschar, User* user, string_list &results) float kbitpersec_in, kbitpersec_out, kbitpersec_total; char kbitpersec_in_s[30], kbitpersec_out_s[30], kbitpersec_total_s[30]; - ServerInstance->SE->GetStats(kbitpersec_in, kbitpersec_out, kbitpersec_total); + ServerInstance->SE->GetStats().GetBandwidth(kbitpersec_in, kbitpersec_out, kbitpersec_total); snprintf(kbitpersec_total_s, 30, "%03.5f", kbitpersec_total); snprintf(kbitpersec_out_s, 30, "%03.5f", kbitpersec_out); diff --git a/src/socketengine.cpp b/src/socketengine.cpp index 35fe5292f..ba3d84512 100644 --- a/src/socketengine.cpp +++ b/src/socketengine.cpp @@ -36,9 +36,6 @@ void EventHandler::SetFd(int FD) SocketEngine::SocketEngine() { - TotalEvents = WriteEvents = ReadEvents = ErrorEvents = 0; - lastempty = ServerInstance->Time(); - indata = outdata = 0; CurrentSetSize = 0; } @@ -195,7 +192,7 @@ int SocketEngine::RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, s { int nbRecvd = recvfrom(fd->GetFd(), (char*)buf, len, flags, from, fromlen); if (nbRecvd > 0) - this->UpdateStats(nbRecvd, 0); + stats.Update(nbRecvd, 0); return nbRecvd; } @@ -203,7 +200,7 @@ int SocketEngine::Send(EventHandler* fd, const void *buf, size_t len, int flags) { int nbSent = send(fd->GetFd(), (const char*)buf, len, flags); if (nbSent > 0) - this->UpdateStats(0, nbSent); + stats.Update(0, nbSent); return nbSent; } @@ -211,7 +208,7 @@ int SocketEngine::Recv(EventHandler* fd, void *buf, size_t len, int flags) { int nbRecvd = recv(fd->GetFd(), (char*)buf, len, flags); if (nbRecvd > 0) - this->UpdateStats(nbRecvd, 0); + stats.Update(nbRecvd, 0); return nbRecvd; } @@ -219,7 +216,7 @@ int SocketEngine::SendTo(EventHandler* fd, const void *buf, size_t len, int flag { int nbSent = sendto(fd->GetFd(), (const char*)buf, len, flags, to, tolen); if (nbSent > 0) - this->UpdateStats(0, nbSent); + stats.Update(0, nbSent); return nbSent; } @@ -257,20 +254,27 @@ void SocketEngine::RecoverFromFork() { } -void SocketEngine::UpdateStats(size_t len_in, size_t len_out) +void SocketEngine::Statistics::Update(size_t len_in, size_t len_out) { - if (lastempty != ServerInstance->Time()) + CheckFlush(); + indata += len_in; + outdata += len_out; +} + +void SocketEngine::Statistics::CheckFlush() const +{ + // Reset the in/out byte counters if it has been more than a second + time_t now = ServerInstance->Time(); + if (lastempty != now) { - lastempty = ServerInstance->Time(); + lastempty = now; indata = outdata = 0; } - indata += len_in; - outdata += len_out; } -void SocketEngine::GetStats(float &kbitpersec_in, float &kbitpersec_out, float &kbitpersec_total) +void SocketEngine::Statistics::GetBandwidth(float& kbitpersec_in, float& kbitpersec_out, float& kbitpersec_total) const { - UpdateStats(0, 0); /* Forces emptying of the values if its been more than a second */ + CheckFlush(); float in_kbit = indata * 8; float out_kbit = outdata * 8; kbitpersec_total = ((in_kbit + out_kbit) / 1024); diff --git a/src/socketengines/socketengine_epoll.cpp b/src/socketengines/socketengine_epoll.cpp index 7ee01b2cc..39cc60606 100644 --- a/src/socketengines/socketengine_epoll.cpp +++ b/src/socketengines/socketengine_epoll.cpp @@ -185,7 +185,7 @@ int EPollEngine::DispatchEvents() int i = epoll_wait(EngineHandle, &events[0], events.size(), 1000); ServerInstance->UpdateTime(); - TotalEvents += i; + stats.TotalEvents += i; for (int j = 0; j < i; j++) { @@ -202,14 +202,14 @@ int EPollEngine::DispatchEvents() if (ev.events & EPOLLHUP) { - ErrorEvents++; + stats.ErrorEvents++; eh->HandleEvent(EVENT_ERROR, 0); continue; } if (ev.events & EPOLLERR) { - ErrorEvents++; + stats.ErrorEvents++; /* Get error number */ socklen_t codesize = sizeof(int); int errcode; @@ -235,7 +235,7 @@ int EPollEngine::DispatchEvents() SetEventMask(eh, mask); if (ev.events & EPOLLIN) { - ReadEvents++; + stats.ReadEvents++; eh->HandleEvent(EVENT_READ); if (eh != GetRef(ev.data.fd)) // whoa! we got deleted, better not give out the write event @@ -243,7 +243,7 @@ int EPollEngine::DispatchEvents() } if (ev.events & EPOLLOUT) { - WriteEvents++; + stats.WriteEvents++; eh->HandleEvent(EVENT_WRITE); } } diff --git a/src/socketengines/socketengine_kqueue.cpp b/src/socketengines/socketengine_kqueue.cpp index c51789b29..0a9a0a399 100644 --- a/src/socketengines/socketengine_kqueue.cpp +++ b/src/socketengines/socketengine_kqueue.cpp @@ -207,7 +207,7 @@ int KQueueEngine::DispatchEvents() if (i < 0) return i; - TotalEvents += i; + stats.TotalEvents += i; for (int j = 0; j < i; j++) { @@ -223,13 +223,13 @@ int KQueueEngine::DispatchEvents() if (kev.flags & EV_EOF) { - ErrorEvents++; + stats.ErrorEvents++; eh->HandleEvent(EVENT_ERROR, kev.fflags); continue; } if (filter == EVFILT_WRITE) { - WriteEvents++; + stats.WriteEvents++; /* When mask is FD_WANT_FAST_WRITE or FD_WANT_SINGLE_WRITE, * we set a one-shot write, so we need to clear that bit * to detect when it set again. @@ -240,7 +240,7 @@ int KQueueEngine::DispatchEvents() } else if (filter == EVFILT_READ) { - ReadEvents++; + stats.ReadEvents++; SetEventMask(eh, eh->GetEventMask() & ~FD_READ_WILL_BLOCK); eh->HandleEvent(EVENT_READ); } diff --git a/src/socketengines/socketengine_ports.cpp b/src/socketengines/socketengine_ports.cpp index 226f59f04..e1fcc0e6c 100644 --- a/src/socketengines/socketengine_ports.cpp +++ b/src/socketengines/socketengine_ports.cpp @@ -148,7 +148,7 @@ int PortsEngine::DispatchEvents() if (ret == -1) return -1; - TotalEvents += nget; + stats.TotalEvents += nget; unsigned int i; for (i = 0; i < nget; i++) @@ -175,14 +175,14 @@ int PortsEngine::DispatchEvents() port_associate(EngineHandle, PORT_SOURCE_FD, fd, mask_to_events(mask), eh); if (portev_events & POLLRDNORM) { - ReadEvents++; + stats.ReadEvents++; eh->HandleEvent(EVENT_READ); if (eh != GetRef(fd)) continue; } if (portev_events & POLLWRNORM) { - WriteEvents++; + stats.WriteEvents++; eh->HandleEvent(EVENT_WRITE); } } diff --git a/src/socketengines/socketengine_select.cpp b/src/socketengines/socketengine_select.cpp index 7aaa7aaf7..be380cb46 100644 --- a/src/socketengines/socketengine_select.cpp +++ b/src/socketengines/socketengine_select.cpp @@ -135,7 +135,7 @@ int SelectEngine::DispatchEvents() if (has_error) { - ErrorEvents++; + stats.ErrorEvents++; socklen_t codesize = sizeof(int); int errcode = 0; @@ -148,7 +148,7 @@ int SelectEngine::DispatchEvents() if (has_read) { - ReadEvents++; + stats.ReadEvents++; SetEventMask(ev, ev->GetEventMask() & ~FD_READ_WILL_BLOCK); ev->HandleEvent(EVENT_READ); if (ev != GetRef(i)) @@ -157,7 +157,7 @@ int SelectEngine::DispatchEvents() if (has_write) { - WriteEvents++; + stats.WriteEvents++; int newmask = (ev->GetEventMask() & ~(FD_WRITE_WILL_BLOCK | FD_WANT_SINGLE_WRITE)); this->OnSetEvent(ev, ev->GetEventMask(), newmask); SetEventMask(ev, newmask); |