001/* 002 * Copyright 2012 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.runtime.plugins.admin.jvmstatus; 017 018import java.io.IOException; 019import java.lang.management.ManagementFactory; 020import java.lang.management.ThreadInfo; 021import java.util.HashMap; 022import java.util.Map; 023 024import org.apache.avalon.framework.parameters.Parameters; 025import org.apache.cocoon.ProcessingException; 026import org.apache.cocoon.environment.ObjectModelHelper; 027import org.apache.cocoon.environment.Response; 028import org.apache.cocoon.environment.SourceResolver; 029import org.apache.cocoon.reading.AbstractReader; 030import org.xml.sax.SAXException; 031 032/** 033 * Send a report on thread 034 */ 035public class ThreadLogReader extends AbstractReader 036{ 037 /** The servlet response */ 038 protected Response _response; 039 040 @Override 041 public String getMimeType() 042 { 043 return "text/plain"; 044 } 045 046 @Override 047 public void setup(SourceResolver pResolver, Map pObjectModel, String pSrc, Parameters pPar) throws ProcessingException, SAXException, IOException 048 { 049 super.setup(pResolver, pObjectModel, pSrc, pPar); 050 _response = ObjectModelHelper.getResponse(pObjectModel); 051 } 052 053 public void generate() throws IOException, SAXException, ProcessingException 054 { 055 if (getLogger().isInfoEnabled()) 056 { 057 getLogger().info("Administrator is download deadlocked threads'report"); 058 } 059 060 _response.setHeader("Content-Disposition", "attachment"); 061 062 long[] deadlockedThreadsIds = ManagementFactory.getThreadMXBean().findMonitorDeadlockedThreads(); 063 if (deadlockedThreadsIds == null) 064 { 065 if (getLogger().isInfoEnabled()) 066 { 067 getLogger().info("Report is empty"); 068 } 069 out.write("No thread in deadlock.\n".getBytes("UTF-8")); 070 } 071 else 072 { 073 if (getLogger().isInfoEnabled()) 074 { 075 getLogger().info("Report contains " + deadlockedThreadsIds.length + " deadlocked threads"); 076 } 077 out.write((deadlockedThreadsIds.length + " threads in deadlock.\n").getBytes("UTF-8")); 078 079 Map<Thread, StackTraceElement[]> threads = Thread.getAllStackTraces(); 080 Map<Long, StackTraceElement[]> stackTraces = new HashMap<>(); 081 for (Thread thread : threads.keySet()) 082 { 083 long id = thread.getId(); 084 stackTraces.put(id, threads.get(thread)); 085 } 086 087 ThreadInfo[] deadlockedThread = ManagementFactory.getThreadMXBean().getThreadInfo(deadlockedThreadsIds); 088 for (ThreadInfo info : deadlockedThread) 089 { 090 out.write("\n".getBytes("UTF-8")); 091 out.write(("THREAD '" + info.getThreadId() + "' - '" + info.getThreadName() + "'\n").getBytes("UTF-8")); 092 out.write(("locked on monitor " + info.getLockName() + " by thread '" + info.getLockOwnerId() + "' - '" + info.getLockOwnerName() + "'\n").getBytes("UTF-8")); 093 094 095 StackTraceElement[] stes = stackTraces.get(info.getThreadId()); // car info.getStackTrace(); renvoie vide 096 for (StackTraceElement ste : stes) 097 { 098 String line = "at " + ste.getClassName() + "." + ste.getMethodName() + " (" + ste.getFileName() + ":" + ste.getLineNumber() + ")\n"; 099 out.write(line.getBytes("UTF-8")); 100 } 101 } 102 } 103 } 104}