/* * Copyright 2016 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.batch.dump; import java.io.File; import java.io.FileWriter; import java.util.ArrayList; import java.util.List; import scouter.agent.batch.trace.TraceContext; import scouter.agent.proxy.IToolsMain; import scouter.agent.proxy.LoaderManager; import scouter.util.SystemUtil; import scouter.util.ThreadUtil; public class ThreadDumpHandler { private static final String TOOLS_MAIN = "scouter.xtra.tools.ToolsMain"; public static void processDump(File stackFile, FileWriter stackWriter, FileWriter indexWriter, String [] filters, boolean headerExists) throws Throwable{ if(stackWriter == null){ return; } List<String> dumpList = threadDump(); if(dumpList == null || dumpList.size() == 0){ return; } String stack = filter(dumpList, filters, headerExists); if(stack == null || stack.length() == 0){ return; } TraceContext.getInstance().lastStack = stack; indexWriter.write(new StringBuilder(50).append(System.currentTimeMillis()).append(' ').append(stackFile.length()).append(System.getProperty("line.separator")).toString()); indexWriter.flush(); stackWriter.write(stack); stackWriter.flush(); } private static String filter(List<String> dumpList, String [] filters, boolean headerExists){ int i; int size = dumpList.size(); int startIndex = 0; String value; String lineSeparator = System.getProperty("line.separator"); StringBuilder stackBuffer = new StringBuilder(4096); if(headerExists){ for(i = startIndex; i < size; i++ ){ value = dumpList.get(i); stackBuffer.append(value).append(lineSeparator); if(value.length() == 0){ startIndex = i + 1; break; } } int ii; boolean bSave = false; boolean bScouter = false; List<String> stack = new ArrayList<String>(); for(i = startIndex; i < size; i++ ){ value = dumpList.get(i); if(value.length() == 0){ if(bSave && stack.size() > 1){ for(ii = 0; ii < stack.size(); ii++){ stackBuffer.append(stack.get(ii)).append(lineSeparator); } stackBuffer.append(lineSeparator); } stack.clear(); bSave = false; bScouter = false; continue; } if( stack.size() == 0 && !bScouter){ if(value.indexOf("Scouter-") >=0){ bScouter = true; continue; } } if(bScouter){ continue; } stack.add(value); if(!bSave){ if(filters == null){ bSave = true; continue; } for(ii = 0; ii < filters.length; ii++){ if(value.indexOf(filters[ii]) >= 0){ bSave = true; } } } } if(bSave && stack.size() > 1){ for(ii = 0; ii < stack.size(); ii++){ stackBuffer.append(stack.get(ii)).append(lineSeparator); } stackBuffer.append(lineSeparator); } } return stackBuffer.toString(); } private static List<String> threadDump() throws Throwable { List<String> out = null; //Java 1.5 or IBM JDK if (SystemUtil.IS_JAVA_1_5||SystemUtil.JAVA_VENDOR.startsWith("IBM")) { out = ThreadUtil.getThreadDumpList(); return out; } ClassLoader loader = LoaderManager.getToolsLoader(); if (loader == null) { out = ThreadUtil.getThreadDumpList(); return out; } try { Class<?> c = Class.forName(TOOLS_MAIN, true, loader); IToolsMain toolsMain = (IToolsMain) c.newInstance(); out = (List<String>) toolsMain.threadDump(0, 100000); } catch (Exception e) { e.printStackTrace(); } return out; } }