feat(network): Accumulate stats from all interfaces

Add config setting that will display accumulated
values for up-/downspeed (accumulate-stats = true)

Closes #144
This commit is contained in:
Michael Carlberg 2016-11-14 12:42:58 +01:00
parent 611dbcd6cd
commit 983963d4e4
4 changed files with 27 additions and 22 deletions

View File

@ -53,7 +53,7 @@ namespace net {
explicit network(string interface);
virtual ~network();
virtual bool query();
virtual bool query(bool accumulate = false);
virtual bool connected() const = 0;
virtual bool ping() const;
@ -77,7 +77,7 @@ namespace net {
public:
explicit wired_network(string interface) : network(interface) {}
bool query() override;
bool query(bool accumulate = false) override;
bool connected() const override;
string linkspeed() const;
@ -92,7 +92,7 @@ namespace net {
public:
wireless_network(string interface) : network(interface) {}
bool query() override;
bool query(bool accumulate = false) override;
bool connected() const override;
string essid() const;

View File

@ -55,6 +55,7 @@ namespace modules {
string m_interface;
int m_ping_nth_update = 0;
int m_udspeed_minwidth = 3;
bool m_accumulate = false;
};
}

View File

@ -59,33 +59,37 @@ namespace net {
/**
* Query device driver for information
*/
bool network::query() {
bool network::query(bool accumulate) {
struct ifaddrs* ifaddr;
if (getifaddrs(&ifaddr) == -1)
return false;
m_status.previous = m_status.current;
m_status.current.transmitted = 0;
m_status.current.received = 0;
m_status.current.time = chrono::system_clock::now();
for (auto ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) {
if (m_interface.compare(0, m_interface.length(), ifa->ifa_name) != 0)
if (m_interface.compare(0, m_interface.length(), ifa->ifa_name) != 0) {
if (!accumulate || ifa->ifa_addr->sa_family != AF_PACKET) {
continue;
}
}
switch (ifa->ifa_addr->sa_family) {
case AF_INET:
char ip_buffer[NI_MAXHOST];
getnameinfo(ifa->ifa_addr, sizeof(sockaddr_in), ip_buffer, NI_MAXHOST, nullptr, 0,
NI_NUMERICHOST);
getnameinfo(ifa->ifa_addr, sizeof(sockaddr_in), ip_buffer, NI_MAXHOST, nullptr, 0, NI_NUMERICHOST);
m_status.ip = string{ip_buffer};
break;
case AF_PACKET:
if (ifa->ifa_data == nullptr)
continue;
struct rtnl_link_stats* link_state =
reinterpret_cast<decltype(link_state)>(ifa->ifa_data);
m_status.previous = m_status.current;
m_status.current.transmitted = link_state->tx_bytes;
m_status.current.received = link_state->rx_bytes;
m_status.current.time = chrono::system_clock::now();
struct rtnl_link_stats* link_state = reinterpret_cast<decltype(link_state)>(ifa->ifa_data);
m_status.current.transmitted += link_state->tx_bytes;
m_status.current.received += link_state->rx_bytes;
break;
}
}
@ -155,9 +159,8 @@ namespace net {
suffixes.pop_back();
}
return string_util::from_stream(stringstream() << std::setw(minwidth) << std::setfill(' ')
<< std::setprecision(0) << std::fixed
<< speedrate << " " << suffix << "/s");
return string_util::from_stream(stringstream() << std::setw(minwidth) << std::setfill(' ') << std::setprecision(0)
<< std::fixed << speedrate << " " << suffix << "/s");
}
// }}}
@ -166,8 +169,8 @@ namespace net {
/**
* Query device driver for information
*/
bool wired_network::query() {
if (!network::query())
bool wired_network::query(bool accumulate) {
if (!network::query(accumulate))
return false;
struct ethtool_cmd ethernet_data;
@ -220,8 +223,8 @@ namespace net {
* Query the wireless device for information
* about the current connection
*/
bool wireless_network::query() {
if (!network::query())
bool wireless_network::query(bool accumulate) {
if (!network::query(accumulate))
return false;
auto socket_fd = iw_sockets_open();

View File

@ -8,6 +8,7 @@ namespace modules {
REQ_CONFIG_VALUE(name(), m_interface, "interface");
GET_CONFIG_VALUE(name(), m_ping_nth_update, "ping-interval");
GET_CONFIG_VALUE(name(), m_udspeed_minwidth, "udspeed-minwidth");
GET_CONFIG_VALUE(name(), m_accumulate, "accumulate-stats");
m_interval = chrono::duration<double>(m_conf.get<float>(name(), "interval", 1));
@ -67,7 +68,7 @@ namespace modules {
net::network* network = m_wireless ? dynamic_cast<net::network*>(m_wireless.get())
: dynamic_cast<net::network*>(m_wired.get());
if (!network->query()) {
if (!network->query(m_accumulate)) {
m_log.warn("%s: Failed to query interface '%s'", name(), m_interface);
return false;
}