From f36ad9e6e7f5d849fc1c47f49b7fc3274e087474 Mon Sep 17 00:00:00 2001 From: psychon Date: Tue, 26 May 2009 18:38:58 +0000 Subject: [PATCH] Change the API for getting traffic stats We now have a central function CZNC::GetTrafficStats() which does all the ugly stuff and just returns the data which the caller can then display. We now also include all unknown sockets (e.g. imapauth or webadmin sockets) in the traffic stats in the "" section. The only downside to all this gloriousness is that this breaks the ordering of /msg *status traffic which is now sorted alphabetically which means that and aren't anymore in the places in which they used to be. I hope one can live with that... git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@1521 726aef4b-f618-498e-8847-2d620e286838 --- ClientCommand.cpp | 35 +++++++------------------------ znc.cpp | 53 +++++++++++++++++++++++++++++++++-------------- znc.h | 5 ++++- 3 files changed, 50 insertions(+), 43 deletions(-) diff --git a/ClientCommand.cpp b/ClientCommand.cpp index af555dc4..dbcaf36d 100644 --- a/ClientCommand.cpp +++ b/ClientCommand.cpp @@ -928,41 +928,22 @@ void CClient::UserCommand(const CString& sLine) { PutStatus("BufferCount for [" + sChan + "] set to [" + CString(pChan->GetBufferCount()) + "]"); } else if (m_pUser->IsAdmin() && sCommand.Equals("TRAFFIC")) { - CZNC::Get().UpdateTrafficStats(); - const map& msUsers = CZNC::Get().GetUserMap(); + map >::const_iterator it; + map > traffic = + CZNC::Get().GetTrafficStats(); CTable Table; Table.AddColumn("Username"); Table.AddColumn("In"); Table.AddColumn("Out"); Table.AddColumn("Total"); - unsigned long long users_total_in = 0; - unsigned long long users_total_out = 0; - for (map::const_iterator it = msUsers.begin(); it != msUsers.end(); it++) { + + for (it = traffic.begin(); it != traffic.end(); it++) { Table.AddRow(); Table.SetCell("Username", it->first); - Table.SetCell("In", CString::ToByteStr(it->second->BytesRead())); - Table.SetCell("Out", CString::ToByteStr(it->second->BytesWritten())); - Table.SetCell("Total", CString::ToByteStr(it->second->BytesRead() + it->second->BytesWritten())); - users_total_in += it->second->BytesRead(); - users_total_out += it->second->BytesWritten(); + Table.SetCell("In", CString::ToByteStr(it->second.first)); + Table.SetCell("Out", CString::ToByteStr(it->second.second)); + Table.SetCell("Total", CString::ToByteStr(it->second.first + it->second.second)); } - Table.AddRow(); - Table.SetCell("Username", ""); - Table.SetCell("In", CString::ToByteStr(users_total_in)); - Table.SetCell("Out", CString::ToByteStr(users_total_out)); - Table.SetCell("Total", CString::ToByteStr(users_total_in + users_total_out)); - - Table.AddRow(); - Table.SetCell("Username", ""); - Table.SetCell("In", CString::ToByteStr(CZNC::Get().BytesRead())); - Table.SetCell("Out", CString::ToByteStr(CZNC::Get().BytesWritten())); - Table.SetCell("Total", CString::ToByteStr(CZNC::Get().BytesRead() + CZNC::Get().BytesWritten())); - - Table.AddRow(); - Table.SetCell("Username", ""); - Table.SetCell("In", CString::ToByteStr(users_total_in + CZNC::Get().BytesRead())); - Table.SetCell("Out", CString::ToByteStr(users_total_out + CZNC::Get().BytesWritten())); - Table.SetCell("Total", CString::ToByteStr(users_total_in + CZNC::Get().BytesRead() + users_total_out + CZNC::Get().BytesWritten())); PutStatus(Table); } else if (m_pUser->IsAdmin() && sCommand.Equals("UPTIME")) { diff --git a/znc.cpp b/znc.cpp index d29db9e6..b52b6934 100644 --- a/znc.cpp +++ b/znc.cpp @@ -1726,23 +1726,46 @@ CZNC& CZNC::Get() { return *pZNC; } -void CZNC::UpdateTrafficStats() { - CSockManager* p = &m_Manager; - for (unsigned int a = 0; a < p->size(); a++) { - if ((*p)[a]->GetSockName().Left(5) == "IRC::") { - CIRCSock *i = (CIRCSock *)(*p)[a]; - i->GetUser()->AddBytesRead((*p)[a]->GetBytesRead()); - (*p)[a]->ResetBytesRead(); - i->GetUser()->AddBytesWritten((*p)[a]->GetBytesWritten()); - (*p)[a]->ResetBytesWritten(); - } else if ((*p)[a]->GetSockName().Left(5) == "USR::") { - CClient *c = (CClient *)(*p)[a]; - c->GetUser()->AddBytesRead((*p)[a]->GetBytesRead()); - (*p)[a]->ResetBytesRead(); - c->GetUser()->AddBytesWritten((*p)[a]->GetBytesWritten()); - (*p)[a]->ResetBytesWritten(); +map > CZNC::GetTrafficStats() { + map > ret; + unsigned long long uiUsers_in, uiUsers_out, uiZNC_in, uiZNC_out; + const map& msUsers = CZNC::Get().GetUserMap(); + + uiUsers_in = uiUsers_out = 0; + uiZNC_in = BytesRead(); + uiZNC_out = BytesWritten(); + + for (map::const_iterator it = msUsers.begin(); it != msUsers.end(); it++) { + ret[it->first] = std::pair + (it->second->BytesRead(), it->second->BytesWritten()); + uiUsers_in += it->second->BytesRead(); + uiUsers_out += it->second->BytesWritten(); + } + + for (CSockManager::const_iterator it = m_Manager.begin(); it != m_Manager.end(); it++) { + if ((*it)->GetSockName().Left(5) == "IRC::") { + CIRCSock *p = (CIRCSock *) *it; + ret[p->GetUser()->GetUserName()].first += p->GetBytesRead(); + ret[p->GetUser()->GetUserName()].second += p->GetBytesWritten(); + uiUsers_in += p->GetBytesRead(); + uiUsers_out += p->GetBytesWritten(); + } else if ((*it)->GetSockName().Left(5) == "USR::") { + CClient *p = (CClient *) *it; + ret[p->GetUser()->GetUserName()].first += p->GetBytesRead(); + ret[p->GetUser()->GetUserName()].second += p->GetBytesWritten(); + uiUsers_in += p->GetBytesRead(); + uiUsers_out += p->GetBytesWritten(); + } else { + uiZNC_in += (*it)->GetBytesRead(); + uiZNC_out += (*it)->GetBytesWritten(); } } + + ret[""] = std::pair(uiUsers_in, uiUsers_out); + ret[""] = std::pair(uiZNC_in, uiZNC_out); + ret[""] = std::pair(uiUsers_in + uiZNC_in, uiUsers_out + uiZNC_out); + + return ret; } void CZNC::AuthUser(CSmartPtr AuthClass) { diff --git a/znc.h b/znc.h index 44913dcf..3549cb68 100644 --- a/znc.h +++ b/znc.h @@ -124,7 +124,10 @@ public: void AddBytesWritten(unsigned long long u) { m_uBytesWritten += u; } unsigned long long BytesRead() const { return m_uBytesRead; } unsigned long long BytesWritten() const { return m_uBytesWritten; } - void UpdateTrafficStats(); + // Returns a map which maps user names to , special + // "usernames" are (All users total), (Traffic which couldn't be + // accounted to any user) and (Total traffic, + ). + map > GetTrafficStats(); // Authenticate a user. // The result is passed back via callbacks to CAuthBase.