Java プログラムをデバッグする時に便利なトレース・ログ出力ライブラリの紹介

Java プログラムをデバッグする時に便利なトレース・ログ出力ライブラリ DebugTrace-java を紹介します。

Java 8 で使用できます。
(主に)メソッドの開始と終了箇所に DebugTrace.enter(), DebugTrace.leave() を埋め込む事で、開発中の Java  プログラムの実行状況をログで把握しやすくします。
特徴として以下があります。

1. メソッド・コールのネストに対応してログのインデントを行う
1. スレッドの切り替え時に自動的にログを出力する
1. リフレクションを使用して変数内容を出力可能
1. 出力量が多い変数の出力で自動改行を行う
1. ログにクラス名、メソッド名、行番号を自動出力
1. リソース・ファイルによるログ内容のカスタマイズが可能
1. コンソール出力 (stdout, stderr) または各種ログ・ライブラリを利用可能
    - java.util.logging
    - Log4j
    - Log4j 2
    - SLF4

### ダウンロード (GitHub)

下記から debugtrace-java-x.x.x-bin.zip をダウンロードします。jar ファイルや JavaDoc が同梱されています。
<a href="https://github.com/MasatoKokubo/DebugTrace/releases" target="github">https://github.com/MasatoKokubo/DebugTrace/releases</a>

### `build.gradle` での依存性の記述例

現時点で、登録されているリポジトリは JCenter のみです。

```gradle:build.gradle
repositories {
    jcenter()
}

dependencies {
    compile 'org.debugtrace:debugtrace:2.+'
}
```

### 基本的な使用方法

1. ログを出力したいメソッドの開始時と終了時に `DebugTrace.enter`, `DebugTrace.leave` を挿入する。
1. ログに内容を出力したい変数に対して `DebugTrace.print` を挿入する。

```java:Example
    public static void main(String[] args) {
        DebugTrace.enter();
        DebugTrace.print("args", args);
            ...
        DebugTrace.leave();
    }
```

### ロギング・ライブラリの指定

```DebugTrace.properties``` ファイルにロギング・ライブラリに対応するロガー・クラスを指定します。

```properties:DebugTrace.properties
# 以下のいずれかを指定
logger = Jdk
logger = Log4j
logger = Log4j2
logger = SLF4J
logger = Std$Out
logger = Std$Err
```
|クラス名|対応するロギング・ライブラリ|
|:--|:--|
|`Jdk`    |JDK ロガー|
|`Log4j`  |<a href="http://logging.apache.org/log4j/2.x/" target="apache">Log4j</a>|
|`Log4j2` |<a href="http://logging.apache.org/log4j/1.2/" target="apache">Log4j 2</a>|
|`SLF4J`  |<a href="http://www.slf4j.org/" target="slf4j">SLF4J</a>|
|`Std$Out`|コンソール / 標準出力 (デフォルト)|
|`Std$Err`|コンソール / 標準エラー出力|

`Std$Out`, `Std$Err`以外を使用する場合は、各ロギング・ライブラリ用の設定ファイルも必要です。

##### `logging.properties` (JDK ロガー) の例

```properties:logging.properties
handlers = java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.SimpleFormatter.format = [Jdk] %1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%1$tL %5$s%n
java.util.logging.ConsoleHandler.level = FINEST
org.debugtrace.DebugTrace.level = FINEST
```
*Java 起動時オプションとして `-Djava.util.logging.config.file=<プロパティの格納フォルダ・パス>/logging.properties` が必要*

##### `log4j.xml` (Log4j) の例

```xml:log4j.xml
<?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="Console" class="org.apache.log4j.ConsoleAppender">
    <param name="Target" value="System.out"/>
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="[Log4j] %d{yyyy-MM-dd HH:mm:ss.SSS} %5p %m%n"/>
    </layout>
  </appender>
  <logger name="org.debugtrace.DebugTrace">
    <level value ="trace"/>
    <appender-ref ref="Console"/>
  </logger>
</log4j:configuration>
```

##### `log4j2.xml` (Log4j 2) の例

```xml:log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="WARN">
  <appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="[Log4j2] %d{yyyy-MM-dd HH:mm:ss.SSS} %5p %msg%n"/>
    </Console>
  </appenders>
  <loggers>
    <logger name="org.debugtrace.DebugTrace" level="trace"/>
    <root level="error"><appender-ref ref="Console"/></root>
  </loggers>
</configuration>
```

##### `logback.xml` (SLF4J / Logback) の例

```xml:logback.xml
<configuration>
  <appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>[SLF4J logback] %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %msg%n</pattern>
    </encoder>
  </appender>
  <logger name="org.debugtrace.DebugTrace" level="trace"/>
  <root level="error"><appender-ref ref="Console"/></root>
</configuration>
```

### デフォルト・パッケージの指定 *(v2.3.0~)*

開発している Java プログラムのベース・パッケージを指定する事でログに出力されるクラス名が簡潔になります。
```DebugTrace.properties``` ファイルに指定します。

```properties:DebugTrace.properties
defaultPackage = org.debugtrace.
```

**defaultPackage を指定していない場合:**
```2016-11-13 12:44:19.456 Enter org.debugtrace.example.Example2.main (Example2.java:12)
2016-11-13 12:44:19.476 Leave org.debugtrace.example.Example2.main (Example2.java:17)```

**defaultPackage を指定した場合:**
```2016-11-13 12:44:19.456 Enter ...example.Example2.main (Example2.java:12)
2016-11-13 12:44:19.476 Leave ...example.Example2.main (Example2.java:17)```

### 出力しないプロパティの指定 *(v2.2.0~)*

DebugTrace-java は、出力対象のクラスで toString メソッドが未実装の場合に、リフレクションを使用して変数内容を出力します。オブジェクトに循環参照があると無限ループに陥ってしまうため、循環参照を検出した場合は、値として `*** cyclic reference ***` を出力します。
循環参照にはならなくても単に他のオブジェクトの参照である場合は、明示的に出力しないプロパティを指定する事ができます。

```properties:DebugTrace.properties
nonPrintProperties.0 = org.debugtrace.example.entity.Phone#contact
nonPrintProperties.1 = org.debugtrace.example.entity.Address#contact
...
```

### 出力するログ文字列および複数要素の上限値のカスタマイズ

[https://github.com/MasatoKokubo/DebugTrace-java/blob/master/README_ja.md](https://github.com/MasatoKokubo/DebugTrace-java//blob/master/README_ja.md) の「DebugTrace.properties ファイルのプロパティ一覧」を参照してください。