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

       Copyright ${license.git.copyrightYears} the original author or authors.

       Licensed under the Apache License, Version 2.0 (the "License");
       you may not use this file except in compliance with the License.
       You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

       Unless required by applicable law or agreed to in writing, software
       distributed under the License is distributed on an "AS IS" BASIS,
       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       See the License for the specific language governing permissions and
       limitations under the License.

-->
<document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">

  <properties>
    <title>MyBatis 3 | Logging</title>
    <author email="clinton.begin@gmail.com">Clinton Begin</author>
  </properties>

  <body>
    <section name="Logging">
      <p></p>
      <p>MyBatis provides logging information through the use of an
        internal log factory. The internal log factory will delegate logging
        information to one of the following log implementations:
      </p>
      <ul>
        <li>
          SLF4J
        </li>
        <li>
          Apache Commons Logging
        </li>
        <li>
          Log4j 2
        </li>
        <li>
          Log4j
        </li>
        <li>
          JDK logging
        </li>
      </ul>
      <p>The logging solution chosen is based on runtime introspection by
        the internal MyBatis log factory. The MyBatis log factory will use
        the first logging implementation it finds (implementations are
        searched in the above order). If MyBatis finds none of the above
        implementations, then logging will be disabled.
      </p>
      <p>Many environments ship Commons Logging as a part of the application server
        classpath (good examples include Tomcat and WebSphere). It is
        important to know that in such environments, MyBatis will use Commons Logging as
        the logging implementation. In an environment like WebSphere this
        will mean that your Log4J configuration will be ignored because
        WebSphere supplies its own proprietary implementation of Commons Logging. This
        can be very frustrating because it will appear that MyBatis is
        ignoring your Log4J configuration (in fact, MyBatis is ignoring your
        Log4J configuration because MyBatis will use Commons Logging in such
        environments). If your application is running in an environment
        where Commons Logging is included in the classpath but you would
        rather use one of the other logging implementations you can select a
        different logging implementation by adding a setting in mybatis-config.xml file as follows:
      </p>
      <source><![CDATA[<configuration>
  <settings>
    ...
    <setting name="logImpl" value="LOG4J"/>
    ...
  </settings>
</configuration>]]>
      </source>
      <p>Valid values are SLF4J, LOG4J, LOG4J2, JDK_LOGGING, COMMONS_LOGGING, STDOUT_LOGGING, NO_LOGGING or
      a full qualified class name that implements <code>org.apache.ibatis.logging.Log</code> and gets
      an string as a constructor parameter.
      </p>
      <p>You can also select the implementation by calling one of the following methods:
      </p>
      <source><![CDATA[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();]]></source>
      <p>If you choose to call one of these methods, you should do so
        before calling any other MyBatis method. Also, these methods
        will only switch to the requested log implementation if that
        implementation is available on the runtime classpath. For example, if
        you try to select Log4J logging and Log4J is not available at runtime,
        then MyBatis will ignore the request to use Log4J and will use it's
        normal algorithm for discovering logging implementations.
      </p>
      <p>The specifics of SLF4J, Apache Commons Logging, Apache Log4J and the JDK
        Logging API are beyond the scope of this document. However the
        example configuration below should get you started. If you would like
        to know more about these frameworks, you can get more information from
        the following locations:
      </p>
      <ul>
        <li>
          <a href="http://www.slf4j.org/">SLF4J</a>
        </li>
        <li>
          <a href="http://commons.apache.org/logging">Apache Commons Logging</a>
        </li>
        <li>
          <a href="http://logging.apache.org/log4j/">Apache Log4j 1.x and 2.x</a>
        </li>
        <li>
          <a href="http://java.sun.com/j2se/1.4.1/docs/guide/util/logging/">JDK Logging API</a>
        </li>
      </ul>
      <subsection name="Logging Configuration">
        <p>To see MyBatis logging statements you may enable logging on a
          package, a mapper fully qualified class name, a namespace
          o a fully qualified statement name.
        </p>
        <p>Again, how you do this is dependent on the logging implementation
          in use. We'll show how to do it with Log4J. Configuring the
          logging services is simply a matter of including one or more extra
          configuration files (e.g. log4j.properties) and sometimes a new JAR
          file (e.g. log4j.jar). The following example configuration will
          configure full logging services using Log4J as a provider. There
          are 2 steps.
        </p>
        <p></p>
        <h4>
          Step 1: Add the Log4J JAR file
        </h4>
        <p>Because we are using Log4J, we will need to ensure its
          JAR file is available to our application. To use Log4J, you need to
          add the JAR file to your application classpath. You can download
          Log4J from the URL above.
        </p>
        <p>For web or enterprise applications you can add the <code>log4j.jar</code> to
          your <code>WEB-INF/lib</code> directory, or for a standalone application you can
          simply add it to the JVM <code>-classpath</code> startup parameter.
        </p>
        <p></p>
        <h4>
          Step 2: Configure Log4J
        </h4>
        <p>Configuring Log4J is simple. Suppose you want to enable the log for this mapper:
        </p>
        <source><![CDATA[package org.mybatis.example;
public interface BlogMapper {
  @Select("SELECT * FROM blog WHERE id = #{id}")
  Blog selectBlog(int id);
}]]></source>
        <p>Create a file called <code>log4j.properties</code>
        as shown below and place it in your classpath:
        </p>
        <source><![CDATA[# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.org.mybatis.example.BlogMapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n]]></source>
        <p>
          The above file will cause log4J to report detailed logging for
          <code>org.mybatis.example.BlogMapper</code>
          and just errors for the rest of the classes of your application.
        </p>
        <p>
          If you want to tune the logging at a finer level you can turn logging
          on for specific statements instead of the whole mapper file.
          The following line will enable logging just for the <code>selectBlog</code>
          statement:
        </p>

        <source>log4j.logger.org.mybatis.example.BlogMapper.selectBlog=TRACE</source>

        <p>By the contrary you may want want to enable logging for a group of mappers.
        In that case you should add as a logger the root package where your mappers reside:</p>

        <source>log4j.logger.org.mybatis.example=TRACE</source>

        <p>There are queries that can return huge result sets. In that cases you may want to see the
        SQL statement but not the results. For that purpose SQL statements are logged at the DEBUG level
        (FINE in JDK logging) and results at the TRACE level (FINER in JDK logging), so in case
        you want to see the statement but not the result, set the level to DEBUG.
        </p>

        <source>log4j.logger.org.mybatis.example=DEBUG</source>

        <p>But what about if you are not using mapper interfaces but mapper XML files like this one?
        </p>

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

		<p>In that case you can enable logging for the whole XML file by adding
		a logger for the namespace as shown below:</p>

        <source>log4j.logger.org.mybatis.example.BlogMapper=TRACE</source>

		<p>Or for an specific statement:</p>

        <source>log4j.logger.org.mybatis.example.BlogMapper.selectBlog=TRACE</source>

		<p>Yes, as you may have noticed, there is no difference in configuring
		logging for mapper interfaces or for XML mapper files.</p>

        <p><span class="label important">NOTE</span> If you are using SLF4J or Log4j 2 MyBatis will call it using the marker MYBATIS.</p>

        <p>The remaining configuration in the <code>log4j.properties</code> file is used
          to configure the appenders, which is beyond the scope of this
          document. However, you can find more information at the Log4J
          website (URL above). Or, you could simply experiment with it to see
          what effects the different configuration options have.
        </p>

      </subsection>
    </section>
  </body>
</document>
