Jakarta CommonsLogging/log4j

Jakarta-Commons-Logging の概要

logging.png
  • プログラムとロギングフレームワークを分離する薄いラッパー
  • 環境にlog4jがあればlog4jを使うし、なければJDKに付属するjava.util.loggingを使用する。*1
  • プログラムから出力されたログをどのように整形して、どこに出力するかはそれぞれのフレームワークの設定ファイルで設定する。

Jakarta-Commons-Logging のアプリ側プログラミング

  1. 環境
    1. Jakartaプロジェクトのダウンロードサイトから、commons-logging-1.0.4.zipをダウンロード
    2. 展開してできたjarファイルをプロジェクトのクラスパスに通す
      1. commons-logging.jar
      2. commons-logging-api.jar
  2. プログラミング
    1. loggerのインスタンス
      1. logger=LogFactory?.getLog( 自Class ) で取得。ログに出力するClass名になったり、出力するレベルをパッケージによって変えるのに使う。
      2. クラスのstaticフィールドとして保持する
    2. log出力
      1. 対応するメソッドを使うことにより重要度を変えることができる
      2. 第二引数にthrowableをとることができる(通常ログファイルにはスタックトレースが出力される...FormatterなりLayoutの設定次第ですが)
    3. 重いログ出力の前には、logger.is${Level}Enable() メソッドで、現在の設定上出力しなければならないログかを調べること
      記述例:
      Everything is expanded. Everything is shortened.
        1
        2
        3
        4
        5
        6
        7
        8
        9
       10
       11
       12
       13
       14
       15
       16
       17
       18
       19
       20
       21
       22
       23
       24
       25
       26
       27
       28
       29
       30
       31
       32
       33
       34
       35
       36
       37
       38
       39
       40
       41
       42
       43
       44
       45
      
      -
      |
      |
      |
      |
      -
      |
      -
      |
      |
      |
      |
      |
      |
      |
      |
      |
      |
      |
      -
      |
      |
      |
      |
      |
      |
      |
      |
      |
      !
      |
      |
      |
      |
      -
      |
      |
      -
      |
      |
      !
      !
      |
      !
      !
      
       public class LogSample {
       
        /** jakarta-commons-logging */
        private static Log logger = LogFactory.getLog(LogSample.class);
       
        public static void main(String[] args) {
       
          try {
       
            /* ----- 基本的なログ出力 ------ */
            logger.fatal("本当にやばいログ");
            logger.error("普通にやばいログ");
            logger.warn("ちょっとやばいログ");
            logger.info("運用時に必要なログ");
            logger.debug("開発時に必要なログ");
            logger.trace("デスマ時に必要なログ");
            /* ---------------------------- */
            
            throw new NullPointerException("('A`) ぬるぽ ");
          } catch (Exception ex) {
       
            /* -- 例外情報を含んだログ出力 -- */
            logger.fatal("本当にやばいログ", ex);
            logger.error("普通にやばいログ", ex);
            logger.warn("ちょっとやばいログ", ex);
            logger.info("運用時に必要なログ", ex);
            logger.debug("開発時に必要なログ", ex);
            logger.trace("デスマ時に必要なログ", ex);
            /* ---------------------------- */
          }
       
          /* ------- 重いログ出力 -------- */
          java.util.Map m = new HashMap();
       
          if (logger.isDebugEnabled()) {
            // Debugレベルが有効ならば、Mapの中身をすべてログに出力する
            Set keys = m.keySet();
            for (Iterator it = keys.iterator(); it.hasNext();) {
              Object key = it.next();
              logger.debug(key + "=" + m.get(key));
            }
          }
          /* ---------------------------- */
        }
       }

