第10章 JMXコンフィギュレーター

名前のとおり、JMXConfiguratorを使うとJMX経由でlogbackを設定することができます。つまり、デフォルトの設定ファイルで設定されたlogbackを、指定したパスやURLに配置した設定ファイルの内容で再設定したり、ロガーの一覧を取得したり、ロガーのレベルを変更することができるのです。

JMXコンフィギュレーターを使用する

サーバーを実行しているJVMがJDK1.6以降なら、コマンドラインからjconsoleコマンドを実行するだけで、実行中のサーバーのMBeanServerにアクセスすることができます。古いJVMで実行している場合はサーバーでJMXを有効化するのセクションを読んでおいてください。

次のように設定ファイルに1行追加するだけでJMXConfiguratorが有効になります。

<configuration>
  <jmxConfigurator />
  
  <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
    <layout class="ch.qos.logback.classic.PatternLayout">
      <Pattern>%date [%thread] %-5level %logger{25} - %msg%n</Pattern>
    </layout>
  </appender>

  <root level="debug">
    <appender-ref ref="console" />
  </root>  
</configuration>

jconsoleでサーバーに接続すれば、MBeans タブに表示される "ch.qos.logback.classic.jmx.Configurator" フォルダの下にいろいろなコマンドがぶら下がっているのが確認できます。スクリーンショットを見てください。

jconsoleJMXConfiguratorを表示している様子

jmxConfigurator

次のような操作を実行することができます。

JMXConfiguratorはAttributesとして存在しているロガーの一覧と、ステータスの一覧を公開します。

ステータスの一覧は、logbackの内部状態を診断するのに役立ちます。

statusList.gif

メモリリークを避ける

アプリケーションがWebサーバーやアプリケーションサーバにデプロイされているときは、JMXConfiguratorのインスタンスをJVMのMBeanサーバーに登録すると、システムクラスローダーの参照をアプリケーションが持つようになってしまいます。これはアプリケーションが停止したり再デプロイされたときにJMXConfiguratorがガベージコレクションされてしまうのを防ぐためですが、そのせいで深刻なメモリリークが生じてしまいます。

したがって、スタンドアローンなJavaアプリケーションではないときは、必ずJMXConfiguratorのインスタンスの登録をJVMのMBeanサーバーから解除しなければなりません。適切なLoggerContetextreset()メソッドを呼べば、すべてのJMXConfiguratorのインスタンスは自動的に解除されるはずです。ロガーコンテキストを初期化するなら、javax.servlet.ServletContextListenercontextDestroyed()メソッドがちょうど良い場所です。サンプルコードを見てみましょう。

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.LoggerContext;

public class MyContextListener implements ServletContextListener {

  public void contextDestroyed(ServletContextEvent sce) {
    LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
    lc.stop();
  }

  public void contextInitialized(ServletContextEvent sce) {
  }
} 

複数のWebアプリケーションでJMXConfiguratorを使用する

複数のアプリケーションを同じサーバーにデプロイしている、コンテキストセレクタを上書きせずデフォルトのまま使っている、それぞれのアプリケーションのWEB-INF/libフォルダにlogback-*.jarslf4j-api.jarを置いている、これらが全て当てはまるなら、それぞれのアプリケーションのJMXConfiguratorのインスタンスは同じ名前("ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator")で登録されてしまうでしょう。言い換えると、何もしなければそれぞれのアプリケーションのロガーコンテキストに関連付けられたJMXConfiguratorのインスタンスは衝突してしまうのです。

衝突を避けるには、単にアプリケーションのロガーコンテキストに名前を付けるだけでよいのです。そうすれば、JMXConfiguratorには自動的にその名前が設定されます。

たとえば、それぞれ"コアラ"と"コウモリ"という名前のアプリケーションをデプロイしているものとします。そして、コアラのlogback.xmlには次のような設定がされているとしましょう。

<configuration>
  <contextName>Koala</contextName>
  <jmxConfigurator/>
  ...
<configuration>

また、コウモリのlogback.xmlには次のように設定がされていることにします。

<configuration>
  <contextName>Wombat</contextName>x
  <jmxConfigurator/>
  ...
<configuration>

そうすると、jconsoleのMBeanタブには、次のように二つの独立したJMXConfiguratorのインスタンスが表示されるはずです。

multiple.gif

MBeanサーバーに登録されるJMXConfiguratorの名前は、jmxConfigurator要素の"objectName"属性で指定することができます。

JMXを有効化する

JDK1.6以降のJVMでサーバーを実行している場合はデフォルトでJMXが有効になっています。

JDK1.6以前の古いJVMを使っている場合は、サーバーのJMX関連のドキュメントを確認することをおすすめします。たとえばTomcatJettyにはドキュメントがあります。それはさておき、このドキュメントではTomcatとJettyの設定方法を簡単に説明していきます。

JettyでJMXを有効にする(JDK 1.5およびJDK 1.6で動作確認済み)

以降の設定はJDK1.5とJDK1.6で動作確認しています。JDK1.6以降のJVMでは、デフォルトでJMXが有効になっています。以降の設定をしてもよいですが、特に何も変わりません。JDK1.5のJVMで実行するJettyでJMXを有効にするには、設定ファイル$JETTY_HOME/etc/jetty.xmlにいくつか設定を追加する必要があります。追加するのは次の設定です。

