/* This file is part of VoltDB. * Copyright (C) 2008-2017 VoltDB Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with VoltDB. If not, see <http://www.gnu.org/licenses/>. */ package org.voltdb.utils; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import org.voltcore.logging.VoltLogger; public class BandwidthMonitor { protected class Stats { public long totalBytesSent = 0; public long totalBytesReceived = 0; public long windowBytesSent = 0; public long windowBytesReceived = 0; } protected Stats m_globalStats = new Stats(); protected Map<String, Stats> m_statsByHost = new HashMap<String, Stats>(); protected final long m_startTS; protected long m_windowStartTS = 0; protected final long m_windowSizeInMS; private final VoltLogger m_logger; public BandwidthMonitor(int throughputDisplayPeriod, VoltLogger log) { // set up current window m_startTS = m_windowStartTS = System.currentTimeMillis(); m_logger = log; m_windowSizeInMS = throughputDisplayPeriod * 1000; } public void logBytesTransfered(String hostName, long byteCountSent, long byteCountReceived) { long now = System.currentTimeMillis(); Stats hostStats = m_statsByHost.get(hostName); if (hostStats == null) { hostStats = new Stats(); m_statsByHost.put(hostName, hostStats); } // check if we need a new window if ((now - m_windowStartTS) >= m_windowSizeInMS) { logStatistics(now, true, m_logger); // reset all the windows for all the hosts for (Entry<String, Stats> e : m_statsByHost.entrySet()) { e.getValue().windowBytesReceived = 0; e.getValue().windowBytesSent = 0; } // reset the global windows m_globalStats.windowBytesReceived = 0; m_globalStats.windowBytesSent = 0; // set a new window start m_windowStartTS += m_windowSizeInMS; } // update stats for this host hostStats.totalBytesReceived += byteCountReceived; hostStats.totalBytesSent += byteCountSent; hostStats.windowBytesReceived += byteCountReceived; hostStats.windowBytesSent += byteCountSent; // update global stats m_globalStats.totalBytesReceived += byteCountReceived; m_globalStats.totalBytesSent += byteCountSent; m_globalStats.windowBytesReceived += byteCountReceived; m_globalStats.windowBytesSent += byteCountSent; } public void removeHost(String hostName) { m_statsByHost.remove(hostName); } private void logStatsLine(String formatStr, String hostname, long windowSize, long sent, long received) { m_logger.info(String.format(formatStr, windowSize / 1000.0, hostname, received / (windowSize / 1000.0) / (1024.0 * 1024.0), sent / (windowSize / 1000.0) / (1024.0 * 1024.0))); } public void logStatistics(long currentTS, boolean includeWindow, VoltLogger log) { // log last 10s is requested if (includeWindow) { logStatsLine("In the previous %.0f s: %-15s rate was %.4f MB/s sent and %.4f MB/s received", "GLOBAL", m_windowSizeInMS, m_globalStats.windowBytesSent, m_globalStats.windowBytesReceived); for (Entry<String, Stats> e : m_statsByHost.entrySet()) { logStatsLine("In the previous %.0f s: %-15s rate was %.4f MB/s sent and %.4f MB/s received", e.getKey(), m_windowSizeInMS, e.getValue().windowBytesSent, e.getValue().windowBytesReceived); } } // log stats since the beginning logStatsLine("Since startup (%.0f s): %-15s rate was %.4f MB/s sent and %.4f MB/s received", "GLOBAL", currentTS - m_startTS, m_globalStats.totalBytesSent, m_globalStats.totalBytesReceived); for (Entry<String, Stats> e : m_statsByHost.entrySet()) { logStatsLine("Since startup (%.0f s): %-15s rate was %.4f MB/s sent and %.4f MB/s received", e.getKey(), currentTS - m_startTS, e.getValue().totalBytesSent, e.getValue().totalBytesReceived); } } }