java.util.loggingの設定

  1. 設定ファイル
    1. %JAVA_HOME%\jre\lib\logging.properties
    2. あるいはjava vm起動時に、-Djava.util.logging.config.file=設定ファイル名 で指定
       
  2. 設定方法
    1. ログレベルの対応
      java.util.loggingCommons-Logging
      SEVERElogging.fatal(),logging.error()
      WARNINGlogging.warn()
      INFOlogging.info()
      CONFIG 
      FINElogging.debug()
      FINER 
      FINESTlogging.trace()
       
    2. あとは、%JAVA_HOME%\jre\lib\logging.propertiesを見りゃあ分かりますな。できることは、コメントに書いてあることで全部です。
      %JAVA_HOME%\jre\lib\logging.properties:
      
      ############################################################
      #  	Default Logging Configuration File
      #
      # You can use a different file by specifying a filename
      # with the java.util.logging.config.file system property.  
      # For example java -Djava.util.logging.config.file=myfile
      ############################################################
      
      ############################################################
      #  	Global properties
      ############################################################
      
      # "handlers" specifies a comma separated list of log Handler 
      # classes.  These handlers will be installed during VM startup.
      # Note that these classes must be on the system classpath.
      # By default we only configure a ConsoleHandler, which will only
      # show messages at the INFO and above levels.
      handlers= java.util.logging.ConsoleHandler
      
      # To also add the FileHandler, use the following line instead.
      #handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
      
      # Default global logging level.
      # This specifies which kinds of events are logged across
      # all loggers.  For any given facility this global level
      # can be overriden by a facility specific level
      # Note that the ConsoleHandler also has a separate level
      # setting to limit messages printed to the console.
      .level= INFO
      
      ############################################################
      # Handler specific properties.
      # Describes specific configuration info for Handlers.
      ############################################################
      
      # default file output is in user's home directory.
      java.util.logging.FileHandler.pattern = %h/java%u.log <-- ファイル名
      java.util.logging.FileHandler.limit = 50000            <-- 最大ファイル長さ(byte)
      java.util.logging.FileHandler.count = 1                <-- ローテートするファイルの個数
      java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
      
      # Limit the message that are printed on the console to INFO and above.
      java.util.logging.ConsoleHandler.level = INFO
      java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
      
      
      ############################################################
      # Facility specific properties.
      # Provides extra control for each logger.
      ############################################################ 
      
      # For example, set the com.xyz.foo logger to only log SEVERE
      # messages:
      com.xyz.foo.level = SEVERE 
       <-- com.xyz.foo パッケージ以下はSEVERE以上のログのみを出力するようにする。

