DebugTrace-java is a library that outputs trace logs when debugging Java programs.
By embedding DebugTrace.enter()
and DebugTrace.leave()
at the start and end of methods,
you can output the execution status of the Java program under development to the log.
DebugTrace-java version | Java version to support |
---|---|
DebugTrace-java 4.x.x |
Java 17 and later |
DebugTrace-java 3.x.x |
Java 8 and later |
-
Automatically outputs invoker’s class name, method name, source file and line number.
-
Automatically indents the log with nesting methods and objects.
-
Automatically output logs when changing threads.
-
Uses reflection to output the contents of classes that do not implement the
toString
method. -
You can customize the output content in
DebugTrace.properties
. -
There are no dependent libraries at run time. (Required if you use the following logging library)
-
You can use the following logging library.
-
Console (stdout and stderr)
-
Direct file output
-
Insert the following for the debuggee and related methods.
-
DebugTrace.enter();
-
DebugTrace.leave();
-
DebugTrace.print("value", value);
public void foo() { DebugTrace.enter(); // TODO: Remove after debugging ... DebugTrace.print("value", value); // TODO: Remove after debugging ... DebugTrace.leave(); // TODO: Remove after debugging }
public void foo() { try {DebugTrace.enter(); // TODO: Remove after debugging ... DebugTrace.print("value", value); // TODO: Remove after debugging ... if (...) return; ... } finally {DebugTrace.leave();} // TODO: Remove after debugging }
public void foo() throws Exception { try {DebugTrace.enter(); // TODO: Remove after debugging ... DebugTrace.print("value", value); // TODO: Remove after debugging ... if (...) throw new Exception(); ... } catch (Exception e) {DebugTrace.print("e", e); throw e; // TODO: Remove after debugging } finally {DebugTrace.leave();} // TODO: Remove after debugging }
The following is an example of Java source used DebugTrace-java methods and the log of when it has been executed.
package example;
import java.util.HashMap;
import java.util.Map;
import org.debugtrace.DebugTrace;
public class Example1 {
private static final Map<Long, Long> fibonacciMap = new HashMap<>();
static {
fibonacciMap.put(0L, 0L);
fibonacciMap.put(1L, 1L);
}
public static void main(String[] args) {
DebugTrace.enter(); // TODO: Remove after debugging
try {
if (args.length <= 0)
throw new IllegalArgumentException("args.length = " + args.length);
long n = Long.parseLong(args[0]);
long fibonacci = fibonacci(n);
System.out.println("fibonacci(" + n + ") = " + fibonacci);
} catch (Exception e) {
DebugTrace.print("e", e); // TODO: Remove after debugging
}
DebugTrace.leave(); // TODO: Remove after debugging
}
public static long fibonacci(long n) {
DebugTrace.enter(); // TODO: Remove after debugging
if (n < 0)
throw new IllegalArgumentException("n (" + n + ") is negative.");
long fibonacci = 0;
if (fibonacciMap.containsKey(n)) {
fibonacci = fibonacciMap.get(n);
DebugTrace.print("mapped fibonacci(" + n + ")", fibonacci); // TODO: Remove after debugging
} else {
fibonacci = fibonacci(n - 2) + fibonacci(n - 1);
DebugTrace.print("fibonacci(" + n + ")", fibonacci); // TODO: Remove after debugging
if (fibonacci < 0)
throw new RuntimeException("Overflow occurred in fibonacci(" + n + ") calculation.");
fibonacciMap.put(n, fibonacci);
}
DebugTrace.leave(); // TODO: Remove after debugging
return fibonacci;
}
}
2023-04-16 08:03:10.363+09:00 DebugTrace 4.0.0 on Amazon.com Inc. OpenJDK Runtime Environment 17.0.6+10-LTS 2023-04-16 08:03:10.363+09:00 property name: DebugTrace.properties 2023-04-16 08:03:10.363+09:00 logger: org.debugtrace.logger.Std$Err 2023-04-16 08:03:10.385+09:00 2023-04-16 08:03:10.388+09:00 ______________________________ main ______________________________ 2023-04-16 08:03:10.388+09:00 2023-04-16 08:03:10.388+09:00 Enter example.Example1.main (Example1.java:18) <- (:0) 2023-04-16 08:03:10.389+09:00 | Enter example.Example1.fibonacci (Example1.java:32) <- (Example1.java:23) 2023-04-16 08:03:10.389+09:00 | | Enter example.Example1.fibonacci (Example1.java:32) <- (Example1.java:40) 2023-04-16 08:03:10.432+09:00 | | | mapped fibonacci(1) = (long)1 (Example1.java:38) 2023-04-16 08:03:10.434+09:00 | | Leave example.Example1.fibonacci (Example1.java:46) duration: 00:00:00.044 2023-04-16 08:03:10.434+09:00 | | 2023-04-16 08:03:10.434+09:00 | | Enter example.Example1.fibonacci (Example1.java:32) <- (Example1.java:40) 2023-04-16 08:03:10.434+09:00 | | | Enter example.Example1.fibonacci (Example1.java:32) <- (Example1.java:40) 2023-04-16 08:03:10.434+09:00 | | | | mapped fibonacci(0) = (long)0 (Example1.java:38) 2023-04-16 08:03:10.436+09:00 | | | Leave example.Example1.fibonacci (Example1.java:46) duration: 00:00:00.000 2023-04-16 08:03:10.436+09:00 | | | 2023-04-16 08:03:10.436+09:00 | | | Enter example.Example1.fibonacci (Example1.java:32) <- (Example1.java:40) 2023-04-16 08:03:10.436+09:00 | | | | mapped fibonacci(1) = (long)1 (Example1.java:38) 2023-04-16 08:03:10.436+09:00 | | | Leave example.Example1.fibonacci (Example1.java:46) duration: 00:00:00.000 2023-04-16 08:03:10.436+09:00 | | | fibonacci(2) = (long)1 (Example1.java:41) 2023-04-16 08:03:10.436+09:00 | | Leave example.Example1.fibonacci (Example1.java:46) duration: 00:00:00.001 2023-04-16 08:03:10.436+09:00 | | fibonacci(3) = (long)2 (Example1.java:41) 2023-04-16 08:03:10.437+09:00 | Leave example.Example1.fibonacci (Example1.java:46) duration: 00:00:00.047 fibonacci(3) = 2 2023-04-16 08:03:10.437+09:00 Leave example.Example1.main (Example1.java:28) duration: 00:00:00.048
This library has the following methods. These are all static methods of org.debugtrace.DebugTrace
class.
Method Name | Arguments | Return Value | Description |
---|---|---|---|
|
None |
None |
Outputs method start to log. |
|
None |
None |
Outputs method end to log. |
|
|
the |
Outputs the message to log. |
|
|
tht message getted from the messageSupplier |
Gets a message from the supplier and output it to log. |
|
|
the |
Outputs to the log in the form of |
|
|
the |
Same as above. |
|
|
the value getted from the |
Gets a value from the |
|
|
the value getted from the |
Same as above. |
|
|
None |
Outputs a list of StackTraceElements to the log. |
DebugTrace read DebugTrace.properties
file in the classpath on startup.
You can specify following properties in the DebugTrace.properties
file.
Property Name | Description | Default Value (Value Examples) |
---|---|---|
|
Logger used by DebugTrace |
|
|
The format string of logging when entering methods |
|
|
The format string of logging when leaving methods |
|
|
The format string of logging at threads boundary |
|
|
The format string of logging at classes boundary |
|
|
The indentation string for code |
|
|
The indentation string for data |
|
|
The string to represent that it has exceeded the limit |
|
|
The string to be output instead of not outputting value |
|
|
The string to represent that the cyclic reference occurs |
|
|
The separator string between the variable name and value |
|
|
The separator string between the key and value of Map object |
|
|
The format string of |
|
|
The format string of the size of collection and map |
|
|
The minimum value to output the number of elements of array, collection and map |
|
|
The format string of the length of string |
|
|
The minimum value to output the length of string |
|
|
The format string of |
|
|
The format string of |
|
|
The format string of |
|
|
The format string of |
|
|
The format string of |
|
|
The format string of |
|
|
The format string of |
|
|
The format string of |
|
|
The format string of |
|
|
The format string of |
|
|
The format string of |
|
|
The format string of the date and time of the log when the logger is |
|
|
The maximum output width of data |
70 |
|
The limit value of elements for collection and map to output |
128 |
|
The limit value of elements for byte array ( |
256 |
|
The limit value of characters for string to output |
256 |
|
The limit value for reflection nesting |
4 |
|
Properties not to be output |
Nome |
|
The default package of your java source |
Nome |
|
The string replacing the default package part |
|
|
Classe names that output content by reflection even if |
Nome |
|
The map for obtaining map name corresponding to variable name |
Nome |
|
The map of numbers (as key) and constant names (as value) corresponding to the numbers |
Predefined constant name maps: |
Specify the date and time format in the format of the argument of the DateTimeFormatter.ofPattern
method.
DebugTrace use reflection to output object contents if the toString
method is not implemented.
If there are other object references, the contents of objects are also output.
However, if there is circular reference, it will automatically detect and suspend output.
You can suppress output by specifying the nonOutputProperties
property and
can specify multiple values of this property separated by commas.
The value of the property specified by nonOutputProperties
are output as the string specified by nonOutputString
(default: ***
).
nonOutputProperties = \ org.lightsleep.helper.EntityInfo#columnInfos,\ org.lightsleep.helper.EntityInfo#keyColumnInfos,\ org.lightsleep.helper.ColumnInfo#entityInfo
A constant map is a map whose keys are numbers and whose values are constant names.
If you specify the map name corresponding to the variable name in the mapNameMap
property, the constant name corresponding to the numerical value will also be output.
mapNameMap
in DebugTrace.propertiesAppleBrand = \ 0: Apple.NO_BRAND,\ 1: Apple.AKANE,\ 2: Apple.AKIYO,\ 3: Apple.AZUSA,\ 4: Apple.YUKARI mapNameMap = appleBrand:AppleBrand
static public class Apple {
public static final int NO_BRAND = 0;
public static final int AKANE = 1;
public static final int AKIYO = 2;
public static final int AZUSA = 3;
public static final int YUKARI = 4;
}
...
int appleBrand = Apple.AKANE;
DebugTrace.print("appleBrand", appleBrand);
appleBrand = Apple.AKIYO;
DebugTrace.print(" 2 appleBrand ", appleBrand);
appleBrand = Apple.AZUSA;
DebugTrace.print(" 3 example.appleBrand ", appleBrand);
appleBrand = Apple.YUKARI;
DebugTrace.print(" 4 example. appleBrand ", appleBrand);
2023-01-29 10:14:29.916+09:00 appleBrand = 1(Apple.AKANE) (ReadmeExample.java:18) 2023-01-29 10:14:29.916+09:00 2 appleBrand = 2(Apple.AKIYO) (ReadmeExample.java:20) 2023-01-29 10:14:29.916+09:00 3 example.appleBrand = 3(Apple.AZUSA) (ReadmeExample.java:22) 2023-01-29 10:14:29.916+09:00 4 example. appleBrand = 4(Apple.YUKARI) (ReadmeExample.java:24)
The logger name of DebugTrace is org.debugtrace.DebugTrace
.
# logging.properties handlers = java.util.logging.FileHandler java.util.logging.FileHandler.level = FINEST java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter java.util.logging.SimpleFormatter.format = %1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%1$tL %5$s%n java.util.logging.FileHandler.encoding = UTF-8 java.util.logging.FileHandler.pattern = /var/log/app/debugtrace.log java.util.logging.FileHandler.append = false org.debugtrace.DebugTrace.level = FINEST
-Djava.util.logging.config.file=<path>/logging.properties
is required as Java startup option
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
<appender name="traceAppender" class="org.apache.log4j.FileAppender">
<param name="File" value="/var/log/app/debugtrace.log"/>
<param name="Append" value="false" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p %t %m%n"/>
</layout>
</appender>
<logger name="org.debugtrace.DebugTrace">
<level value ="trace"/>
<appender-ref ref="traceAppender"/>
</logger>
</log4j:configuration>
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<File name="traceAppender" append="false" fileName="/var/log/app/debugtrace.log">
<PatternLayout pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level %thread %message%n"/>
</File>
</Appenders>
<Loggers>
<Logger name="org.debugtrace.DebugTrace" level="trace" additivity="false">
<AppenderRef ref="traceAppender"/>
</Logger>
</Loggers>
</Configuration>
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="traceAppender" class="ch.qos.logback.core.FileAppender">
<file>/var/log/app/debugtrace.log</file>
<encoder>
<pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level %thread %message%n</pattern>
</encoder>
</appender>
<logger name="org.debugtrace.DebugTrace" level="trace">
<appender-ref ref="traceAppender"/>
</logger>
</configuration>
repositories {
mavenCentral()
}
dependencies {
compile 'org.debugtrace:debugtrace:3.6.0'
}