第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" フォルダの下にいろいろなコマンドがぶら下がっているのが確認できます。スクリーンショットを見てください。
jconsole
でJMXConfigurator
を表示している様子
次のような操作を実行することができます。
- デフォルトの設定ファイルを使用してlogbackを再設定します。
- URLに配置された設定ファイルを使用して再設定します。
- ファイルパスに配置された設定ファイルを使用して再設定します。
- 指定したロガーのレベルを設定します。nullを設定するには文字列"null"を指定します。
- 指定したロガーのレベルを取得します。nullになることがあります。
- 指定したロガーの有効レベルを取得します。
JMXConfigurator
はAttributesとして存在しているロガーの一覧と、ステータスの一覧を公開します。
ステータスの一覧は、logbackの内部状態を診断するのに役立ちます。
メモリリークを避ける
アプリケーションがWebサーバーやアプリケーションサーバにデプロイされているときは、JMXConfigurator
のインスタンスをJVMのMBeanサーバーに登録すると、システムクラスローダーの参照をアプリケーションが持つようになってしまいます。これはアプリケーションが停止したり再デプロイされたときにJMXConfiguratorがガベージコレクションされてしまうのを防ぐためですが、そのせいで深刻なメモリリークが生じてしまいます。
したがって、スタンドアローンなJavaアプリケーションではないときは、必ずJMXConfigurator
のインスタンスの登録をJVMのMBeanサーバーから解除しなければなりません。適切なLoggerContetext
のreset()
メソッドを呼べば、すべてのJMXConfiguratorのインスタンスは自動的に解除されるはずです。ロガーコンテキストを初期化するなら、javax.servlet.ServletContextListener
のcontextDestroyed()
メソッドがちょうど良い場所です。サンプルコードを見てみましょう。
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-*.jarとslf4j-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
のインスタンスが表示されるはずです。
MBeanサーバーに登録されるJMXConfiguratorの名前は、jmxConfigurator要素
の"objectName"属性で指定することができます。
JMXを有効化する
JDK1.6以降のJVMでサーバーを実行している場合はデフォルトでJMXが有効になっています。
JDK1.6以前の古いJVMを使っている場合は、サーバーのJMX関連のドキュメントを確認することをおすすめします。たとえばTomcatやJettyにはドキュメントがあります。それはさておき、このドキュメントでは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
にアクセスすることができます。
接続したら、前のスクリーンショットのように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" を探してください。
MX4Jにアクセスしているところのスクリーンショットです。
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
にアクセスできるようになります。
接続したら、前のスクリーンショットのように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" を探してください。
MX4Jにアクセスしているところのスクリーンショットです。