/*******************************************************************************
*
* Copyright (c) 2012 GigaSpaces Technologies Ltd. All rights reserved
*
* 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.
*
******************************************************************************/
package org.openspaces.admin.internal.vm;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.openspaces.admin.support.StatisticsUtils;
import org.openspaces.admin.vm.VirtualMachineDetails;
import org.openspaces.admin.vm.VirtualMachineStatistics;
import com.gigaspaces.internal.jvm.JVMStatistics;
/**
* @author kimchy
*/
public class DefaultVirtualMachineStatistics implements VirtualMachineStatistics {
private static final JVMStatistics NA_STATS = new JVMStatistics();
private final long timeDelta;
private final JVMStatistics stats;
private final VirtualMachineDetails details;
private volatile VirtualMachineStatistics previousStats;
private final double cpuPerc;
private final double gcCollectionPerc;
private final long previousTimeStamp;
public DefaultVirtualMachineStatistics() {
this(NA_STATS, null, null, 0, -1);
}
public DefaultVirtualMachineStatistics(JVMStatistics stats, VirtualMachineStatistics previousStats, VirtualMachineDetails details, int historySize, long timeDelta) {
this.stats = stats;
this.previousStats = previousStats;
this.details = details;
this.timeDelta = timeDelta;
if (previousStats == null) {
this.cpuPerc = -1;
this.gcCollectionPerc = -1;
this.previousTimeStamp = -1;
} else {
this.cpuPerc = stats.computeCpuPerc(((DefaultVirtualMachineStatistics)previousStats).stats);
this.previousTimeStamp = previousStats.getTimestamp();
this.gcCollectionPerc = StatisticsUtils.computePercByTime(getGcCollectionTime(), previousStats.getGcCollectionTime(), getTimestamp(), previousTimeStamp);
}
VirtualMachineStatistics lastStats = previousStats;
if (lastStats != null) {
for (int i = 0; i < historySize; i++) {
if (lastStats.getPrevious() == null) {
break;
}
lastStats = lastStats.getPrevious();
}
((DefaultVirtualMachineStatistics) lastStats).setPreviousStats(null);
}
}
public boolean isNA() {
return stats.isNA();
}
public long getTimestamp() {
return stats.getTimestamp();
}
public long getAdminTimestamp() {
if (stats.getTimestamp() != -1 && timeDelta != Integer.MIN_VALUE) {
return stats.getTimestamp() + timeDelta;
}
return -1;
}
public VirtualMachineDetails getDetails() {
return this.details;
}
public List<VirtualMachineStatistics> getTimeline() {
ArrayList<VirtualMachineStatistics> timeline = new ArrayList<VirtualMachineStatistics>();
timeline.add(this);
VirtualMachineStatistics current = this.getPrevious();
while (current != null && !current.isNA()) {
timeline.add(current);
current = current.getPrevious();
}
return timeline;
}
public VirtualMachineStatistics getPrevious() {
return previousStats;
}
public void setPreviousStats(VirtualMachineStatistics previousStats) {
this.previousStats = previousStats;
}
public long getPreviousTimestamp() {
return previousTimeStamp;
}
public long getUptime() {
return stats.getUptime();
}
public long getMemoryHeapCommittedInBytes() {
return stats.getMemoryHeapCommitted();
}
public double getMemoryHeapCommittedInMB() {
return StatisticsUtils.convertToMB(getMemoryHeapCommittedInBytes());
}
public double getMemoryHeapCommittedInGB() {
return StatisticsUtils.convertToGB(getMemoryHeapCommittedInBytes());
}
public long getMemoryHeapUsedInBytes() {
return stats.getMemoryHeapUsed();
}
public double getMemoryHeapUsedInMB() {
return StatisticsUtils.convertToMB(getMemoryHeapUsedInBytes());
}
public double getMemoryHeapUsedInGB() {
return StatisticsUtils.convertToGB(getMemoryHeapUsedInBytes());
}
public double getMemoryHeapUsedPerc() {
if (isNA()) {
return -1;
} else {
return StatisticsUtils.computePerc(getMemoryHeapUsedInBytes(), getDetails().getMemoryHeapMaxInBytes());
}
}
public double getMemoryHeapCommittedUsedPerc() {
return StatisticsUtils.computePerc(getMemoryHeapUsedInBytes(), getMemoryHeapCommittedInBytes());
}
public long getMemoryNonHeapCommittedInBytes() {
return stats.getMemoryNonHeapCommitted();
}
public double getMemoryNonHeapCommittedInMB() {
return StatisticsUtils.convertToMB(getMemoryNonHeapCommittedInBytes());
}
public double getMemoryNonHeapCommittedInGB() {
return StatisticsUtils.convertToGB(getMemoryNonHeapCommittedInBytes());
}
public long getMemoryNonHeapUsedInBytes() {
return stats.getMemoryNonHeapUsed();
}
public double getMemoryNonHeapUsedInMB() {
return StatisticsUtils.convertToMB(getMemoryNonHeapUsedInBytes());
}
public double getMemoryNonHeapUsedInGB() {
return StatisticsUtils.convertToGB(getMemoryNonHeapUsedInBytes());
}
public double getMemoryNonHeapUsedPerc() {
if (isNA()) {
return -1;
} else {
return StatisticsUtils.computePerc(getMemoryNonHeapUsedInBytes(), getDetails().getMemoryNonHeapMaxInBytes());
}
}
public double getMemoryNonHeapCommittedUsedPerc() {
return StatisticsUtils.computePerc(getMemoryNonHeapUsedInBytes(), getMemoryNonHeapCommittedInBytes());
}
public int getThreadCount() {
return stats.getThreadCount();
}
public int getPeakThreadCount() {
return stats.getPeakThreadCount();
}
public long getGcCollectionCount() {
return stats.getGcCollectionCount();
}
public long getGcCollectionTime() {
return stats.getGcCollectionTime();
}
@Override
public double getGcCollectionPerc() {
return gcCollectionPerc;
}
@Override
public double getCpuPerc() {
return cpuPerc;
}
public double getCpuPercAverage(long requestedTotalTime, TimeUnit timeUnit) {
if (requestedTotalTime <= 0) {
throw new IllegalArgumentException("Total time has to be positive");
}
long requestedTotalTimeMillis = TimeUnit.MILLISECONDS.convert(requestedTotalTime, timeUnit);
long endTimeStamp = stats.getTimestamp();
DefaultVirtualMachineStatistics start = (DefaultVirtualMachineStatistics)getPrevious();
if (start == null) {
return -1;
}
DefaultVirtualMachineStatistics previousStart = null;
long duration = endTimeStamp - start.getTimestamp();
long previousDuration = 0;
while (duration < requestedTotalTimeMillis) {
previousStart = start;
previousDuration = duration;
start = (DefaultVirtualMachineStatistics)previousStart.getPrevious();
if (start == null) {
return -1;
}
duration = endTimeStamp - start.getTimestamp();
}
if (duration == previousDuration) {
throw new IllegalStateException("This can never happen");
}
double result;
if (previousDuration == 0) {
result = stats.computeCpuPerc(start.stats);
} else {
// weighted average of duration and previousDuration to get a precise average based on the requestedTotalTime
long timeSlot = duration - previousDuration;
double rightWeight = (double)(requestedTotalTimeMillis - previousDuration) / timeSlot;
double leftWeight = (double)(duration - requestedTotalTimeMillis) / timeSlot;
result = rightWeight * stats.computeCpuPerc(start.stats) +
leftWeight * stats.computeCpuPerc(previousStart.stats);
}
return result;
}
public String getCpuPercFormatted() {
return StatisticsUtils.formatPerc(getCpuPerc());
}
}