package de.bodden.tamiflex.reporting.rt; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; public class Reporter { private final static boolean PRINT_STACK_TRACES = false; private final static int NUM_STACK_FRAMES = 7; static class Data { Set<String> threadIDs = new HashSet<String>(); int numSuccessfulCalls, numFailedCalls; Map<String,Set<String>> kindToArguments = new HashMap<String, Set<String>>(); Set<List<String>> stackTraces = new HashSet<List<String>>(); @Override public String toString() { StringBuilder sb = new StringBuilder(); if(PRINT_STACK_TRACES) for(List<String> trace: stackTraces) { for(String frame: trace) { sb.append(frame+"\n"); } sb.append("\n"); } sb.append("Thread IDs: "+threadIDs+"\n"); sb.append("Success rate: "+(numSuccessfulCalls+0.0)/(numSuccessfulCalls+numFailedCalls)*100+"% ("+numSuccessfulCalls+" succeeded, "+numFailedCalls+ " failed)\n"); for(Map.Entry<String,Set<String>> entry: kindToArguments.entrySet()) { sb.append(entry.getKey()); sb.append("\n"); for(String arguments: entry.getValue()) { sb.append(" "); sb.append(arguments); sb.append("\n"); } } return sb.toString(); } } public static void generateReport(List<Entry> allEntries, PrintWriter out) { Map<String,Data> callSiteToData = new HashMap<String, Data>(); for (Entry entry : allEntries) { String payload = entry.payload; String[] items = payload.split(";"); String method = items[0]; String line = items[1]; String callSite = method+":"+line; Data data = callSiteToData.get(callSite); if(data==null) { data = new Data(); callSiteToData.put(callSite, data); } data.threadIDs.add(entry.thread.getName()+"-"+entry.thread.getId()); boolean successful = entry.status == Entry.Status.SUCCEEDED; if(successful) data.numSuccessfulCalls++; else data.numFailedCalls++; String kind = items[2]; Set<String> arguments = data.kindToArguments.get(kind); if(arguments==null) { arguments = new HashSet<String>(); data.kindToArguments.put(kind,arguments); } String args = payload.substring(payload.lastIndexOf(kind)+kind.length()); arguments.add(args); StackTraceElement[] stackTrace = entry.getStackTrace(); List<String> partialTrace = new LinkedList<String>(); for(int i=1;i<NUM_STACK_FRAMES;i++) { if(i<stackTrace.length) { StackTraceElement frame = stackTrace[i]; partialTrace.add(" " + frame.getClassName()+"."+frame.getMethodName()+":"+frame.getLineNumber()); } } data.stackTraces.add(partialTrace); } List<String> callSites = new ArrayList<String>(callSiteToData.keySet()); Collections.sort(callSites); out.println("Report for "+callSites.size()+" call sites."); out.println(); out.println(); for (String callSite : callSites) { out.println(callSite); out.println(); out.println(callSiteToData.get(callSite)); out.println(); out.println("Remarks:"); out.println(); out.println("================================================================================"); } } }