• 締切済み

Log4jで機能毎に別ファイルへ出力する方法

こんにちは。 Log4jで複数のログファイルを出力する方法について質問させてください。 やりたい事としては・・・ WebアプリケーションからLog4jを使用して、ログ出力する際に サブアプリAからはsub-A.log サブアプリBからはsub-B.log などとログファイルを出力させたいと思っています。 Log4j.xmlでappenderタグを複数定義すれば良いだけかも知れませんが Java側でどうやって別のログオブジェクトを生成するのかが分かりません。 どの様にして別のオブジェクトの取得が出来るのでしょうか? それとも見当違いのことを質問していますでしょうか? よろしくご教授ください。 これが実現できれば… SQLだけのログ(DBバックアップ用) 例外だけのログ(監視用) などの用途に使えるのかと思っています。 よろしくお願いします。

みんなの回答

回答No.2

ソース上で、Log4jを使用するとき、 (1)private static Logger logger = Logger.getLogger(クラス名.class); または、 (2)private static Logger logger = Logger.getLogger(クラス名.class.getName()); と、ログ出力用にstaticインスタンスを生成していると思います。 Logger.getLogger(Class)は、内部でLogger.getLogger(String)を呼んでいるので、 この(2)のパターンで話を進めます。この引数で渡すStringによって ログインスタンスに名前を与えることになります。この名前決めがLog4jでは重要で、ログの出力先を分けたり、出力するしないを決めたりします。 log4j.xmlでは、 <appender>要素 と <category>要素 を設定します。 <appender>要素 は、出力について決めます。リソースはファイルなのか?コンソールなのか?メールなのか?どんな書式で出力するのか?などです。 複数のファイルに出力するなら、FileAppender系のappenderを複数用意して、それぞれ異なるname属性を与えます。 一方、<category>要素 は、どのログとappenderを紐付けるか設定します。 <appender-ref>要素で、参照するappenderをref属性で指定します。複数あれば(コンソールに出しつつ、ファイルに出すとか)、<appender-ref>要素を並べます。 「どのログ」との紐付けは、<category>要素のname属性で指定します。 このname属性 で指定した文字列が Logger.getLogger(String) で指定したログ名称に「前方一致」すれば、紐付けされる仕組みというわけです。 この「前方一致」ということで重要で、通常、ログ名称は、パッケージ名を含んだ完全名称となりますね。で、クラス名は、"jp.co.会社名.大分類.中分類.・・.クラス名"になりますね。 なので、<category>要素のname属性に"jp.co.会社名.大分類1"と与えたら、jp.co.会社名.大分類1 パッケージ以下のクラスのログが有効になり、"jp.co.会社名.大分類1.中分類2"と与えたら、jp.co.会社名.大分類1.中分類2 パッケージ以下のクラスのログが有効になります。 このことから、パッケージ分けが機能単位、アプリ単位で分かれていれば、ログを有効にしたい、特定のログしか出力しないログファイルを作りたい、という要望に答えられます。 たとえば、下のような、log4j.xmlを組めば、test.log4j.daoパッケージ以下のクラスのログ(より正確には、名前が test.log4j.dao で始まるログ)だけが、ファイル dao.logに出力されます。 ちなみに<root>要素は、すべてのログについて設定になります。下の例では、すべてのログ(dao.logに出力したログも含めて)コンソールとファイルkanshi.logに出力されます。 ただし、<appender>要素は、<param name="threshold">要素によって、<category>要素、<root>要素は、<priority>要素によって、出力するログレベルの下限を設定しています。これによって、コンソールはすべてのログがでますが、dao.logにはinfo以上、kanshi.logにはerror以上のログしか出力されません。 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>  <!-- デバッグ用。   コンソールログを出力するConsoleAppenderとして定義。-->  <appender name="debugAppender"    class="org.apache.log4j.ConsoleAppender" >   <!-- ログレベル:INFO以上 -->   <param name="threshold" value="INFO"/>   <!-- ログの出力形式を指定 -->   <layout class="org.apache.log4j.PatternLayout">    <param name="ConversionPattern"     value="%d %-5p [%t] (%F:%L) - %m%n"/>   </layout>  </appender>  <!-- DAO用 appender -->  <appender name="daoAppender"    class="org.apache.log4j.DailyRollingFileAppender">   <!-- ログのファイル名 -->   <param name="file" value="sql.log" />   <!-- ログレベル:DEBUG以上 -->   <param name="threshold" value="DEBUG" />   <!-- すでにログが存在する場合、ファイルにログを追加 -->   <param name="append" value="true" />   <!-- ログの出力形式を指定 -->   <layout class="org.apache.log4j.PatternLayout">    <param name="ConversionPattern" value="%c, %p, %d, %m%n" />   </layout>  </appender>  <!-- 監視用 appender -->  <appender name="kanshiAppender"    class="org.apache.log4j.DailyRollingFileAppender">   <!-- ログのファイル名 -->   <param name="file" value="kanshi.log" />   <!-- ログレベル:ERROR以上 -->   <param name="threshold" value="ERROR" />   <!-- すでにログが存在する場合、ファイルにログを追加 -->   <param name="append" value="true" />   <!-- ログの出力形式を指定 -->   <layout class="org.apache.log4j.PatternLayout">    <param name="ConversionPattern" value="%c, %p, %d, %m%n" />   </layout>  </appender>  <!-- DAO用ログのカテゴリ -->  <category name="test.log4j.dao">   <priority value="info" />   <appender-ref ref="daoAppender"/>  </category>  <!-- すべてのログ -->  <root>   <priority value="debug" />   <appender-ref ref="debugAppender" />   <appender-ref ref="kanshiAppender" />  </root> </log4j:configuration> もし、パッケージ分けではどうしても、ログの区分けがしづらい場合には、名称に区分けが判るプレフィックスをつけた Loggerインスタンスを生成します。 private static Logger logger = Logger.getLogger("プレフィックス" + クラス名.class.getName()); そして、設定ファイル側も、<category name="プレフィックス"> といった形で、そのプレフィックスがついているログを受け持つカテゴリを設定します。

noname#33813
noname#33813
回答No.1

log4j.xmlで設定したことはないのですが、 log4j.propertiesで ・log4j.logger.sub-A=DEBUG,stdout ・log4j.logger.sub-B=DEBUG,stdout としていたら ・Logger loggerA = Logger.getLogger("sub-A") ・Logger loggerB = Logger.getLogger("sub-B") でそれぞれの設定が使われますよ。

関連するQ&A