package com.xqbase.metric.client;

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.lang.management.ThreadMXBean;

import com.sun.management.OperatingSystemMXBean;
import com.xqbase.metric.common.Metric;

public class ManagementMonitor implements Runnable {
	private static double MB(long value) {
		return (double) value / 1048576;
	}

	private static double PERCENT(long dividend, long divisor) {
		return divisor == 0 ? 0 : (double) dividend * 100 / divisor;
	}

	private String cpu, threads, memoryMB, memoryPercent;

	public ManagementMonitor(String prefix) {
		cpu = prefix + ".cpu";
		threads = prefix + ".threads";
		memoryMB = prefix + ".memory.mb";
		memoryPercent = prefix + ".memory.percent";
	}

	@Override
	public void run() {
		ThreadMXBean thread = ManagementFactory.getThreadMXBean();
		Metric.put(threads, thread.getThreadCount(), "type", "total");
		Metric.put(threads, thread.getDaemonThreadCount(), "type", "daemon");

		// Runtime rt = Runtime.getRuntime();
		// Metric.add(memory, inMB(rt.totalMemory() - rt.freeMemory()), "type", "heap_used");
		MemoryMXBean memory_ = ManagementFactory.getMemoryMXBean();
		MemoryUsage heap = memory_.getHeapMemoryUsage();
		Metric.put(memoryMB, MB(heap.getCommitted()), "type", "heap_committed");
		Metric.put(memoryMB, MB(heap.getUsed()), "type", "heap_used");
		Metric.put(memoryPercent, PERCENT(heap.getUsed(), heap.getMax()), "type", "heap");
		MemoryUsage nonHeap = memory_.getNonHeapMemoryUsage();
		Metric.put(memoryMB, MB(nonHeap.getCommitted()), "type", "non_heap_committed");
		Metric.put(memoryMB, MB(nonHeap.getUsed()), "type", "non_heap_used");
		// nonHeap.getMax() always returns -1 in Java 1.8
		// Metric.put(memoryPercent, PERCENT(nonHeap.getUsed(), nonHeap.getMax()), "type", "non_heap");

		java.lang.management.OperatingSystemMXBean os_ =
				ManagementFactory.getOperatingSystemMXBean();
		if (!(os_ instanceof OperatingSystemMXBean)) {
			return;
		}
		OperatingSystemMXBean os = (OperatingSystemMXBean) os_;
		long totalPhysical = os.getTotalPhysicalMemorySize();
		long usedPhysical = totalPhysical - os.getFreePhysicalMemorySize();
		Metric.put(memoryMB, MB(usedPhysical), "type", "physical");
		Metric.put(memoryPercent, PERCENT(usedPhysical, totalPhysical),
				"type", "physical_memory");
		long totalSwap = os.getTotalSwapSpaceSize();
		long usedSwap = totalSwap - os.getFreeSwapSpaceSize();
		Metric.put(memoryMB, MB(usedSwap), "type", "swap");
		Metric.put(memoryMB, MB(os.getCommittedVirtualMemorySize()),
				"type", "process_committed");
		Metric.put(memoryPercent, PERCENT(usedSwap, totalSwap),
				"type", "swap_space");

		double system = os.getSystemCpuLoad();
		if (system >= 0) {
			Metric.put(cpu, system * 100, "type", "system");
		}
		double process = os.getProcessCpuLoad();
		if (process >= 0) {
			Metric.put(cpu, process * 100, "type", "process");
		}
	}
}
@@ -606,16 +606,194 @@
 Percent;
+%0A%09private ThreadMXBean thread = ManagementFactory.getThreadMXBean();%0A%09private MemoryMXBean memory = ManagementFactory.getMemoryMXBean();%0A%09private OperatingSystemMXBean os = null;
 %0A%0A%09publi
@@ -974,103 +974,230 @@
 %22;%0A%09
-%7D%0A%0A%09@Override%0A%09public void run() %7B%0A%09%09ThreadMXBean thread = ManagementFactory.getThreadMXBean();
+%09java.lang.management.OperatingSystemMXBean os_ =%0A%09%09%09%09ManagementFactory.getOperatingSystemMXBean();%0A%09%09if (os_ instanceof OperatingSystemMXBean) %7B%0A%09%09%09os = (OperatingSystemMXBean) os_;%0A%09%09%7D%0A%09%7D%0A%0A%09@Override%0A%09public void run() %7B
 %0A%09%09M
@@ -1463,70 +1463,8 @@
 %22);%0A
-%09%09MemoryMXBean memory_ = ManagementFactory.getMemoryMXBean();%0A
 %09%09Me
@@ -1482,25 +1482,24 @@
 eap = memory
-_
 .getHeapMemo
@@ -1764,17 +1764,16 @@
 = memory
-_
 .getNonH
@@ -2099,230 +2099,42 @@
 );%0A%0A
-%09%09java.lang.management.OperatingSystemMXBean os_ =%0A%09%09%09%09ManagementFactory.getOperatingSystemMXBean();%0A
 %09%09if 
-(!
 (os
-_ instanceof OperatingSystemMXBean)) %7B%0A%09%09%09return;%0A%09%09%7D%0A%09%09OperatingSystemMXBean os = (OperatingSystemMXBean) os_;
+ == null) %7B%0A%09%09%09return;%0A%09%09%7D
 %0A%09%09l
@@ -2763,221 +2763,144 @@
 %0A%0A%09%09
-double system = os.getSystemCpuLoad();%0A%09%09if (system %3E= 0) %7B%0A%09%09%09Metric.put(cpu, system * 100, %22type%22, %22system%22);%0A%09%09%7D%0A%09%09double process = os.getProcessCpuLoad();%0A%09%09if (process %3E= 0) %7B%0A%09%09%09Metric.put(cpu, process * 100
+Metric.put(cpu, Math.max(os.getSystemCpuLoad() * 100, 0), %22type%22, %22system%22);%0A%09%09Metric.put(cpu, Math.max(os.getProcessCpuLoad() * 100, 0)
 , %22t
@@ -2917,16 +2917,12 @@
 cess%22);%0A
-%09%09%7D%0A
 %09%7D%0A%7D

optimize mxbean usage