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

View File

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

View File

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

View File

@ -8,6 +8,7 @@ namespace modules {
REQ_CONFIG_VALUE(name(), m_interface, "interface"); REQ_CONFIG_VALUE(name(), m_interface, "interface");
GET_CONFIG_VALUE(name(), m_ping_nth_update, "ping-interval"); GET_CONFIG_VALUE(name(), m_ping_nth_update, "ping-interval");
GET_CONFIG_VALUE(name(), m_udspeed_minwidth, "udspeed-minwidth"); 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)); 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()) net::network* network = m_wireless ? dynamic_cast<net::network*>(m_wireless.get())
: dynamic_cast<net::network*>(m_wired.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); m_log.warn("%s: Failed to query interface '%s'", name(), m_interface);
return false; return false;
} }