A Tapestry Application Status Page

A Tapestry Application Status Page

I’ve spent the last hour creating a very simple Tapestry page but one that i think is very useful. It’s a page that shows application and session information.  Here’s an example of what the page can show:

As you can see it’s got a very simple design but it gets the job done.

The information you’ll probably find most useful is the session size. With this page you can easily check if you’re putting too much information in the http session.

I’m going to create an issue to see if the Tapestry devs want to include this page on the framework. In the meantime here’s the code for the page so you can add it to your application.

The page class
public class ApplicationStatus {

@Inject
@Property
private ApplicationGlobals applicationGlobals;

@Inject
@Property
private RequestGlobals requestGlobals;

@Property
private List sessionAttributes;

@Property
private int totalSessionSize;

@Property
private SessionAttributeInfo currentSessionAttribute;

void setupRender() throws IOException {
sessionAttributes = new ArrayList();

if (getSession() != null) {
Enumeration attributeNames = getSession().getAttributeNames();

while (attributeNames.hasMoreElements()) {
String attributeName = attributeNames.nextElement().toString();

SessionAttributeInfo sessionAttributeInfo = new SessionAttributeInfo(attributeName);
sessionAttributeInfo.setType(getSession().getAttribute(attributeName).getClass().getName());
sessionAttributeInfo.setSerializable(true);

ByteArrayOutputStream baos;
ObjectOutputStream oos = null;

try {
baos = new ByteArrayOutputStream();

oos = new ObjectOutputStream(baos);

oos.writeObject(getSession().getAttribute(attributeName));

sessionAttributeInfo.setSize(baos.size());

totalSessionSize += baos.size();
} catch (NotSerializableException ex) {
sessionAttributeInfo.setSerializable(true);
} finally {
if (oos != null) {
oos.close();
}
}

sessionAttributes.add(sessionAttributeInfo);
}
}
}

@Cached
public HttpSession getSession() {
return requestGlobals.getHTTPServletRequest().getSession(false);
}

public Date getDate(long time) {
return new Date(time);
}

public String formatSize(int size) {
return StorageUnit.of(size).format(size);
}

public enum StorageUnit {

BYTE("bytes", 1L),
KILOBYTE("KB", 1L << 10),
MEGABYTE("MB", 1L << 20),
GIGABYTE("GB", 1L << 30),
TERABYTE("TB", 1L << 40),
PETABYTE("PB", 1L << 50),
EXABYTE("EB", 1L << 60);

public static final StorageUnit BASE = BYTE;

private final String symbol;
private final long divider; // divider of BASE unit

StorageUnit(String name, long divider) {
this.symbol = name;
this.divider = divider;
}

public static StorageUnit of(final long number) {
final long n = number > 0 ? -number : number;
if (n > -(1L << 10)) {
return BYTE;
} else if (n > -(1L << 20)) {
return KILOBYTE;
} else if (n > -(1L << 30)) {
return MEGABYTE;
} else if (n > -(1L << 40)) {
return GIGABYTE;
} else if (n > -(1L << 50)) {
return TERABYTE;
} else if (n > -(1L << 60)) {
return PETABYTE;
} else { // n >= Long.MIN_VALUE
return EXABYTE;
}
}

public String format(long number) {
return nf.format((double) number / divider) + " " + symbol;
}

private static java.text.NumberFormat nf
= java.text.NumberFormat.getInstance();

static {
nf.setGroupingUsed(false);
nf.setMinimumFractionDigits(0);
nf.setMaximumFractionDigits(1);
}
}

public static class SessionAttributeInfo {

private String name;
private String type;
private boolean serializable;
private Integer size;

public SessionAttributeInfo(String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}

public boolean isSerializable() {
return serializable;
}

public void setSerializable(boolean serializable) {
this.serializable = serializable;
}

public Integer getSize() {
return size;
}

public void setSize(Integer size) {
this.size = size;
}
}
}
The Page Template
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">



Tapestry Application Status


Application Information