<Call id="MBeanServer" class="java.lang.management.ManagementFactory" 
      name="getPlatformMBeanServer"/>

<Get id="Container" name="container">
  <Call name="addEventListener">
    <Arg>
      <New class="org.mortbay.management.MBeanContainer">
        <Arg><Ref id="MBeanServer"/></Arg>
        <Call name="start" />
      </New>
    </Arg>
  </Call>
</Get> 

Jettyの公開するMBeanにjconsoleでアクセスしたいときは、Jettyを実行するJVMにシステムプロパティ"com.sun.management.jmxremote"を指定しておかなければなりません。

スタンドアローン版のJettyなら次のように実行します。

java -Dcom.sun.management.jmxremote -jar start.jar [config files]

MavenのプラグインからJettyを実行する場合は、システムプロパティ"com.sun.management.jmxremote"をシェル変数MAVEN_OPTSで指定しなければなりません。

MAVEN_OPTS="-Dcom.sun.management.jmxremote" mvn jetty:run

そうすれば、jconsoleでJettyの公開するMBeanとしてJMXConfiguratorにアクセスすることができます。

jconsole15_jetty.gif

接続したら、前のスクリーンショットのようにJMXConfiguratorにアクセスできるはずです。

JettyにMX4Jを入れる(JDK 1.5およびJDK 1.6で動作確認済み)

MX4JのHTTPインターフェイスを経由してJMXConfiguratorにアクセスしたいときは、前に説明した設定ファイルに管理ポート番号の設定を追加します。MX4Jはすでにダウンロード済みであることにします。

<Call id="MBeanServer"
    class="java.lang.management.ManagementFactory"
    name="getPlatformMBeanServer"/>

<Get id="Container" name="container">
  <Call name="addEventListener">
    <Arg>
      <New class="org.mortbay.management.MBeanContainer">
        <Arg><Ref id="MBeanServer"/></Arg>
        <Set name="managementPort">8082</Set>
        <Call name="start" />
      </New>
    </Arg>
  </Call>
</Get> 
    

なお、mx4j-tools.jarはJettyのクラスパス上に配置しておいてください。

MavenのプラグインからJettyを実行する場合は、依存関係にmx4j-toolsを追加してください。

<plugin>
  <groupId>org.mortbay.jetty</groupId>
  <artifactId>maven-jetty-plugin</artifactId>
  <configuration>
    <jettyConfig>path/to/jetty.xml</jettyConfig>
    ...
  </configuration>
  <dependencies>
    <dependency>
      <groupId>mx4j</groupId>
      <artifactId>mx4j-tools</artifactId>
      <version>3.0.1</version>
    </dependency>
  </dependencies>
</plugin>

この設定でJettyを起動すると、ブラウザで次のURLからJMXConfiguratorにアクセスできるようになります。アクセスした後は "ch.qos.logback.classic" を探してください。

http://localhost:8082/

MX4Jにアクセスしているところのスクリーンショットです。

mx4j_jetty.gif

Tomcat用のJMXの設定(JDK 1.5およびJDK 1.6で動作確認済み)

JDK1.6以降のJVMを使用しているならJMXはデフォルトで有効になっているので以降の設定をする必要はありません。JDK1.5の場合は$TOMCAT_HOME/bin/catalina.sh(Windowsの場合はcatalina.bat)の適切な場所に次の設定を追加する必要があります。

CATALINA_OPTS="-Dcom.sun.management.jmxremote"

そうすれば、jconsoleを使ってTomcatの公開するMBeanとしてJMXConfiguratorにアクセスできるようになります。

jconsole15_tomcat.gif

接続したら、前のスクリーンショットのようにJMXConfiguratorにアクセスできるはずです。

TomcatにMX4Jを入れる(JDK 1.5およびJDK 1.6で動作確認済み)

MX4JのWebインターフェイスを使ってJMXのコンポーネントにアクセスしたくなるかもしれません。そうするために必要な設定方法を説明します。

MX4Jはすでにダウンロードしてあることにしましょう。mx4j-tools.jar$TOMCAT_HOME/binフォルダーにおいてください。それから、$TOMCAT_HOME/bin/catalina.sh(Windowsの場合はcatalina.bat)の適切な場所に次の設定を追加します。

<!-- at the beginning of the file --> CATALINA_OPTS="-Dcom.sun.management.jmxremote" <!-- in the "Add on extra jar files to CLASSPATH" section --> CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/bin/mx4j-tools.jar

最後に、$TOMCAT_HOME/conf/server.xmlで新しいConnector要素を宣言します。

<Connector port="0" 
  handler.list="mx"
  mx.enabled="true" 
  mx.httpHost="localhost" 
  mx.httpPort="8082" 
  protocol="AJP/1.3" />

Tomcatを起動したら、ブラウザで次のURLからJMXConfiguratorにアクセスできるようになります。アクセスした後は "ch.qos.logback.classic" を探してください。

http://localhost:8082/

MX4Jにアクセスしているところのスクリーンショットです。

mx4j_tomcat.gif