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

scouter.agent.util.DumpUtil Maven / Gradle / Ivy

/*
 *  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.util;

import scouter.agent.Configure;
import scouter.agent.proxy.ToolsMainFactory;
import scouter.agent.trace.TraceContext;
import scouter.agent.trace.TraceContextManager;
import scouter.lang.pack.MapPack;
import scouter.lang.pack.Pack;
import scouter.lang.value.ListValue;
import scouter.util.*;

import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.Enumeration;

public class DumpUtil extends Thread {

	private static DumpUtil instance = null;

	public final static synchronized DumpUtil getInstance() {
		if (instance == null) {
			instance = new DumpUtil();
			instance.setDaemon(true);
			instance.setName(ThreadUtil.getName(instance));
			instance.start();
		}
		return instance;
	}

	protected DumpUtil() {
	}

	public static File getDumpFile(String prefix) {
		String name = prefix + "." + DateUtil.ymdhms(System.currentTimeMillis()) + ".dump";
		return new File(Configure.getInstance().dump_dir, name);
	}

	public static Pack triggerHeapHisto() {
		PrintWriter out = null;
		MapPack pack = new MapPack();
		try {
			File file = DumpUtil.getDumpFile("scouter.heaphisto");
			out = new PrintWriter(new FileWriter(file));
			ToolsMainFactory.heaphisto(out);
			pack.put("name", file.getName());
		} catch (Throwable e) {
			e.printStackTrace();
		} finally {
			FileUtil.close(out);
		}
		return pack;
	}

	public static Pack triggerThreadDump() {
		PrintWriter out = null;
		MapPack pack = new MapPack();
		try {
			File file = DumpUtil.getDumpFile("scouter.threaddump");
			out = new PrintWriter(new FileWriter(file));
			ToolsMainFactory.threadDump(out);
			pack.put("name", file.getName());
		} catch (Throwable e) {
			e.printStackTrace();
		} finally {
			FileUtil.close(out);
		}
		return pack;
	}

	public static Pack triggerThreadList() {
		PrintWriter out = null;
		MapPack pack = new MapPack();
		try {
			File file = DumpUtil.getDumpFile("scouter.threads");
			out = new PrintWriter(new FileWriter(file));
			MapPack mpack = ThreadUtil.getThreadList();
			ListValue ids = mpack.getList("id");
			ListValue name = mpack.getList("name");
			ListValue stat = mpack.getList("stat");
			ListValue cpu = mpack.getList("cpu");

			for (int i = 0; i < ids.size(); i++) {
				long tid = CastUtil.clong(ids.get(i));
				out.print(i + ":");
				out.print(tid + ":");
				out.print(name.get(i) + ":");
				out.print(stat.get(i) + ":");
				out.print("cpu " + cpu.get(i));

				TraceContext ctx = TraceContextManager.getContext(tid);
				if (ctx != null) {
					out.print(":service " + Hexa32.toString32(ctx.txid) + ":");
					out.print(ctx.serviceName + ":");
					long etime = System.currentTimeMillis() - ctx.startTime;
					out.print(etime + " ms");
				}
				out.println("");
				printStack(out, tid);
				out.println("");
				pack.put("name", file.getName());
			}

		} catch (Throwable e) {
			e.printStackTrace();
		} finally {
			FileUtil.close(out);
		}
		return pack;
	}

	static Configure conf = Configure.getInstance();

	public static Pack triggerActiveService() {
		PrintWriter out = null;
		MapPack pack = new MapPack();
		try {
			File file = DumpUtil.getDumpFile("scouter.activeservice");
			out = new PrintWriter(new FileWriter(file));
			Enumeration en = TraceContextManager.getContextEnumeration();
			for (int n = 0; en.hasMoreElements(); n++) {
				TraceContext ctx = en.nextElement();
				out.print(n + ":");
				out.print(ctx.thread.getId() + ":");
				out.print(ctx.thread.getName() + ":");
				out.print(ctx.thread.getState().name() + ":");
				out.print("cpu " + SysJMX.getThreadCpuTime(ctx.thread) + ":");
				out.print(Hexa32.toString32(ctx.txid) + ":");
				out.print(ctx.serviceName + ":");
				long etime = System.currentTimeMillis() - ctx.startTime;
				out.print(etime + " ms");
				if (ctx.sqltext != null) {
					out.print(":sql=" + ctx.sqltext + ":");
				}
				if (ctx.apicall_name != null) {
					out.println(":subcall=" + ctx.apicall_name);
				}
				out.println("");
				printStack(out, ctx.thread.getId());
				out.println("");
				pack.put("name", file.getName());
			}
		} catch (Throwable e) {
			e.printStackTrace();
		} finally {
			FileUtil.close(out);
		}
		return pack;
	}

	public static void printStack(PrintWriter out, long tid) {
		ThreadMXBean tmb = ManagementFactory.getThreadMXBean();
		ThreadInfo f = tmb.getThreadInfo(tid, 500);
		StackTraceElement[] se = f.getStackTrace();
		if (se != null) {
			for (int i = 0; i < se.length; i++) {
				if (se[i] != null) {
					out.println("\t" + se[i]);
				}
			}
		}
	}

	private void trigger() {
		synchronized (this) {
			this.notifyAll();
		}
	}

	public void run() {
		while (true) {

			synchronized (this) {
				ThreadUtil.wait(this);
			}

			switch (conf.autodump_level) {
			case 1:
				DumpUtil.triggerThreadDump();
				break;
			case 2:
				DumpUtil.triggerActiveService();
				break;
			case 3:
				DumpUtil.triggerThreadList();
				break;
			default:
				DumpUtil.triggerThreadDump();
				break;
			}

		}
	}

	private static long last_auto_dump = 0;
    private static boolean stopAutoDumpTemporarily = false;

	public static void autoDump() {
		if (conf.autodump_enabled == false || stopAutoDumpTemporarily == true)
			return;

		long now = System.currentTimeMillis();
		if (now < last_auto_dump + conf.autodump_interval_ms)
			return;
		last_auto_dump = now;

		DumpUtil.getInstance().trigger();
	}

	public static void autoDumpByCpuExceedance() {
		if (conf.autodump_enabled && conf.autodump_interval_ms <= conf.autodump_cpu_exceeded_dump_interval_ms) {
			return;
		}

		if(conf.autodump_cpu_exceeded_enabled == false) {
			return;
		}

        stopAutoDumpTemporarily = true;

        try{
            for(int i=0; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy