Skip to content
Snippets Groups Projects
Commit 28504e3e authored by Florian Fittkau's avatar Florian Fittkau
Browse files

some new features

parent 764ada28
No related branches found
No related tags found
No related merge requests found
...@@ -3,7 +3,6 @@ package kieker.monitoring.gwt.client.monitoring; ...@@ -3,7 +3,6 @@ package kieker.monitoring.gwt.client.monitoring;
public class AspectWeaver { public class AspectWeaver {
public static native void weave() /*-{ public static native void weave() /*-{
$wnd.WRITE_TIME_TRIGGERED = false $wnd.WRITE_TIME_TRIGGERED = false
$wnd.MODULE_NAME = "gwtmonitoring"
$wnd.RECORD_BATCH_SIZE = 1 // increase for normal usage... $wnd.RECORD_BATCH_SIZE = 1 // increase for normal usage...
function initMonitoring() { function initMonitoring() {
...@@ -20,53 +19,80 @@ public class AspectWeaver { ...@@ -20,53 +19,80 @@ public class AspectWeaver {
$wnd.moduleCacheJSLines = null $wnd.moduleCacheJSLines = null
$wnd.moduleCacheJSLineLength = -1 $wnd.moduleCacheJSLineLength = -1
$wnd.functionLineMap = {} $wnd.functionToClassnameMap = {}
$wnd.classFilenameMap = {} $wnd.methodnameToLinenumber = {}
$wnd.recordBatchStorage = [] $wnd.recordBatchStorage = []
$wnd.stringRegistry = {}
$wnd.stringRegistryNextIndex = 0
$wnd.currentStackDepth = 0 $wnd.currentStackDepth = 0
$wnd.traceID = 0 // TODO init from server? $wnd.traceID = 0 // TODO init from server?
$wnd.orderID = 0 $wnd.orderID = 0
$wnd.lastWrite = 0 $wnd.lastWrite = 0
$wnd.jQuery.get('http://localhost:9876/'+$wnd.MODULE_NAME+'/' + $strongName $wnd.jQuery.get('http://localhost:9876/gwtmonitoring/' + $strongName
+ '.cache.js', '', function(result) { + '.cache.js', '', function(result) {
if (result) {
$wnd.moduleCacheJSLines = result.split("\n"); $wnd.moduleCacheJSLines = result.split("\n");
$wnd.moduleCacheJSLineLength = $wnd.moduleCacheJSLines.length; $wnd.moduleCacheJSLineLength = $wnd.moduleCacheJSLines.length;
var lines = $wnd.moduleCacheJSLines
var length = $wnd.moduleCacheJSLineLength
for (var i = 10; i < length; i++) {
var line = lines[i];
if (line.length >= 9
&& line.startsWith('function ')) {
var methodname = line.substring(9, line.indexOf("("))
$wnd.methodnameToLinenumber[methodname] = i
}
}
}
}, 'html'); }, 'html');
} }
function fetchStaticClazz(methodname) { function getStringRegistryId(str) {
var clazzname = null; if (str in $wnd.stringRegistry) {
if (methodname in $wnd.functionLineMap) { return $wnd.stringRegistry[str];
return $wnd.functionLineMap[methodname]
} else { } else {
var toSeekName = 'function ' + methodname; $wnd.stringRegistry[str] = $wnd.stringRegistryNextIndex;
var toSeekNameLength = toSeekName.length $wnd.recordBatchStorage.push("4;" + $wnd.stringRegistryNextIndex + ";" + str);
var lines = $wnd.moduleCacheJSLines return $wnd.stringRegistryNextIndex++;
var length = $wnd.moduleCacheJSLineLength
var firstMethodChar = methodname[0]
for (var i = 0; i < length; i++) {
var line = lines[i];
if (line.length >= toSeekNameLength
&& line[9] == firstMethodChar
&& line.startsWith(toSeekName)) {
for (var j = i; j < length; j++) {
var indexName = lines[j].indexOf("createForClass_0_g$")
if (indexName >= 0) {
clazzname = lines[j].substring(indexName + 21, lines[j].lastIndexOf(","));
clazzname = clazzname.substring(0, clazzname.lastIndexOf(",")-1);
clazzname = clazzname.substring(0, clazzname.indexOf(",")-1) + "." + clazzname.substring(clazzname.indexOf(",") + 3, clazzname.length);
$wnd.functionLineMap[methodname] = clazzname;
return clazzname;
} }
} }
function createBeforeRecord(clazzname, methodname) {
$wnd.recordBatchStorage.push("1;" + $wnd.performance.now() + ";"
+ $wnd.traceID + ";" + ($wnd.orderID++) + ";" + clazzname
+ ";" + methodname);
$wnd.currentStackDepth++;
} }
function createAfterRecord(afterTimestamp,clazzname, methodname) {
$wnd.currentStackDepth--;
$wnd.recordBatchStorage.push("3;" + afterTimestamp + ";"
+ $wnd.traceID + ";" + ($wnd.orderID++) + ";" + clazzname
+ ";" + methodname);
}
function writeRecordsToServerIfNecessary(afterTimestamp) {
if (!$wnd.WRITE_TIME_TRIGGERED) {
if ($wnd.recordBatchStorage.length >= $wnd.RECORD_BATCH_SIZE) {
@kieker.monitoring.gwt.client.monitoring.MonitoringManager::sendRecordBundle(Ljava/lang/String;)($wnd.recordBatchStorage.toString())
$wnd.recordBatchStorage = [];
}
} else {
if (afterTimestamp - $wnd.lastWrite > 1000) {
$wnd.lastWrite = afterTimestamp
@kieker.monitoring.gwt.client.monitoring.MonitoringManager::sendRecordBundle(Ljava/lang/String;)($wnd.recordBatchStorage.toString())
$wnd.recordBatchStorage = [];
} }
} }
return clazzname;
} }
function finishTraceIfNecessary() { function finishTraceIfNecessary() {
...@@ -76,51 +102,110 @@ public class AspectWeaver { ...@@ -76,51 +102,110 @@ public class AspectWeaver {
$wnd.traceID++; $wnd.traceID++;
$wnd.orderID = 0; $wnd.orderID = 0;
$wnd.currentStackDepth = 0; $wnd.currentStackDepth = 0;
}; }
;
} }
function aspectInvoc(invocation) { function aspectInvocOperation(invocation) {
// JS source not yet fetched therefore only proceed // JS source not yet fetched therefore only proceed
if ($wnd.moduleCacheJSLineLength == -1) if ($wnd.moduleCacheJSLineLength == -1)
return invocation.proceed(); return invocation.proceed();
// TODO replace method with StringRegistryID and send those records... eval("$wnd.currentClazzname = (this.__proto__.___clazz$.packageName_1_g$ + '.' + this.__proto__.___clazz$.compoundName_1_g$)")
// TODO operations:
// eval("$wnd.currentClazz = (this.__proto__.___clazz$.packageName_1_g$ + '.' + this.__proto__.___clazz$.compoundName_1_g$)")
var classFilename = fetchStaticClazz(invocation.method) var clazzname = $wnd.currentClazzname;
if (clazzname == null) {
if (className == null) {
return invocation.proceed(); return invocation.proceed();
} }
if (classFilename.startsWith("kieker.monitoring.gwt.client.monitoring") || !classFilename.startsWith("kieker.monitoring.gwt.client")) var methodname = invocation.method
return invocation.proceed()
$wnd.recordBatchStorage.push("1;" + $wnd.performance.now() + ";" + $wnd.traceID + ";" + ($wnd.orderID++) + ";" + classFilename + ";" + invocation.method); var classnameId = getStringRegistryId(clazzname)
var methodnameId = getStringRegistryId(methodname)
createBeforeRecord(classnameId, methodnameId);
$wnd.currentStackDepth++;
var result = invocation.proceed(); var result = invocation.proceed();
$wnd.currentStackDepth--;
var afterTimestamp = $wnd.performance.now() var afterTimestamp = $wnd.performance.now();
$wnd.recordBatchStorage.push("3;" + afterTimestamp + ";" + $wnd.traceID + ";" + ($wnd.orderID++) + ";" + classFilename + ";" + invocation.method); createAfterRecord(afterTimestamp,classnameId, methodnameId);
if (!$wnd.WRITE_TIME_TRIGGERED) { writeRecordsToServerIfNecessary(afterTimestamp);
if ($wnd.recordBatchStorage.length >= $wnd.RECORD_BATCH_SIZE) {
@kieker.monitoring.gwt.client.monitoring.MonitoringManager::sendRecordBundle(Ljava/lang/String;)($wnd.recordBatchStorage.toString()) finishTraceIfNecessary();
$wnd.recordBatchStorage = [];
return result;
} }
function fetchStaticClazz(methodname) {
if (methodname in $wnd.functionToClassnameMap) {
return $wnd.functionToClassnameMap[methodname]
} else { } else {
if (afterTimestamp - $wnd.lastWrite > 1000) { var L1 = $wnd.performance.now();
$wnd.lastWrite = afterTimestamp
@kieker.monitoring.gwt.client.monitoring.MonitoringManager::sendRecordBundle(Ljava/lang/String;)($wnd.recordBatchStorage.toString()) var lines = $wnd.moduleCacheJSLines
$wnd.recordBatchStorage = []; var length = $wnd.moduleCacheJSLineLength
if (methodname in $wnd.methodnameToLinenumber) {
var linenumber = $wnd.methodnameToLinenumber[methodname]
for (var i = linenumber; i < length; i++) {
var indexName = lines[i]
.indexOf("createForClass_0_g$")
if (indexName >= 0) {
var clazzname = lines[i].substring(indexName + 21,
lines[i].lastIndexOf(","));
clazzname = clazzname.substring(0, clazzname
.lastIndexOf(",") - 1);
clazzname = clazzname.substring(0, clazzname
.indexOf(",") - 1)
+ "."
+ clazzname.substring(clazzname
.indexOf(",") + 3,
clazzname.length);
$wnd.functionToClassnameMap[methodname] = clazzname;
return clazzname;
}
} }
} }
$wnd.functionToClassnameMap[methodname] = null;
return null;
}
}
function aspectInvocStatic(invocation) {
// JS source not yet fetched therefore only proceed
if ($wnd.moduleCacheJSLineLength == -1)
return invocation.proceed();
var methodname = invocation.method
var clazzname = fetchStaticClazz(methodname);
if (clazzname == null) {
return invocation.proceed();
}
if (!clazzname.startsWith("kieker")
|| clazzname
.startsWith("kieker.monitoring.gwt.client.monitoring")) {
// delete the value
$wnd.functionToClassnameMap[methodname] = null;
return invocation.proceed();
}
var classnameId = getStringRegistryId(clazzname)
var methodnameId = getStringRegistryId(methodname)
createBeforeRecord(classnameId, methodnameId);
var result = invocation.proceed();
var afterTimestamp = $wnd.performance.now();
createAfterRecord(afterTimestamp,classnameId, methodnameId);
writeRecordsToServerIfNecessary(afterTimestamp);
finishTraceIfNecessary(); finishTraceIfNecessary();
return result; return result;
...@@ -132,30 +217,28 @@ public class AspectWeaver { ...@@ -132,30 +217,28 @@ public class AspectWeaver {
eval("for (var key in prototypesByTypeId_1_g$) { $wnd.prototypeDefinitions.push(prototypesByTypeId_1_g$[key]) };") eval("for (var key in prototypesByTypeId_1_g$) { $wnd.prototypeDefinitions.push(prototypesByTypeId_1_g$[key]) };")
$wnd.tempAttri = 0
for (var i = 2; i < $wnd.prototypeDefinitions.length; i++) { for (var i = 2; i < $wnd.prototypeDefinitions.length; i++) {
$wnd.currentPrototypeElement = $wnd.prototypeDefinitions[i] $wnd.currentPrototypeElement = $wnd.prototypeDefinitions[i]
$wnd.shouldInstrumentObject = false $wnd.shouldInstrumentObject = false
eval("if ($wnd.currentPrototypeElement.___clazz$ && $wnd.currentPrototypeElement.___clazz$.packageName_1_g$.startsWith('kieker')) {$wnd.shouldInstrumentObject = true}") eval("if ($wnd.currentPrototypeElement.___clazz$ && $wnd.currentPrototypeElement.___clazz$.packageName_1_g$.startsWith('kieker') && !($wnd.currentPrototypeElement.___clazz$.packageName_1_g$.startsWith('kieker.monitoring.gwt.client.monitoring'))) {$wnd.shouldInstrumentObject = true}")
if ($wnd.shouldInstrumentObject) { if ($wnd.shouldInstrumentObject == true) {
// $wnd.jQuery.aop $wnd.jQuery.aop.around({
// .around( target : $wnd.currentPrototypeElement,
// { method : /(^[a-z].*)/,
// target : $wnd.currentPrototypeElement, }, aspectInvocOperation);
// method : /(^[a-z].*)/,
// }, aspectInvoc);
} }
} }
$wnd.shouldInstrumentObject = null
$wnd.prototypeDefinitions = [] $wnd.currentPrototypeElement = null
$wnd.prototypeDefinitions = null
$wnd.jQuery.aop $wnd.jQuery.aop
.around( .around(
{ {
target : this, target : this,
method : /(^[a-s].*)|(^[u-z].*)|(^[t][a-x].*)|(^[t][z].*)|(^[t][y][p][e][P].*)|(^[t][y][p][e][_].*)/, method : /(^[a-s].*)|(^[u-z].*)|(^[t][a-x].*)|(^[t][z].*)|(^[t][y][p][e][P].*)|(^[t][y][p][e][_].*)/,
}, aspectInvoc); }, aspectInvocStatic);
}-*/; }-*/;
} }
package kieker.monitoring.gwt.server.monitoring; package kieker.monitoring.gwt.server.monitoring;
import java.util.concurrent.ConcurrentHashMap;
import kieker.monitoring.gwt.client.monitoring.MonitoringService; import kieker.monitoring.gwt.client.monitoring.MonitoringService;
import kieker.monitoring.gwt.server.monitoring.writer.IGWTRecordWriter; import kieker.monitoring.gwt.server.monitoring.writer.IGWTRecordWriter;
import kieker.monitoring.gwt.server.monitoring.writer.KiekerRecordWriter; import kieker.monitoring.gwt.server.monitoring.writer.KiekerRecordWriter;
...@@ -10,7 +12,9 @@ public class MonitoringServiceImpl extends RemoteServiceServlet implements Monit ...@@ -10,7 +12,9 @@ public class MonitoringServiceImpl extends RemoteServiceServlet implements Monit
private static final long serialVersionUID = -1474770740583197159L; private static final long serialVersionUID = -1474770740583197159L;
IGWTRecordWriter writer = new KiekerRecordWriter(); private static IGWTRecordWriter writer = new KiekerRecordWriter();
private static ConcurrentHashMap<Integer, String> stringRegistry = new ConcurrentHashMap<Integer, String>();
@Override @Override
public void sendRecordBundle(final String recordBundle) { public void sendRecordBundle(final String recordBundle) {
...@@ -21,33 +25,45 @@ public class MonitoringServiceImpl extends RemoteServiceServlet implements Monit ...@@ -21,33 +25,45 @@ public class MonitoringServiceImpl extends RemoteServiceServlet implements Monit
// TODO always throw away trace 0? // TODO always throw away trace 0?
String recordId = splitRecord[0]; final String recordId = splitRecord[0];
if (recordId.equals("1")) { // BEFORE record if (recordId.equals("1")) { // BEFORE record
writer.writeBeforeRecord(convertTimestampToNano(splitRecord[1]), writer.writeBeforeRecord(convertTimestampToNano(splitRecord[1]),
Long.parseLong(splitRecord[2]), Integer.parseInt(splitRecord[3]), Long.parseLong(splitRecord[2]), Integer.parseInt(splitRecord[3]),
convertClassname(splitRecord[4]), convertMethod(splitRecord[5])); convertClassname(splitRecord[4]), convertMethod(splitRecord[5]) + "()");
} else if (recordId.equals("3")) { // AFTER record } else if (recordId.equals("3")) { // AFTER record
writer.writeAfterRecord(convertTimestampToNano(splitRecord[1]), writer.writeAfterRecord(convertTimestampToNano(splitRecord[1]),
Long.parseLong(splitRecord[2]), Integer.parseInt(splitRecord[3]), Long.parseLong(splitRecord[2]), Integer.parseInt(splitRecord[3]),
convertClassname(splitRecord[4]), convertMethod(splitRecord[5])); convertClassname(splitRecord[4]), convertMethod(splitRecord[5]) + "()");
} else if (recordId.equals("4")) { // String record
stringRegistry.put(Integer.parseInt(splitRecord[1]), splitRecord[2]);
} }
} }
} }
private final long convertTimestampToNano(String timestampInMsec) { private final long convertTimestampToNano(final String timestampInMsec) {
final double timestampInDouble = Double.parseDouble(timestampInMsec); final double timestampInDouble = Double.parseDouble(timestampInMsec);
return Math.round(timestampInDouble * 1000 * 1000); return Math.round(timestampInDouble * 1000 * 1000);
} }
private final String convertClassname(String clazzFilename) { private final String convertClassname(final String clazzFilename) {
final String withoutEnding = clazzFilename.substring(0, clazzFilename.indexOf(".")); return stringRegistry.get(Integer.parseInt(clazzFilename));
return withoutEnding.replaceAll("/", "."); }
private final String convertMethod(final String method) {
String methodname = stringRegistry.get(Integer.parseInt(method));
if (methodname.lastIndexOf("_") >= 0) {
methodname = methodname.substring(0, methodname.lastIndexOf("_"));
} else {
return methodname;
} }
private final String convertMethod(String method) { if (methodname.lastIndexOf("_") >= 0) {
final String withoutGS = method.substring(0, method.lastIndexOf("_")); return methodname.substring(0, methodname.lastIndexOf("_"));
return withoutGS.substring(0, withoutGS.lastIndexOf("_")) + "()"; } else {
return methodname;
}
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment