All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scouter.agent.netio.request.handle.AgentHeapDump Maven / Gradle / Ivy

There is a newer version: 2.20.0
Show newest version
/*
 *  Copyright 2015 the original author or authors. 
 *  @https://github.com/scouter-project/scouter
 *
 *  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 scouter.agent.netio.request.handle;

import java.io.File;
import java.io.FileFilter;
import java.io.RandomAccessFile;
import java.lang.management.ManagementFactory;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;

import javax.management.MBeanServer;

import scouter.agent.netio.request.anotation.RequestHandler;
import scouter.io.DataInputX;
import scouter.io.DataOutputX;
import scouter.lang.pack.MapPack;
import scouter.lang.pack.Pack;
import scouter.lang.value.BooleanValue;
import scouter.lang.value.ListValue;
import scouter.net.RequestCmd;
import scouter.net.TcpFlag;
import scouter.util.DateUtil;
import scouter.util.FormatUtil;
import scouter.util.SystemUtil;


public class AgentHeapDump {

	private String folderName = "heapdump";
	private String fileExt = ".hprof";
	private long lastCallTime = 0;

	@RequestHandler(RequestCmd.OBJECT_CALL_HEAP_DUMP)
	public Pack callHeapDump(Pack param) {

		long curTime = System.currentTimeMillis();
		if (curTime - lastCallTime < 10000) {
			MapPack p = new MapPack();
			p.put("success", new BooleanValue(false));
			p.put("msg", "please wait 10 sec. from last request...");
			return p;
		}
		lastCallTime = curTime;
		long time = ((MapPack) param).getLong("time");
		String yyyymmdd = DateUtil.yyyymmdd(time);
		String hhmmss = FormatUtil.print(new Date(time), "HHmmss");
		String fName = yyyymmdd + "-" + hhmmss + ((MapPack) param).getText("fName").replaceAll("/", "_") + fileExt;

		File hprofDir = new File(folderName);
		if (hprofDir.exists() == false) {
			hprofDir.mkdirs();
		}

		File hprofFile = new File(hprofDir, fName);
		if (hprofFile.exists()) {
			hprofFile.delete();
		}

		// version check.
		if (SystemUtil.IS_JAVA_1_5) {
			MapPack p = new MapPack();
			p.put("success", new BooleanValue(false));
			p.put("msg", "dumpHeap only works on a Sun Java 1.6+ VM");
			return p;
		}

		String error = dumpHeap(folderName + "/" + fName);
		if (error == null) {
			MapPack p = new MapPack();
			p.put("success", new BooleanValue(true));
			p.put("msg", "Successfully request heap dump...");
			return p;
		} else {
			MapPack p = new MapPack();
			p.put("success", new BooleanValue(false));
			p.put("msg", error);
			return p;
		}

		// HotSpotDiagnosticMXBean hdm =
		// sun.management.ManagementFactory.getDiagnosticMXBean();
		// try {
		// hdm.dumpHeap(folderName+"/"+fName, true);
		//
		// MapPack p = new MapPack();
		// p.put("success", new BooleanValue(true));
		// p.put("msg", "Successfully request heap dump...");
		//
		// return p;
		//
		// } catch (IOException e) {
		// MapPack p = new MapPack();
		// p.put("success", new BooleanValue(false));
		// p.put("msg", e.getMessage());
		//
		// return p;
		// }

	}

	public String dumpHeap(String fileName) {
		Class clazz;
		try {
			clazz = Class.forName("com.sun.management.HotSpotDiagnosticMXBean");
		} catch (ClassNotFoundException e) {
			return "ERROR: dumpHeap only works on a Sun Java 1.6+ VM containing "
					+ "the class com.sun.management.HotSpotDiagnosticMXBean";
		}

		Object hotspotMBean = null;
		try {
			MBeanServer server = ManagementFactory.getPlatformMBeanServer();
			hotspotMBean = ManagementFactory.newPlatformMXBeanProxy(server,
					"com.sun.management:type=HotSpotDiagnostic", clazz);
		} catch (Throwable e) {
			return "ERROR: dumpHeap was unable to obtain the HotSpotDiagnosticMXBean: " + e.getMessage();
		}

		try {
			Method method = hotspotMBean.getClass().getMethod("dumpHeap", String.class, Boolean.TYPE);
			method.invoke(hotspotMBean, fileName, true);
		} catch (InvocationTargetException e) {
			Throwable t = e.getCause() != null ? e.getCause() : e;
			return "ERROR: dumpHeap threw a InvocationTargetException: " + t;
		} catch (Throwable e) {
			return "ERROR: dumpHeap threw a Throwable: " + e;
		}
		return null;
	}

	@RequestHandler(RequestCmd.OBJECT_DELETE_HEAP_DUMP)
	public Pack deleteHeapDump(Pack param) {
		File delFile = new File(folderName + "/" + ((MapPack) param).getText("delfileName"));
		if (delFile.exists() == false) {
			MapPack p = new MapPack();
			p.put("success", new BooleanValue(false));
			p.put("msg", "file \'" + delFile.getName() + "\' is not exist...");
			return p;
		} else {
			delFile.delete();
			MapPack p = new MapPack();
			p.put("success", new BooleanValue(true));
			p.put("msg", "Successfully deleted...");
			return p;
		}
	}

	@RequestHandler(RequestCmd.OBJECT_LIST_HEAP_DUMP)
	public Pack listHeapDump(Pack param) {

		MapPack p = new MapPack();
		ListValue nameLv = p.newList("name");
		ListValue sizeLv = p.newList("size");

		File hprofDir = new File(folderName);
		if (hprofDir.exists() == false) {
			return null;
		}

		File[] fileList = hprofDir.listFiles(new ContentFilter());
		if (fileList != null && fileList.length > 0) {
			for (int i = 0; i < fileList.length; i++) {
				File f = fileList[i];
				if (/* f.isFile() && */f.getName().endsWith(fileExt)) {
					nameLv.add(f.getName());
					sizeLv.add(f.length());
				}
			}
			return p;
		}
		return p;
	}

	public class ContentFilter implements FileFilter {
		public boolean accept(File file) {
			return file.isFile() || !file.getName().startsWith(".");
		}
	}

	@RequestHandler(RequestCmd.OBJECT_DOWNLOAD_HEAP_DUMP)
	public Pack downloadHeapDump(Pack param, DataInputX in, DataOutputX out) {
		int buff = 2 * 1024 * 1024;
		File downloadFile = new File(folderName + "/" + ((MapPack) param).getText("fileName"));
		try {
			RandomAccessFile raf = new RandomAccessFile(downloadFile, "r");

			byte[] buffer = new byte[buff];
			int read = 0;

			long offset = downloadFile.length();
			int unitsize;
			while (read < offset) {
				unitsize = (int) (((offset - read) >= buff) ? buff : (offset - read));
				raf.read(buffer, 0, unitsize);
				out.writeByte(TcpFlag.HasNEXT);
				out.writeBlob(buffer, 0, unitsize);
				read += unitsize;
			}
			raf.close();
			return null;

		} catch (Throwable e) {
			e.printStackTrace();
		}
		return null;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy