ログ出力

MyBatisは、内部ログファクトリを使用してログ情報を提供します。内部ログファクトリは、以下のログ実装のいずれかにログ情報を委譲します。

  • SLF4J
  • Apache Commons Logging
  • Log4j 2
  • Log4j(3.5.9以降非推奨)
  • JDKロギング

選択されるロギングソリューションは、内部MyBatisログファクトリによるランタイムイントロスペクションに基づきます。MyBatisログファクトリは、最初に検出されたロギング実装を使用します(実装は上記の順序で検索されます)。MyBatisが上記のいずれの実装も検出しない場合、ログ出力は無効になります。

多くの環境では、Commons Loggingがアプリケーションサーバのクラスパスの一部として提供されています(TomcatやWebSphereなどが良い例です)。このような環境では、MyBatisはCommons Loggingをログ実装として使用することを知っておくことが重要です。WebSphereのような環境では、これはWebSphereが独自のCommons Logging実装を提供するため、Log4Jの設定が無視されることを意味します。これは非常にイライラする可能性があります。MyBatisがLog4Jの設定を無視しているように見えるからです(実際、MyBatisは、このような環境ではCommons Loggingを使用するため、Log4Jの設定を無視しています)。アプリケーションがCommons Loggingがクラスパスに含まれている環境で実行されているが、他のログ実装を使用したい場合は、次のように`mybatis-config.xml`ファイルに設定を追加して、異なるログ実装を選択できます。

<configuration>
  <settings>
    ...
    <setting name="logImpl" value="LOG4J"/>
    ...
  </settings>
</configuration>

有効な値は、SLF4J、LOG4J、LOG4J2、JDK_LOGGING、COMMONS_LOGGING、STDOUT_LOGGING、NO_LOGGING、または`org.apache.ibatis.logging.Log`を実装し、コンストラクタパラメータとして文字列を受け取る完全修飾クラス名です。

次のメソッドのいずれかを呼び出すことによっても、実装を選択できます。

org.apache.ibatis.logging.LogFactory.useSlf4jLogging();
org.apache.ibatis.logging.LogFactory.useLog4JLogging();
org.apache.ibatis.logging.LogFactory.useLog4J2Logging();
org.apache.ibatis.logging.LogFactory.useJdkLogging();
org.apache.ibatis.logging.LogFactory.useCommonsLogging();
org.apache.ibatis.logging.LogFactory.useStdOutLogging();

これらのメソッドのいずれかを選択する場合は、他のMyBatisメソッドを呼び出す前に実行する必要があります。また、これらのメソッドは、要求されたログ実装がランタイムクラスパスで使用可能な場合にのみ、要求されたログ実装に切り替えます。たとえば、Log4J2ロギングを選択しようとしており、Log4J2がランタイムで使用できない場合、MyBatisはLog4J2を使用する要求を無視し、ログ実装の検出のための通常のアルゴリズムを使用します。

SLF4J、Apache Commons Logging、Apache Log4J、およびJDK Logging APIの詳細は、このドキュメントの範囲外です。ただし、以下の例の設定は開始するのに役立ちます。これらのフレームワークの詳細を知りたい場合は、以下の場所から詳細情報を入手できます。

ログ出力の設定

MyBatisのログステートメントを表示するには、パッケージ、Mapperの完全修飾クラス名、名前空間、または完全修飾ステートメント名でログ出力を有効にすることができます。

これも、使用しているログ実装によって異なります。SLF4J(Logback)を使用して実行する方法を示します。ロギングサービスの設定は、1つ以上の追加設定ファイル(例:`logback.xml`)と、場合によっては新しいJARファイルを含めるだけです。次の設定例では、SLF4J(Logback)をプロバイダとして使用して、完全なロギングサービスを設定します。2つのステップがあります。

ステップ1:SLF4J + Logback JARファイルの追加

SLF4J(Logback)を使用しているので、そのJARファイルがアプリケーションで使用可能になっていることを確認する必要があります。SLF4J(Logback)を使用するには、JARファイルをアプリケーションのクラスパスに追加する必要があります。

Webアプリケーションまたはエンタープライズアプリケーションの場合、`logback-classic.jar`、`logback-core.jar`、および`slf4j-api.jar`を`WEB-INF/lib`ディレクトリに追加するか、スタンドアロンアプリケーションの場合は、JVMの`-classpath`スタートアップパラメータに単純に追加できます。

Mavenを使用する場合は、`pom.xml`に次の設定を追加することでJARファイルをダウンロードできます。