Context Path: ${requestGlobals.request.contextPath}  
Servlet Version: ${applicationGlobals.servletContext.majorVersion}.${applicationGlobals.servletContext.minorVersion}  
Server Info: ${applicationGlobals.servletContext.serverInfo}

Session Information


Id: ${session.id}  
Creation Date: ${getDate(session.creationTime)}  
Last Accessed Date: ${getDate(session.lastAccessedTime)}  
Estimated Size: ${formatSize(totalSessionSize)}  

No session created!

Session Attributes

${formatSize(currentSessionAttribute.size)}




public class ApplicationStatus {

@Inject
@Property
private ApplicationGlobals applicationGlobals;

@Inject
@Property
private RequestGlobals requestGlobals;

@Property
private List sessionAttributes;

@Property
private int totalSessionSize;

@Property
private SessionAttributeInfo currentSessionAttribute;

void setupRender() throws IOException {
sessionAttributes = new ArrayList();

if (getSession() != null) {
Enumeration attributeNames = getSession().getAttributeNames();

while (attributeNames.hasMoreElements()) {
String attributeName = attributeNames.nextElement().toString();

SessionAttributeInfo sessionAttributeInfo = new SessionAttributeInfo(attributeName);
sessionAttributeInfo.setType(getSession().getAttribute(attributeName).getClass().getName());
sessionAttributeInfo.setSerializable(true);

ByteArrayOutputStream baos;
ObjectOutputStream oos = null;

try {
baos = new ByteArrayOutputStream();

oos = new ObjectOutputStream(baos);

oos.writeObject(getSession().getAttribute(attributeName));

sessionAttributeInfo.setSize(baos.size());

totalSessionSize += baos.size();
} catch (NotSerializableException ex) {
sessionAttributeInfo.setSerializable(true);
} finally {
if (oos != null) {
oos.close();
}
}

sessionAttributes.add(sessionAttributeInfo);
}
}
}

@Cached
public HttpSession getSession() {
return requestGlobals.getHTTPServletRequest().getSession(false);
}

public Date getDate(long time) {
return new Date(time);
}

public String formatSize(int size) {
return StorageUnit.of(size).format(size);
}

public enum StorageUnit {

BYTE(”bytes”, 1L),
KILOBYTE(”KB”, 1L << 10),
MEGABYTE(”MB”, 1L << 20),
GIGABYTE(”GB”, 1L << 30),
TERABYTE(”TB”, 1L << 40),
PETABYTE(”PB”, 1L << 50),
EXABYTE(”EB”, 1L << 60);

public static final StorageUnit BASE = BYTE;

private final String symbol;
private final long divider;  // divider of BASE unit

StorageUnit(String name, long divider) {
this.symbol = name;
this.divider = divider;
}

public static StorageUnit of(final long number) {
final long n = number > 0 ? -number : number;
if (n > -(1L << 10)) {
return BYTE;
} else if (n > -(1L << 20)) {
return KILOBYTE;
} else if (n > -(1L << 30)) {
return MEGABYTE;
} else if (n > -(1L << 40)) {
return GIGABYTE;
} else if (n > -(1L << 50)) {
return TERABYTE;
} else if (n > -(1L << 60)) {
return PETABYTE;
} else {  // n >= Long.MIN_VALUE
return EXABYTE;
}
}

public String format(long number) {
return nf.format((double) number / divider) + ” ” + symbol;
}

private static java.text.NumberFormat nf
= java.text.NumberFormat.getInstance();

static {
nf.setGroupingUsed(false);
nf.setMinimumFractionDigits(0);
nf.setMaximumFractionDigits(1);
}
}

public static class SessionAttributeInfo {

private String name;
private String type;
private boolean serializable;
private Integer size;

public SessionAttributeInfo(String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}

public boolean isSerializable() {
return serializable;
}

public void setSerializable(boolean serializable) {
this.serializable = serializable;
}

public Integer getSize() {
return size;
}

public void setSize(Integer size) {
this.size = size;
}
}
}

© 2008 - PT.JUG - Todos os direitos reservados
seara