r9708 - in helma-ng/trunk: modules/helma src/org/helma/util
[email protected] Tue, 5 May 2009 00:33:59 +0200 (CEST)
| Newsgroups | gmane.comp.java.helma.cvs |
|---|---|
| Message-ID | <20090504223359.AD6B23D0D6@mia> |
Author: hannes
Date: 2009-05-05 00:33:59 +0200 (Tue, 05 May 2009)
New Revision: 9708
Modified:
helma-ng/trunk/modules/helma/logging.js
helma-ng/trunk/src/org/helma/util/RhinoAppender.java
Log:
Change log4j RhinoAppender to use a thread-local callback, and use helma/webapp/util.ResponseFilter to insert the log messages right before the body close tag.
Details at http://dev.helma.org/trac/helma/changeset/9708
Modified: helma-ng/trunk/modules/helma/logging.js
===================================================================
--- helma-ng/trunk/modules/helma/logging.js 2009-05-04 19:12:23 UTC (rev 9707)
+++ helma-ng/trunk/modules/helma/logging.js 2009-05-04 22:33:59 UTC (rev 9708)
@@ -2,6 +2,9 @@
include('helma/system');
include('helma/buffer');
+importPackage(org.apache.log4j);
+importClass(org.apache.log4j.xml.DOMConfigurator);
+
var __shared__ = true;
var configured = false;
@@ -12,11 +15,10 @@
* Make sure to set the reset property to true in the <log4j:configuration> header
* e.g. <log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/' reset="true">
*/
-exports.setConfig = function(resource) {
+var setConfig = exports.setConfig = function(resource) {
var {path, url} = resource;
var configurator = path.endsWith('.properties') || path.endsWith('.props') ?
- org.apache.log4j.PropertyConfigurator :
- org.apache.log4j.xml.DOMConfigurator;
+ PropertyConfigurator : DOMConfigurator;
configurator.configure(url);
try {
configurator.configureAndWatch(path, 2000);
@@ -29,16 +31,16 @@
/**
* Get a logger for the given name.
*/
-exports.getLogger = function(name) {
+var getLogger = exports.getLogger = function(name) {
if (!configured) {
// getResource('foo').name gets us the absolute path to a local resource
this.setConfig(getResource('config/log4j.properties'));
}
- return org.apache.log4j.Logger.getLogger(name.replace(/\//g, '.'));
+ return Logger.getLogger(name.replace(/\//g, '.'));
}
// now that getLogger is installed we can get our own log
-var log = exports.getLogger(__name__);
+var log = getLogger(__name__);
/**
* Render log4j messages to response buffer in the style of helma 1 res.debug().
@@ -48,47 +50,60 @@
if (!responseLogEnabled) {
return req.process();
}
- getRhinoContext().putThreadLocal('responseLog', new java.util.LinkedList());
- var res = req.process();
+ var messages = [];
+ var appender = Logger.getRootLogger().getAppender("rhino") || {};
+ appender.callback = function(message, scriptStack, javaStack) {
+ messages.push([message, scriptStack, javaStack]);
+ };
+
+ var res;
+ try {
+ res = req.process();
+ } finally {
+ appender.callback = null;
+ }
+
if (res && typeof res === 'object' && typeof res.close === 'function') {
res = res.close();
}
- var [status, headers, body] = res;
-
- if (status != 200 && status < 400) {
+ if (res[0] != 200 && res[0] < 400) {
return res;
}
- var list = getRhinoContext().getThreadLocal('responseLog');
-
- if (list && !list.isEmpty()) {
- if (!(body instanceof Buffer)) {
- body = res[2] = new Buffer(body);
- }
- for (var i = 0; i < list.size(); i++) {
- var item = list.get(i);
- var msg = item[0];
- var multiline = msg && msg.trim().indexOf('\n') > 0 || msg.indexOf('\r')> 0;
- body.write("<div class=\"helma-debug-line\" style=\"background: #fc3;");
- body.write("color: black; border-top: 1px solid black;\">");
- if (multiline) {
- body.write("<pre>").write(msg).write("</pre>");
- } else {
- body.write(msg);
+ if (messages.length > 0) {
+ var ResponseFilter = require("helma/webapp/util").ResponseFilter;
+ res[2] = new ResponseFilter(res[2], function(part) {
+ if (typeof part != "string" && part.lastIndexOf("</body>") == -1) {
+ return part;
}
- if (item[1]) {
- body.write("<h4 style='padding-left: 8px; margin: 4px;'>Script Stack</h4>");
- body.write("<pre style='margin: 0;'>", item[1], "</pre>");
+ var buffer = new Buffer();
+ for (var i = 0; i < messages.length; i++) {
+ var item = messages[i];
+ var msg = item[0];
+ var multiline = msg && msg.trim().indexOf('\n') > 0 || msg.indexOf('\r')> 0;
+ buffer.write("<div class=\"helma-debug-line\" style=\"background: #fc3;");
+ buffer.write("color: black; border-top: 1px solid black;\">");
+ if (multiline) {
+ buffer.write("<pre>").write(msg).write("</pre>");
+ } else {
+ buffer.write(msg);
+ }
+ if (item[1]) {
+ buffer.write("<h4 style='padding-left: 8px; margin: 4px;'>Script Stack</h4>");
+ buffer.write("<pre style='margin: 0;'>", item[1], "</pre>");
+ }
+ if (item[2]) {
+ buffer.write("<h4 style='padding-left: 8px; margin: 4px;'>Java Stack</h4>");
+ buffer.write("<pre style='margin: 0;'>", item[2], "</pre>");
+ }
+ buffer.writeln("</div>");
}
- if (item[2]) {
- body.write("<h4 style='padding-left: 8px; margin: 4px;'>Java Stack</h4>");
- body.write("<pre style='margin: 0;'>", item[2], "</pre>");
- }
- body.writeln("</div>");
- }
+ var insert = part.lastIndexOf("</body>");
+ return part.substring(0, insert) + buffer + part.substring(insert);
+ });
}
return res;
Modified: helma-ng/trunk/src/org/helma/util/RhinoAppender.java
===================================================================
--- helma-ng/trunk/src/org/helma/util/RhinoAppender.java 2009-05-04 19:12:23 UTC (rev 9707)
+++ helma-ng/trunk/src/org/helma/util/RhinoAppender.java 2009-05-04 22:33:59 UTC (rev 9708)
@@ -6,15 +6,16 @@
import org.helma.javascript.RhinoEngine;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.RhinoException;
+import org.mozilla.javascript.Function;
-import java.util.List;
-
/**
* A log4j appender that passes log events to a Rhino callback function
* named <code>onLogEvent</code>.
*/
public class RhinoAppender extends AppenderSkeleton {
+ private static ThreadLocal<Function> callback = new ThreadLocal<Function>();
+
/**
* Tries to get the current {@link RhinoEngine} and invoke a callback named
* <code>onLogEvent</code>, passing the log message and the stack trace rendered
@@ -23,16 +24,11 @@
*/
protected void append(LoggingEvent event) {
Context cx = Context.getCurrentContext();
- if (cx == null) {
+ Function cb = callback.get();
+ if (cx == null || cb == null) {
return;
}
- Object responseLog = cx.getThreadLocal("responseLog");
- if (responseLog == null || !(responseLog instanceof List)) {
- return;
- }
- List logList = (List) responseLog;
-
if(this.layout == null) {
errorHandler.error("No layout set for the appender named ["+ name+"].");
return;
@@ -60,10 +56,18 @@
}
}
- logList.add(new String[] {message, scriptStack, javaStack});
+ Object[] args = new Object[] {message, scriptStack, javaStack};
+ cb.call(cx, cb.getParentScope(), null, args);
+ }
+ public static Function getCallback() {
+ return callback.get();
}
+ public static void setCallback(Function callback) {
+ RhinoAppender.callback.set(callback);
+ }
+
/**
* We need a layout, so this returns true.
* @return true