ProfilerIf pluggable delegate api.
Quartz <[email protected]> Fri, 1 Aug 2003 15:44:43 -0700 (PDT)
| Newsgroups | gmane.comp.java.seda.user |
|---|---|
| Message-ID | <[email protected]> |
Hi,
Thought you might like a live profiler UI.
Siply update your sandStormProfiler (or merge changes).
I simply forward some call to the plugged implementation.
the config section look like this:
<profile>
enable true
#if class not present will default to printwriter
class tests.basic.ProfilerDelegateUI
<delegatevar>
#number of point to keep per graph
buffersize 400
#number of columns in the ui
columns 3
#item name profiling filters: list of regex seperated by spaces
#acceptregex (.*)(StageName)(.*)
rejectregex ^(TPController)(.+)
#color regexes: list of "regex hexcolor" pairs separated by spaces
bgcolors ^(ThreadPool)(.+) 000040 (.+)(queueLength)(.*) 400000
#fgcolors ^(ThreadPool)(.+) 0000ff (.+)(queueLength)(.*) ff0000
#tcolors ^(ThreadPool)(.+) 0000ff (.+)(queueLength)(.*) ff0000
</delegatevar>
</profile>
__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com
seda_profilerUI_snapshot.jpg
(image/jpeg, 101.9 KB) - not displayed
ProfilerDelegateUI.java
(text/plain, 8.1 KB)
/*
* Created on Jul 31, 2003
*
* To change this generated comment go to
* Window>Preferences>Java>Code Generation>Code Template
*/
package tests.basic;
import java.awt.*;
import java.awt.event.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Pattern;
import seda.sandStorm.api.ManagerIF;
import seda.sandStorm.internal.sandStormProfiler;
import seda.sandStorm.main.SandstormConfig;
/**
* @author ddeschenes
*/
public class ProfilerDelegateUI implements sandStormProfiler.IProfilerDelegate {
LinkedHashMap items = new LinkedHashMap(); //string to list of Long
HashSet includeNamePatterns = new HashSet();
HashSet excludeNamePatterns = new HashSet();
HashMap bgColors = new HashMap();
HashMap fgColors = new HashMap();
HashMap tColors = new HashMap();
private int defaultsize = 600;
ProfilerUI ui;
public void init(ManagerIF mgr, final int sampledelay) {
defaultsize = mgr.getConfig().getInt("global.profile.delegatevar.buffersize", 600);
int col = mgr.getConfig().getInt("global.profile.delegatevar.columns", 3);
readFilters(mgr.getConfig());
readColors(mgr.getConfig().getStringList("global.profile.delegatevar.bgcolors"), bgColors);
readColors(mgr.getConfig().getStringList("global.profile.delegatevar.fgcolors"), fgColors);
readColors(mgr.getConfig().getStringList("global.profile.delegatevar.tcolors"), tColors);
ui = new ProfilerUI(this, col);
ui.setSize(600, 400);
ui.setLocation(300,300);
ui.setVisible(true);
Thread t = new Thread("ProfilerUI-Repainter("+sampledelay+")") {
public void run() {
while(true) {
ui.repaint();
try {sleep(sampledelay);}
catch(InterruptedException e) { break;}
}
System.out.println(getName()+": exiting");
}
};
t.start();
}
private void readFilters(SandstormConfig cfg) {
String[] ar = cfg.getStringList("global.profile.delegatevar.acceptregex");
for(int i=0; ar!=null && i<ar.length; i++){
Pattern p = null;
try {p = Pattern.compile(ar[i]);} catch(Exception e) {e.printStackTrace();}
if(p!=null)
includeNamePatterns.add(p);
}
String[] rr = cfg.getStringList("global.profile.delegatevar.rejectregex");
for(int i=0; rr!=null && i<rr.length; i++){
Pattern p = null;
try {p = Pattern.compile(rr[i]);} catch(Exception e) {e.printStackTrace();}
if(p!=null)
excludeNamePatterns.add(p);
}
}
private void readColors(String[] regex_color_pairs, Map map) {
for(int i=0; regex_color_pairs!=null && (i+1)<regex_color_pairs.length; i+=2){
Pattern p = null;
try {p = Pattern.compile(regex_color_pairs[i]);} catch(Exception e) {e.printStackTrace();}
if(p!=null)
map.put(p, new Color(Integer.parseInt(regex_color_pairs[i+1], 16)));
}
}
private Color findColor(String name, Map map, Color def) {
for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
Map.Entry e = (Map.Entry)it.next();
Pattern p = (Pattern)e.getKey();
if(p.matcher(name).matches()) {
return (Color)e.getValue();
}
}
return def;
}
private boolean accept(String name) {
//System.out.println("########## ProfilerDelegateUI.add(\""+name+"\")");
if(includeNamePatterns.size()>0) {
for (Iterator it = includeNamePatterns.iterator(); it.hasNext();) {
Pattern p = (Pattern)it.next();
if(p.matcher(name).matches())
return true;
}
}
if(excludeNamePatterns.size()>0) {
for (Iterator it = excludeNamePatterns.iterator(); it.hasNext();) {
Pattern p = (Pattern)it.next();
if(p.matcher(name).matches())
return false;
}
}
return true;
}
public void add(String name) {
if(!accept(name))
return;
Curve c = new Curve(defaultsize);
c.bgcolor = findColor(name, bgColors, Color.BLACK);
c.fgcolor = findColor(name, fgColors, Color.GREEN);
c.tcolor = findColor(name, tColors, Color.LIGHT_GRAY);
items.put(name, c);
}
public void remove(String name) {
items.remove(name);
}
public void update(String name, long value) {
Curve c = (Curve)items.get(name);
if (c != null)
c.add(value);
}
public void destroy() {
if (ui != null)
ui.dispose();
items.clear();
}
//---------------
static class Curve {
long[] values;
int count = 0;
int nextpos = 0;
Color bgcolor = Color.BLACK;
Color fgcolor = Color.GREEN;
Color tcolor = Color.WHITE;
Curve(int size) {
values = new long[size];
}
synchronized void add(long l) {
values[nextpos] = l;
nextpos = (nextpos + 1) % values.length;
count++;
if (count > values.length)
count = values.length;
}
synchronized long[] getValues() {
long[] la = new long[count];
if(nextpos==count) {//wrapped
System.arraycopy(values, 0, la, 0, count);
} else if (nextpos<count){
System.arraycopy(values, nextpos, la, 0, count-nextpos);
System.arraycopy(values, 0, la, count-nextpos, nextpos);
} else {
throw new RuntimeException("nextpos ("+nextpos+") > count ("+count+")");
}
return la;
}
static long findMax(long[] la) {
int n = la.length;
long m = 0;
for(int i=0; i<n; i++) {
if(la[i]>m)
m = la[i];
}
return m;
}
}
static class ProfilerUI extends Frame {
Graph graph;
ProfilerDelegateUI pd;
ProfilerUI(ProfilerDelegateUI _pd, int columns) {
super("ProfilerUI");
this.pd = _pd;
setLayout(new BorderLayout());
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
pd.destroy();
}
});
graph = new Graph(pd, columns);
graph.setFont(new Font("Dialog", Font.PLAIN, 10));
this.add(graph, BorderLayout.CENTER);
}
public void doLayout() {
Dimension d = getSize();
Insets ins = getInsets();
graph.setBounds(ins.left, ins.top, d.width - ins.left - ins.right, d.height - ins.top - ins.bottom);
}
}
static class Graph extends Component {
static Color fg = Color.white;
static Color bg = Color.black;
static final int TOP = 2;
static final int BOTTOM = 2;
static final int LEFT = 2;
static final int RIGHT = 2;
static final int GAP = 2;
ProfilerDelegateUI pd;
int columns;
Graph(ProfilerDelegateUI pd, int columns) {
this.pd = pd;
this.columns = columns;
}
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
Dimension d = getSize();
g.setColor(bg);
g.fillRect(0, 0, d.width, d.height);
g.setColor(fg);
g.drawRect(0, 0, d.width - 1, d.height - 1);
try {
paintSeries(g, LEFT, TOP, d.width - LEFT - RIGHT, d.height - TOP - BOTTOM, pd.items);
} catch(Throwable t) {
t.printStackTrace();
}
Toolkit.getDefaultToolkit().sync();
}
void paintSeries(Graphics g, int x, int y, int w, int h, Map items) {
int n = items.size();
if(n<=0)
return;
Map.Entry[] entries = (Map.Entry[])items.entrySet().toArray(new Map.Entry[n]);
int rows = (n-1)/columns +1;
int sh = h/rows;
int sw = w/columns;
for(int i=0; i<n; i++) {
Curve c = (Curve)entries[i].getValue();
paintOne(g, (String)entries[i].getKey(), c, x + sw*(i%columns) +2, y + sh*(i/columns) +2, sw-4, sh-4);
}
}
static void paintOne(Graphics g, String name, Curve c, int x, int y, int w, int h) {
g.setColor(c.bgcolor);
g.fillRect(x, y, w, h);
g.setColor(Color.DARK_GRAY);
g.drawRect(x, y, w, h);
String msg = name;
if(c.count>0) {
g.setColor(Color.GREEN);
long[] values = c.getValues();
long maxy = Curve.findMax(values);
long amp = (maxy<=0 ? 1 : maxy);
int sx1=0;
int sy1=(int)(h*values[0]/amp);
for(int i=0; i<values.length; i++) {
long val = values[i];
int sx2 = (int) (w*i/values.length);
int sy2 = (int) (h*val/amp);
g.drawLine(x+sx1, y+h-sy1, x+sx2, y+h-sy2);
sx1 = sx2;
sy1 = sy2;
}
msg += " = "+values[values.length-1]+" (max="+maxy+")";
} else {
msg += " (no result)";
}
FontMetrics fm = g.getFontMetrics();
int sw = fm.stringWidth(msg);
//int ma = fm.getMaxAscent();
//int md = fm.getMaxDescent();
g.setColor(Color.lightGray);
g.drawString(msg, x+ (w-sw)/2, y + h/2);
}
}
}
sandStormProfiler.java
(text/plain, 5 KB)
/* * Copyright (c) 2001 by Matt Welsh and The Regents of the University of * California. All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written agreement is * hereby granted, provided that the above copyright notice and the following * two paragraphs appear in all copies of this software. * * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * * Author: Matt Welsh <[email protected]> * */ package seda.sandStorm.internal; import seda.sandStorm.api.*; import seda.sandStorm.main.*; import java.io.*; import java.util.*; /** * sandStormProfiler is an implementation of the ProfilerIF interface * for Sandstorm. It is implemented using a thread that periodically * samples the set of ProfilableIF's registered with it, and outputs * the profile to a file. * * @author Matt Welsh * @see ProfilerIF * @see ProfilableIF */ public class sandStormProfiler extends Thread implements sandStormConst, ProfilerIF { private int delay; private PrintWriter pw; private Vector profilables; private boolean started = false; private StageGraph graphProfiler; private IProfilerDelegate delegate; public interface IProfilerDelegate { //HACK: delegate interface void init(ManagerIF mgr, int sampledelay); void add(String name); void remove(String name); void update(String name, long value); void destroy(); } sandStormProfiler(ManagerIF mgr) throws IOException { super("SandStorm Profiler"); graphProfiler = new StageGraph(mgr); SandstormConfig config = mgr.getConfig(); delay = config.getInt("global.profile.delay"); //HACK: delegate interface boolean enable = config.getBoolean("global.profile.enable"); if(enable) { String delegateClassname = config.getString("global.profile.class"); if (delegateClassname == null) { String filename = config.getString("global.profile.filename"); pw = new PrintWriter(new FileWriter(filename, true)); } else { try { delegate = (IProfilerDelegate)Class.forName(delegateClassname).newInstance(); delegate.init(mgr, delay); delegate.add("usedmem(kb)"); delegate.add("freemem(kb)"); delegate.add("totalmem(kb)"); } catch(Exception e) { e.printStackTrace(); } } } profilables = new Vector(1); } /** * Returns true if the profiler is enabled. */ public boolean enabled() { return started; } /** * Add a class to this profiler. */ public void add(String name, ProfilableIF pr) { if (pr == null) return; if (pw == null && delegate==null)//HACK: delegate interface return; synchronized (profilables) { if(delegate==null) {//HACK: delegate interface pw.println("# Registered " + profilables.size() + " " + name); } else { delegate.add(name); } profilables.addElement(new profile(name, pr)); } } public void run() { if (pw == null && delegate==null)//HACK: delegate interface return; started = true; if(pw!=null) {//HACK: delegate interface pw.println("##### Profile started at " + (new Date()).toString()); pw.println("##### Sample delay " + delay + " msec"); } Runtime r = Runtime.getRuntime(); while (true) { long totalmem = r.totalMemory() / 1024; long freemem = r.freeMemory() / 1024; if(pw!=null)//HACK: delegate interface pw.print("totalmem(kb) " + totalmem + " freemem(kb) " + freemem + " "); else if(delegate!=null) { delegate.update("totalmem(kb)",totalmem); delegate.update("freemem(kb)",freemem); delegate.update("usedmem(kb)",(totalmem-freemem)); } synchronized (profilables) { if (profilables.size() > 0) { for (int i = 0; i < profilables.size(); i++) { profile p = (profile)profilables.elementAt(i); if(pw!=null)//HACK: delegate interface pw.print("pr" + i + " " + p.pr.profileSize() + " "); else if(delegate!=null) { delegate.update(p.name, p.pr.profileSize()); } } } } if(pw!=null) {//HACK: delegate interface pw.println(""); pw.flush(); } try { Thread.currentThread().sleep(delay); } catch (InterruptedException ie) { break; } } //while true started=false; delegate.destroy();//HACK: delegate interface } public StageGraph getGraphProfiler() { return graphProfiler; } class profile { String name; ProfilableIF pr; profile(String name, ProfilableIF pr) { this.name = name; this.pr = pr; } } }