log4jの設定

  1. 環境
    1. Logging Services Project @ Apache のダウンロードサイトから logging-log4j-1.2.9.zip をダウンロード
    2. 展開してできたjarファイルをプロジェクトのクラスパスに通す
      1. log4j-1.2.9.jar
    3. 設定ファイルのlog4j.xmlをクラスパスのルートに置く
      1. eclipseなら、\srcにおいておくと、ビルド時に \binにコピーしてくれます
      2. antの場合は、コピーするようにスクリプトを書かなければなりませんね
  2. 設定方法
    1. ログレベルの対応
      log4jCommons-Logging
      FATALlogging.fatal()
      ERRORlogging.error()
      WARNlogging.warn()
      INFOlogging.info()
      DEBUGlogging.debug(),logging.trace()
       
    2. log4j.xmlの構造
      1. log4j.xmlは、appender・category・rootから成ります
        <log4j:configuration> ::= <appender>+ <category>* <root>
      2. appenderセクションには、ログ出力クラスの設定を行います。appenderセクションはlayoutセクションを含み、layoutセクションでログの整形に関する設定を行います。
        <appender> ::= 使用Appenderクラス名 Appenderデフォルトログレベル 出力設定 <layout>?
        <layout>   ::= 使用Layoutクラス名 書式
      3. rootセクションでは、デフォルトのログレベルと、使用するAppender名を指定します。出力されるログレベルは、appenderセクションで定義されたデフォルトログレベルとrootセクションで定義されたデフォルトログレベルの内重要度が大きいものが使用されます。
        <root>     ::= Rootデフォルトログレベル 使用Appender名+
      4. categoryセクションでは、特定のカテゴリ(パッケージ)に対して、ログレベルを変更することができます(rootではinfoレベルだが、com.xx.buggy.* だけは traceレベル で出力したい・・・など)。必ずrootカテゴリよりも前に定義します。
        <category> ::= 適用カテゴリ名 ログレベル 使用Appender名+
    3. 記述例
      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
      
      <log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
      
      	<!-- ********************** レイアウト書式 ***********************
      		%r アプリ起動から何ミリ秒たったか
      		%d 日時 %d{dd MMM yyyy HH:mm:ss.SSS}
      		
      		%t スレッド名
      		%x ネスト化診断コンテキスト(@see org.apache.log4j.NDC)
      		%X マップ化診断コンテキスト(@see org.apache.log4j.MDC)
      		
      		%p レベル名(FATAL/ERROR/WARN/INFO/DEBUG)
      		%c カテゴリー名(クラス名) // LogFactoryで指定したもの 
      		
      		%m メッセージ
      		
      		%n 改行コード
      		%% %
      		
      		%10m     桁数が10桁未満のとき、左側にSPを追加して10桁にする
      		%.10m    桁数が10桁以上のとき、11桁目以降を削除して10桁にする
      		%10.20m  (左側にSPを足して)桁数を10桁~20桁にそろえる
      		%-10m    桁数が10桁未満のとき、右側にSPを追加して10桁にする
      		%-10.20m (右側にSPを足して)桁数を10桁~20桁にそろえる
      		
      		※パフォーマンス上の問題があるので避けるべき書式(StatcTraceから取得?)
      		
      		%C クラス名
      		%M メソッド名
      		%l ファイル名・行番号
      		%F ファイル名
      		%L 行番号
      	-->
      		
      	<!-- ********************** 標準出力への出力 ********************** -->
      	<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
      	
      		<!-- デフォルトのログレベル -->
      		<param name="threshold" value="debug" />
      		
      		<!-- レイアウトの指定 -->
      		<layout class="org.apache.log4j.PatternLayout">
      			<param name="ConversionPattern"
      			       value="%d{HH:mm:ss.SSS} [%-5p] %.30m%n" />
      		</layout>
      	</appender>
      	
      	<!-- ********************** ファイルへの出力 ********************** -->
      	<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
      	
      		<!-- デフォルトのログレベル -->
      		<param name="threshold" value="info" />
      		
      		<!-- ファイル情報 -->
      		<param name="file" value="log.txt" />
      		<param name="append" value="false" />
      		<param name="datePattern" value="'.'yyyy-MM-dd" />
      		<!--
      			ファイルローテートの指定
      			'.'yyyy       年の変わり目(1月1日の0時)
      			'.'yyyy-MM    月の変わり目(1日の0時)
      			'.'yyyy-ww    週の変わり目(日曜の0時)
      			'.'yyyy-MM-dd 日の変わり目(0時)
      		-->
      		
      		<!-- レイアウトの指定 -->
      		<layout class="org.apache.log4j.PatternLayout">
      			<param name="ConversionPattern"
      			       value="%d %x [%-5p] %m%n" />
      		</layout>
      	</appender>
      
      	<!-- ********************** syslogdへの出力 ********************** -->
      	<appender name="SYSLOG" class="org.apache.log4j.net.SyslogAppender">
      	
      		<!-- デフォルトのログレベル -->
      		<param name="threshold" value="error" />
      		<!--
      			(log4j)  (syslog)
      			FATAL    crit,panic,emerg
      			ERROR    err,error 
      			WARN     warning,warn 
      			INFO     info 
      			DEBUG    debug 
      		-->
      		
      		<!-- syslogサーバ情報 -->
      		<param name="SyslogHost" value="localhost" />
      		<param name="facility" value="user" />
      		<!--
      			facility には以下の項目を設定できる
      			kern , user , mail , daemon , auth(認証) , syslog , lpr ,
      			news , uucp , cron , authpriv(アプリ固有の認証) , ftp , local0~7
      		-->
      
      		<!-- レイアウトの指定 -->
      		<layout class="org.apache.log4j.PatternLayout">
      			<param name="ConversionPattern"
      			       value="%d{HH:mm:ss.SSS} [%-5p] %.30m%n" />
      		</layout>
      	</appender>
      
      	<!-- ********************** NTEventへの出力 ********************** -->
      	<!-- NTEventを記録するサーバの C:\WINNT\SYSTEM32 に
      	     logging-log4j-x.x.x\src\java\org\apache\log4j\nt\NTEventLogAppender.dll
      	     をコピー
      	-->
      	<appender name="NTEvent" class="org.apache.log4j.nt.NTEventLogAppender">
      	
      		<!-- デフォルトのログレベル -->
      		<param name="threshold" value="fatal" />
      		
      		<!-- NTEventサーバの設定 -->
      		<param name="source" value="XXアプリ" />
      		
      		<!-- レイアウトの指定 -->
      		<layout class="org.apache.log4j.PatternLayout">
      			<param name="ConversionPattern"
      			       value="%d{HH:mm:ss.SSS} [%-5p] %.30m%n" />
      		</layout>
      	</appender>
      
      	<!-- ********************** SMTPへの出力 ************************* -->
      	<!-- JavaMail(mail.jar)  http://java.sun.com/j2ee/ja/javamail/index.html
      	     JAF(activation.jar) http://java.sun.com/beans/glasgow/jaf.html
      	     をクラスパスに通しておく
      	-->
      	<appender name="SMTP" class="org.apache.log4j.net.SMTPAppender">
      	
      		<!-- デフォルトのログレベル -->
      		<param name="threshold" value="fatal" />
      		
      		<!-- メール送信の設定 -->
      		<param name="SMTPHost" value="mail.xxxxxxx.com" />
      		<param name="To" value="xxxxx@xxxxxxx.com" />
      		<param name="Subject" value="【緊急】XXアプリ致命的エラーの発生" />
      		<param name="From" value="XXMaster@xxxxxxxxxx.com" />
      		<param name="BufferSize" value="1" />
      		
      		<!-- レイアウトの指定 -->
      		<!-- PatternLayoutは、getContentType()の返値に文字コードを指定できない
      		     ので、文字コード を指定して text/plane; chaset=XXX を出力できるよう
      		     に拡張したEncordablePatternLayoutを独自に作る
      		     (http://issues.apache.org/bugzilla/show_bug.cgi?id=32074 で議論中)
      		-->
      		<layout class="EncodablePatternLayout">
      			<param name="Charset" value="ISO-2022-JP" />
      			<param name="ConversionPattern"
      			       value="%d{HH:mm:ss.SSS} [%-5p] %.30m%n" />
      		</layout>
      	</appender>
      
      	<!-- **************** Socket(Log4JMonitor)への出力 *************** -->
      	<!-- http://freshmeat.net/projects/log4jmonitor/?topic_id=45%2C846%2C47 -->
      	<!-- log4jmonitor-1.1.jar をダブルクリックすると起動します                -->
      	<appender name="SOCKET" class="org.apache.log4j.net.SocketAppender">
      	
      		<!-- デフォルトのログレベル -->
      		<param name="threshold" value="debug" />
      		
      		<!-- 送信先の設定 -->
      		<param name="RemoteHost" value="localhost" />
      		<param name="Port"       value="27272" />
      		
      		<!-- layoutは指定しない -->
      	</appender>
      	
      	<!-- ********************** category定義 ************************* -->
      	<category name="com.xx.buggy">
      		<priority value="debug" />
      		<appender-ref="STDOUT" />
      	</category>
      	
      	<!-- ********************** root定義 ***************************** -->
      	<root>
      		<priority value="info" />
      		<appender-ref ref="STDOUT" />
      		<appender-ref ref="SOCKET" />
      	</root>
      	 
      </log4j:configuration>
  3. SMTPAppenderで日本語のメールを送る
    PatternLayout?.getContentType?()が常に、"text/plain"を返すので、日本語のメールを送ることができません。
    そこで、PatternLayout?を拡張して、ContentType?を指定できるEncordablePatternLayout?を作りました。
    Everything is expanded. Everything is shortened.
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
    
     
     
     
     
    -
    |
    |
    |
    -
    |
    !
    |
    -
    |
    !
    !
    
     EncodablePatternLayout.java:
     
     import org.apache.log4j.PatternLayout;
     
     public class EncodablePatternLayout extends PatternLayout {
     
      private String charset;
     
      public void setCharset(String charset) {
        this.charset = charset;
      }
     
      public String getContentType() {
        return "text/plain; charset=\"" + charset + "\"";
      }
     }
    log4j.xml(抜粋):
    
    <layout class="EncodablePatternLayout">
      <param name="Charset" value="ISO-2022-JP" />
      <param name="ConversionPattern"
             value="%d{HH:mm:ss.SSS} [%-5p] %.30m%n" />
    </layout>
  4. ネスト化診断コンテキスト
    Threadに対して、push(String)で文字列を指定できる。
    Servletのフィルタ?やEJBのFacadeなどに用いる。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值