I have a small system, and I want to offer a product that can analyze errors / exceptions and suggest a possible solution.
So I want a way to parse a java Exception (since I have them only in logs [I don't want to affect the actual system]).
After parsing it, I want to save it in a DB and compare it to previously saved exceptions (in some format), so that I can find the closest matching exception.
I thought about the following idea: "XException at A at B at C at D" will be saved as [XException, A, B, C, D] and I will be somehow searching in my DB: [XException, ?, ?, ?] which is the closest. For example: [XException, A, G, C, D] is quite good.
What do you think of these ideas?
Any effiecient way to parse Exceptions?
Efficient or better ways to define distance between two Exceptions?
Know any open sources that can do this - I saure haven't found any.
Thank you.
It's quite hard work, but here is a demonstration of parsing some real-life exceptions generated on the fly.
Code:
private static List<String> generate_$() {
List<String> returnValue = new LinkedList<String>();
Exception[] exceptions = { new ClassCastException(),
new NullPointerException(), new IOException("foo") };
for (Exception exception : exceptions) {
try {
throw exception;
} catch (Exception e) {
StringWriter writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
returnValue.add(writer.getBuffer().toString());
}
}
return returnValue;
}
public static void main(String[] args) {
List<String> examples = generate_$();
for (String trace : examples) {
Pattern headLinePattern = Pattern.compile("([\\w\\.]+)(:.*)?");
Matcher headLineMatcher = headLinePattern.matcher(trace);
if (headLineMatcher.find()) {
System.out.println("Headline: " + headLineMatcher.group(1));
if (headLineMatcher.group(2) != null) {
System.out.println("Optional message "
+ headLineMatcher.group(2));
}
}
// "at package.class.method(source.java:123)"
Pattern tracePattern = Pattern
.compile("\\s*at\\s+([\\w\\.$_]+)\\.([\\w$_]+)(\\(.*java)?:(\\d+)\\)(\\n|\\r\\n)");
Matcher traceMatcher = tracePattern.matcher(trace);
List<StackTraceElement> stackTrace = new ArrayList<StackTraceElement>();
while (traceMatcher.find()) {
String className = traceMatcher.group(1);
String methodName = traceMatcher.group(2);
String sourceFile = traceMatcher.group(3);
int lineNum = Integer.parseInt(traceMatcher.group(4));
stackTrace.add(new StackTraceElement(className, methodName,
sourceFile, lineNum));
}
System.out.println("Stack: " + stackTrace);
}
}
Output:
Headline: java.lang.ClassCastException
Stack: [com.adamish.ExceptionParse.generate_$((ExceptionParse.java:16), com.adamish.ExceptionParse.main((ExceptionParse.java:31)]
Headline: java.lang.NullPointerException
Stack: [com.adamish.ExceptionParse.generate_$((ExceptionParse.java:17), com.adamish.ExceptionParse.main((ExceptionParse.java:31)]
Headline: java.io.IOException
Optional message : foo
Stack: [com.adamish.ExceptionParse.generate_$((ExceptionParse.java:17), com.adamish.ExceptionParse.main((ExceptionParse.java:31)]
I guess this question is going to be closed as being too open-ended. SO is intended for questions that can be given clear and definitive answers.
Even so, before that happens I'd like to say that this seems like a pretty good idea and I hope you can make it work. It would be best to focus on those parts of the stack trace that clearly identify immutable information, like package, class and method names. As for detecting partial or complete matches, I suggest you look into known indexing and matching algorithms. Some well-known algorithms for text searches could be applied, but with the "atomic" units being method names or package-qualified class names instead if single letters or words.
Good luck!
EDIT: just thought of something else. You may wish to focus on making your implementation as generic as possible for stack traces of many different programming languages, frameworks etc. This would make the software more future-proof and widely applicable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With