/* * Copyright (c) 2014-2015 Spotify AB * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ /** * Copyright (C) 2014 Spotify AB */ package com.spotify.folsom; import java.lang.management.ManagementFactory; import java.util.ArrayDeque; import java.util.concurrent.atomic.AtomicLong; public class ProgressMeter { static class Delta { Delta(final long ops, final long time, final long latency) { this.ops = ops; this.time = time; this.latency = latency; } public final long ops; public final long time; public final long latency; } private long lastRows = 0; private long lastTime = System.nanoTime(); private long lastLatency = 0; private final long interval = 1000; private final String unit; private final AtomicLong latency = new AtomicLong(); private final AtomicLong operations = new AtomicLong(); private final ArrayDeque<Delta> deltas = new ArrayDeque<>(); private volatile boolean run = true; private final Thread worker; public ProgressMeter() { this("ops"); } public ProgressMeter(final String unit) { this.unit = unit; worker = new Thread(new Runnable() { public void run() { while (run) { try { Thread.sleep(interval); } catch (InterruptedException e) { continue; } progress(); } } }); worker.start(); } private void progress() { final long count = this.operations.get(); final long time = System.nanoTime(); final long latency = this.latency.get(); final long delta = count - lastRows; final long deltaTime = time - lastTime; final long deltaLatency = latency - lastLatency; deltas.add(new Delta(delta, deltaTime, deltaLatency)); if (deltas.size() > 10) { deltas.pop(); } long opSum = 0; long timeSum = 0; long latencySum = 0; for (final Delta d : deltas) { timeSum += d.time; opSum += d.ops; latencySum += d.latency; } final long operations = deltaTime == 0 ? 0 : 1000000000 * delta / deltaTime; final long averagedOperations = timeSum == 0 ? 0 : 1000000000 * opSum / timeSum; final double averageLatency = opSum == 0 ? 0 : latencySum / (1000000.d * opSum); com.sun.management.OperatingSystemMXBean operatingSystemMXBean = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean(); double totalCPU = 100.0 * operatingSystemMXBean.getSystemCpuLoad(); double processCPU = 100.0 * operatingSystemMXBean.getProcessCpuLoad(); System.out.printf( "%,10d (%,10d) %s/s. %,10.9f ms average latency. " + "%,10d %s total. process=%3.0f%%, total=%3.0f%%\n", operations, averagedOperations, unit, averageLatency, count, unit, processCPU, totalCPU); System.out.flush(); lastRows = count; lastTime = time; lastLatency = latency; } public void finish() { run = false; worker.interrupt(); try { worker.join(); } catch (InterruptedException e) { e.printStackTrace(); } progress(); } public void inc(final long ops, final long latency) { this.operations.addAndGet(ops); this.latency.addAndGet(latency); } }