<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>1.x.x</version>
</dependency>

ステップ2:Logbackの設定

Logbackの設定は簡単です。このMapperのログを有効にしたいとします。

package org.mybatis.example;
public interface BlogMapper {
  @Select("SELECT * FROM blog WHERE id = #{id}")
  Blog selectBlog(int id);
}

以下に示すように`logback.xml`というファイルを作成し、クラスパスに配置します。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>

  <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%5level [%thread] - %msg%n</pattern>
    </encoder>
  </appender>

  <logger name="org.mybatis.example.BlogMapper">
    <level value="trace"/>
  </logger>
  <root level="error">
    <appender-ref ref="stdout"/>
  </root>

</configuration>

上記のファイルにより、SLF4J(Logback)は`org.mybatis.example.BlogMapper`の詳細なログ出力を報告し、アプリケーションの他のクラスについてはエラーのみを報告します。

より細かいレベルでログ出力を調整したい場合は、Mapperファイル全体ではなく、特定のステートメントに対してログ出力を有効にすることができます。次の行は、`selectBlog`ステートメントのみのログ出力を有効にします。

<logger name="org.mybatis.example.BlogMapper.selectBlog">
  <level value="trace"/>
</logger>

逆に、Mapperのグループのログ出力を有効にしたい場合があります。その場合は、Mapperが存在するルートパッケージをロガーとして追加する必要があります。

<logger name="org.mybatis.example">
  <level value="trace"/>
</logger>

非常に大きな結果セットを返すクエリがあります。そのような場合、結果は表示せずにSQLステートメントを確認したい場合があります。その目的のために、SQLステートメントはDEBUGレベル(JDKロギングではFINE)で、結果はTRACEレベル(JDKロギングではFINER)でログ出力されるため、ステートメントを表示して結果を表示しない場合は、レベルをDEBUGに設定します。

<logger name="org.mybatis.example">
  <level value="debug"/>
</logger>

しかし、このようなMapperインターフェースではなく、Mapper XMLファイルを使用している場合はどうでしょうか?

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.dokyumento.jp//DTD Mapper 3.0//EN"
  "https://mybatis.dokyumento.jp/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.mybatis.example.BlogMapper">
  <select id="selectBlog" resultType="Blog">
    select * from Blog where id = #{id}
  </select>
</mapper>

その場合、以下に示すように、名前空間のロガーを追加することで、XMLファイル全体のログ出力を有効にできます。

<logger name="org.mybatis.example.BlogMapper">
  <level value="trace"/>
</logger>

または、特定のステートメントの場合

<logger name="org.mybatis.example.BlogMapper.selectBlog">
  <level value="trace"/>
</logger>

はい、お気づきかもしれませんが、MapperインターフェースまたはXML Mapperファイルのログ出力の設定に違いはありません。

注記 SLF4JまたはLog4j 2を使用している場合、MyBatisはマーカー`MYBATIS`を使用して呼び出します。

`logback.xml`ファイルの残りの設定は、アペンダーの設定に使用されますが、これはこのドキュメントの範囲外です。ただし、LogbackのWebサイトで詳細情報を見つけることができます。または、さまざまな設定オプションがどのような影響を与えるかを確認するために、単純に実験することもできます。

Log4j 2の設定例

<!-- pom.xml -->
<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-core</artifactId>
  <version>2.x.x</version>
</dependency>
<!-- log4j2.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<Configuration xmlns="http://logging.apache.org/log4j/2.0/config">

  <Appenders>
    <Console name="stdout" target="SYSTEM_OUT">
      <PatternLayout pattern="%5level [%t] - %msg%n"/>
    </Console>
  </Appenders>

  <Loggers>
    <Logger name="org.mybatis.example.BlogMapper" level="trace"/>
    <Root level="error" >
      <AppenderRef ref="stdout"/>
    </Root>
  </Loggers>

</Configuration>

Log4jの設定例

<!-- pom.xml -->
<dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.2.17</version>
</dependency>
# log4j.properties
log4j.rootLogger=ERROR, stdout

log4j.logger.org.mybatis.example.BlogMapper=TRACE

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

JDKロギングの設定例

# logging.properties
handlers=java.util.logging.ConsoleHandler
.level=SEVERE

org.mybatis.example.BlogMapper=FINER

java.util.logging.ConsoleHandler.level=ALL
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.SimpleFormatter.format=%1$tT.%1$tL %4$s %3$s - %5$s%6$s%n