package com.emc.ecs.sync; import com.emc.ecs.sync.util.PerformanceWindow; import com.sun.management.OperatingSystemMXBean; import java.lang.management.ManagementFactory; import java.text.MessageFormat; import java.util.HashSet; import java.util.Set; public class SyncStats implements AutoCloseable { private long objectsComplete, objectsSkipped, objectsFailed; private long bytesComplete, bytesSkipped, pastRunTime, startTime, stopTime, cpuStartTime; private Set<String> failedObjects = new HashSet<>(); private PerformanceWindow objectCompleteRate = new PerformanceWindow(500, 20); private PerformanceWindow objectSkipRate = new PerformanceWindow(500, 20); private PerformanceWindow objectErrorRate = new PerformanceWindow(500, 20); @Override public void close() { objectCompleteRate.close(); objectSkipRate.close(); objectErrorRate.close(); } @Override protected void finalize() throws Throwable { try { close(); } finally { super.finalize(); // make sure we call super.finalize() no matter what! } } public void reset() { objectsComplete = objectsSkipped = objectsFailed = 0; bytesComplete = bytesSkipped = 0; failedObjects = new HashSet<>(); } public synchronized void incObjectsComplete() { objectsComplete++; objectCompleteRate.increment(1); } public synchronized void incObjectsSkipped() { objectsSkipped++; objectSkipRate.increment(1); } public synchronized void incObjectsFailed() { objectsFailed++; objectErrorRate.increment(1); } public synchronized void incBytesComplete(long bytes) { bytesComplete += bytes; } public synchronized void incBytesSkipped(long bytes) { bytesSkipped += bytes; } public long getObjectCompleteRate() { return objectCompleteRate.getWindowRate(); } public long getObjectSkipRate() { return objectSkipRate.getWindowRate(); } public long getObjectErrorRate() { return objectErrorRate.getWindowRate(); } public synchronized void pause() { stopTime = System.currentTimeMillis(); } public synchronized void resume() { pastRunTime += stopTime - startTime; startTime = System.currentTimeMillis(); stopTime = 0; } public void addFailedObject(String name) { failedObjects.add(name); } public long getTotalRunTime() { if (startTime == 0) return 0; long last = stopTime > 0 ? stopTime : System.currentTimeMillis(); return pastRunTime + (last - startTime); } /** * Returns the CPU time consumed by a sync process in milliseconds */ public long getTotalCpuTime() { if (cpuStartTime == 0) return 0; return ((OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean()).getProcessCpuTime() / 1000000 - cpuStartTime; } public String getStatsString() { long secs = (System.currentTimeMillis() - startTime) / 1000L; if (secs == 0) secs = 1; long byteRate = bytesComplete / secs; double objectRate = (double) objectsComplete / secs; return MessageFormat.format("Transferred {0} bytes in {1} seconds ({2} bytes/s) - skipped {3} bytes\n", bytesComplete, secs, byteRate, bytesSkipped) + MessageFormat.format("Successful files: {0} ({2,number,#.##}/s) Skipped files: {3} Failed Files: {1}\n", objectsComplete, objectsFailed, objectRate, objectsSkipped) + MessageFormat.format("Failed files: {0}\n", failedObjects); } public long getObjectsComplete() { return objectsComplete; } public long getObjectsSkipped() { return objectsSkipped; } public long getObjectsFailed() { return objectsFailed; } public long getBytesComplete() { return bytesComplete; } public long getBytesSkipped() { return bytesSkipped; } public long getPastRunTime() { return pastRunTime; } public long getStartTime() { return startTime; } public void setStartTime(long startTime) { this.startTime = startTime; } public long getStopTime() { return stopTime; } public void setStopTime(long stopTime) { this.stopTime = stopTime; } public long getCpuStartTime() { return cpuStartTime; } public void setCpuStartTime(long cpuStartTime) { this.cpuStartTime = cpuStartTime; } public Set<String> getFailedObjects() { return failedObjects; } }