Last active
October 27, 2015 17:30
-
-
Save jan-krueger/cbacc575ce587fb97596 to your computer and use it in GitHub Desktop.
Simple Logger
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package de.YonasCode.SweetUtils.Debugger; | |
import java.lang.reflect.*; | |
import java.util.concurrent.TimeUnit; | |
import java.util.regex.Pattern; | |
/** | |
* Created by Yonas on 21.06.2015. | |
*/ | |
public class Debugger<T> implements InvocationHandler { | |
private T clazz; | |
private static Pattern[] pattern = { | |
Pattern.compile("^((.*)?([a-zA-Z0-9\\.]+)((;)?@)([a-zA-Z0-9]+))"), | |
Pattern.compile("^(java.util|java.lang).*") | |
}; | |
public Debugger(T clazz) { | |
this.clazz = clazz; | |
} | |
@Override | |
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { | |
StringBuffer buffer = new StringBuffer(); | |
buffer.append(clazz.getClass().getSimpleName()); | |
buffer.append(Debugger.modifiersToString(clazz.getClass().getModifiers())); | |
buffer.append(method.getName()); | |
buffer.append("("); | |
for(int i = 0; args != null && i < args.length; i++) { | |
String argument = (args[i] == null ? "null" : Debugger.getSimpleName(args[i].toString())); | |
buffer.append(argument); | |
if(i < (args.length - 1)) { | |
buffer.append(", "); | |
} | |
} | |
buffer.append(")"); | |
Object result = null; | |
String exceptionName = null; | |
String exceptionMessage = null; | |
long executionTime = -1; | |
try { | |
executionTime = System.nanoTime(); | |
//invoke the method | |
result = method.invoke(clazz, args); | |
executionTime = System.nanoTime() - executionTime; | |
} catch(Exception exception) { | |
//get information (name, message) from the exception | |
executionTime = System.nanoTime() - executionTime; | |
exceptionName = exception.getCause().getClass().getSimpleName(); | |
exceptionMessage = exception.getCause().getLocalizedMessage(); | |
} | |
//execution time | |
if(TimeUnit.NANOSECONDS.toMillis(executionTime) == 0) { | |
buffer.append("\n -> " + executionTime + "ns "); | |
} else { | |
buffer.append("\n -> " + TimeUnit.NANOSECONDS.toMillis(executionTime) + "ms "); | |
} | |
//where? | |
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); | |
StackTraceElement stackTraceElement = (stackTraceElements.length >= 4 ? stackTraceElements[3] : null); | |
if(!(stackTraceElement == null)) { | |
buffer.append("\n -> " + String.format( | |
"Called in %s#%s (%s) at line %d", | |
Debugger.getSimpleName(stackTraceElement.getClassName()), | |
stackTraceElement.getMethodName(), | |
stackTraceElement.getFileName(), | |
stackTraceElement.getLineNumber() | |
)); | |
} | |
//result | |
String className = null; | |
StringBuilder resultString = new StringBuilder(); | |
if(!(result == null)) { | |
//called when it's a normal java class | |
if(result.getClass().getName().matches(Debugger.pattern[1].pattern())) { | |
className = result.getClass().getSimpleName(); | |
resultString = resultString.append(Debugger.getSimpleName(result.toString())); | |
} else { //called when it's a "custom" class | |
className = result.getClass().getSimpleName(); | |
if(className.isEmpty()) { | |
className = result.getClass().getName(); | |
} | |
Field[] fields = result.getClass().getDeclaredFields(); | |
for(int i = 0; i < fields.length; i++) { | |
Field field = fields[i]; | |
field.setAccessible(true); | |
String fieldName = field.getName(); | |
String fieldValue = Debugger.getSimpleName(field.get(result).toString()); | |
resultString.append(fieldName + " = " + fieldValue); | |
if(i < (fields.length - 1)) { | |
resultString.append(", "); | |
} | |
} | |
} | |
} else if(method.getReturnType().equals(Void.TYPE)) { //called when the return type is "void" | |
resultString.append("void"); | |
} else if(!(exceptionName == null)) { //called when the invoke "throws" an exception | |
className = exceptionName; | |
resultString.append(exceptionMessage); | |
} else { //called when the method returns "null" but the return type is not "void" | |
resultString.append("null"); | |
} | |
buffer.append(String.format("\n -> (%s) %s", className, resultString)); | |
//print out the result | |
System.out.println(buffer); | |
return result; | |
} | |
public static String modifiersToString(int modifiers) { | |
if(Modifier.isPublic(modifiers)) { | |
return "+"; | |
} | |
if(Modifier.isProtected(modifiers)) { | |
return "#"; | |
} | |
if(Modifier.isPrivate(modifiers)) { | |
return "-"; | |
} | |
return ""; | |
} | |
public static <V> V factory(Class type, V value) { | |
return (V) Proxy.newProxyInstance( | |
Debugger.class.getClassLoader(), | |
new Class[]{ type }, | |
new Debugger<V>( value ) | |
); | |
} | |
private static String getSimpleName(String clazz) { | |
if(!(clazz.matches(Debugger.pattern[0].pattern()))) { | |
try { | |
return Class.forName(clazz).getSimpleName(); | |
} catch (ClassNotFoundException e) { | |
return clazz; | |
} | |
} | |
boolean isArray = false; | |
int start = -1, end = -1; | |
char[] chars = clazz.toCharArray(); | |
for(int x = chars.length - 1; x >= 0; x--) { | |
if(chars[x] == '@' || (chars[x] == ';' && chars[x+1] == '@')) { | |
end = x; | |
isArray = (chars[x] == ';' && chars[x+1] == '@'); | |
} | |
if(end != -1 && chars[x] == '.') { | |
start = x+1; | |
break; | |
} | |
} | |
if(start == -1 || end == -1) { | |
return clazz; | |
} | |
String sequence = clazz.substring(start, end); | |
return (isArray ? sequence + "[]" : sequence); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package de.YonasCode.SweetUtils; | |
import de.YonasCode.SweetUtils.Debugger.Debugger; | |
import java.util.ArrayList; | |
import java.util.List; | |
public class Example { | |
public static void main(String[] args) { | |
new Example(); | |
} | |
public Example() { | |
List<String> names = Debugger.factory(List.class, new ArrayList<String>()); | |
names.add("Yonas"); | |
names.add("Susen"); | |
names.add("Mike"); | |
names.size(); | |
names.get(1); | |
names.toArray(null); | |
names.subList(0, 2); | |
names.listIterator(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
You can call the Debugger#factory() method. The first argument is the interface class and the second one the instance of a class that implements this class e.g.: | |
Debbuger.factory(List.class, new ArrayList<String>()); | |
-------------------------- | |
ArrayList#add(Yonas) | |
-> 11703ns | |
-> Called in Example#<init> (Example.java) at line 21 | |
-> (Boolean) true | |
ArrayList#add(Susen) | |
-> 4973ns | |
-> Called in Example#<init> (Example.java) at line 22 | |
-> (Boolean) true | |
ArrayList#add(Mike) | |
-> 4389ns | |
-> Called in Example#<init> (Example.java) at line 23 | |
-> (Boolean) true | |
ArrayList#size() | |
-> 5851ns | |
-> Called in Example#<init> (Example.java) at line 25 | |
-> (Integer) 3 | |
ArrayList#get(1) | |
-> 4682ns | |
-> Called in Example#<init> (Example.java) at line 27 | |
-> (String) Susen | |
ArrayList#toArray(null) | |
-> 65536ns | |
-> Called in Example#<init> (Example.java) at line 29 | |
-> (NullPointerException) null | |
ArrayList#subList(0, 2) | |
-> 129315ns | |
-> Called in Example#<init> (Example.java) at line 30 | |
-> (SubList) [Yonas, Susen] | |
ArrayList#listIterator() | |
-> 19017ns | |
-> Called in Example#<init> (Example.java) at line 31 | |
-> (ListItr) ArrayList$ListItr | |
-------------------------- | |
Above you can find one example. | |
--------------------------- | |
Note: Please keep in minde that I wrote this little helper while I fall asleep so don't expect too much... :D | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment