SLF4Jとは

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.mycompany</groupId>
  <artifactId>SLF4JExam</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>SLF4JExam</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.2</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-ext</artifactId>
      <version>1.7.2</version>
    </dependency>
  </dependencies>
</project>

slf4j-log4j12

slf4j使用例 (App.java)

package com.mycompany.slf4jexam;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;

public class App {

    public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger(App.class);
        
        // バインドしているログフレームワークのマップ化コンテキストと連携
        // Log 用の ThreadLocal な Map
        // Log4j の MDC に対応 (NDC((スタック))に対応する者は無い)
        MDC.put("uid", "USER01234");
        
        logger.trace("Hello Trace");
        logger.debug("Hello Debug");
        logger.warn("Hello Warn");
        logger.info("Hello Info");
        logger.error("Hello Error");
        // fatal は無い
        
        logger.info("\\{} はプレースホルダ => {} is not {}", 1, 2);
        logger.info("\\{} に順版を指定できない => {1} is not {0}", 1, 2);
        
        try {
            throw new NullPointerException("ぬるぽ");
        } catch (NullPointerException e) {
            // logback では、設定ファイルで Marker によって出力する・しないのフィルタリングができる
            // たとえば ERROR レベルで、syslogMarker マーカーのついているログだけ、SYSLOG に出力して
            // 運用監視するとか
            //
            // <turboFilter class="ch.qos.logback.classic.turbo.MarkerFilter">
            //   <Marker>REPORT</Marker>
            //   <OnMatch>ACCEPT</OnMatch>
            // </turboFilter>
            
            Marker syslogMarker = MarkerFactory.getMarker("REPORT");
            logger.error(syslogMarker, "エラーが発生しました", e); // 引数に throwable を入れるとスタックトレースが出る
        }
        
        // MDC は、処理終了時に必ず clear() する
        // (特に Web アプリなどで ThreadPool で Thread が使いまわされる可能性があるので)
        MDC.clear();
    }
}

log4j.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>

  <!-- ********************** 標準出力への出力 ********************** -->
  <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">

    <param name="threshold" value="trace" />

    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" 
             value="%d{yyyy-MMM-dd HH:mm:ss.SSS} : %-5p : %X{uid} : %m%n" />
    </layout>
  </appender>

  <!-- ********************** /dev/nullへの出力 ********************** -->
  <appender name="NULL" class="org.apache.log4j.varia.NullAppender">
    <param name="threshold" value="fatal"/>
  </appender>

  <!-- ********************** com.mycompany.slf4jexam.* のログは、STDOUT へ ********************** -->
  <logger name="com.mycompany.slf4jexam" additivity="false"> <!-- root および 包含するパッケージの category の設定を継承しない -->
    <level value="trace" />
    <appender-ref ref="STDOUT" />
  </logger >

  <!-- ********************** その他(ライブラリなど)は NULL へ ********************** -->
  <root>
    <priority value="warn" />
    <appender-ref ref="NULL" />
  </root>

</log4j:configuration>

実行結果

2013-2-08 01:27:20.056 : TRACE : USER01234 : Hello Trace
2013-2-08 01:27:20.058 : DEBUG : USER01234 : Hello Debug
2013-2-08 01:27:20.058 : WARN  : USER01234 : Hello Warn
2013-2-08 01:27:20.058 : INFO  : USER01234 : Hello Info
2013-2-08 01:27:20.058 : ERROR : USER01234 : Hello Error
2013-2-08 01:27:20.063 : INFO  : USER01234 : {} はプレースホルダ => 1 is not 2
2013-2-08 01:27:20.063 : INFO  : USER01234 : {} に順版を指定できない => {1} is not {0}
2013-2-08 01:27:20.070 : ERROR : USER01234 : エラーが発生しました
java.lang.NullPointerException: ぬるぽ
	at com.mycompany.slf4jexam.App.main(App.java:33)

国際化、ログの外部定義

slf4j-ext にある LocLogger? を使う。メッセージのキーは enum で定義し、各国語のプロパティファイルでテンプレートを管理する

App2.java

package com.mycompany.slf4jexam;

import java.util.Locale;
import org.slf4j.cal10n.LocLogger;

public class App2 {

    public static void main(String[] args) {
        LocLogger logger = MyLoggerFactory.getLogger(App.class);
        
        logger.info(Msg.INFORM_START_ACTION, "TEST");
        // LocLogger で、外部定義のメッセージテンプレートを使うときには、
        // プレースホルダに順番を設定できる {0} is {1}
        logger.warn(Msg.BIZERR_RESERVE_SHORTAGE, "Mario Bros. Co.", 18000);
        // メッセージテンプレートが即値の場合には Logger とおなじ
        logger.debug("顧客ID={}, 売掛金={}, 回収金={}", 01234, 141400, 123400);
        logger.info(Msg.INFORM_END_ACTION, "TEST");
        
        LocLogger logger2 = MyLoggerFactory.getLogger(App.class, Locale.UK);
        
        logger2.info(Msg.INFORM_START_ACTION, "TEST");
        logger2.warn(Msg.BIZERR_RESERVE_SHORTAGE, "Mario Bros. Co.", 18000);
        logger.debug("customer_id={}, book_credit={}, claw_back={}", 01234, 141400, 123400);
        logger2.info(Msg.INFORM_END_ACTION, "TEST");
    }
}

Msg.java

package com.mycompany.slf4jexam;

import ch.qos.cal10n.BaseName;
import ch.qos.cal10n.Locale;
import ch.qos.cal10n.LocaleData;

@BaseName("template")
@LocaleData( { @Locale("en_UK"), @Locale("ja_JP") })
public enum Msg  {
    SYSERR_CANNOT_CONNECT_DB,
    BIZERR_RESERVE_SHORTAGE,
    INFORM_START_ACTION,
    INFORM_END_ACTION
}

MyLoggerFactory?.java

package com.mycompany.slf4jexam;

import ch.qos.cal10n.IMessageConveyor;
import ch.qos.cal10n.MessageConveyor;
import java.util.Locale;
import org.slf4j.cal10n.LocLogger;
import org.slf4j.cal10n.LocLoggerFactory;

public class MyLoggerFactory {

    public static LocLogger getLogger(Class clazz) {
        return getLogger(clazz, Locale.getDefault());
    }
    public static LocLogger getLogger(Class clazz, Locale locale) {
        IMessageConveyor messageConveyor = new MessageConveyor(locale);
        LocLoggerFactory factory = new LocLoggerFactory(messageConveyor);
        return factory.getLocLogger(clazz);
    }
}

template_ja_JP.properites

SYSERR_CANNOT_CONNECT_DB=データベース接続エラー PORT={0}, SID={1}
BIZERR_RESERVE_SHORTAGE={0} 向けの債権の引き当てができません。 {1} ドル不足しています
INFORM_START_ACTION={0} 業務開始
INFORM_END_ACTION={0} 業務終了

template_en_GB.properties

SYSERR_CANNOT_CONNECT_DB=DB Connection Error PORT={0}, SID={1}
BIZERR_RESERVE_SHORTAGE=the loans of {0} will not be covered by its loan-loss reserves. ${1} shortage.
INFORM_START_ACTION=START {0}
INFORM_END_ACTION=END {0}

NetBeans? いかす

slf4j-2.png

実行結果

2013-2-08 01:36:58.615 : INFO  :  : TEST 業務開始
2013-2-08 01:36:58.621 : WARN  :  : Mario Bros. Co. 向けの債権の引き当てができません。 18,000 ドル不足しています
2013-2-08 01:36:58.624 : DEBUG :  : 顧客ID=668, 売掛金=141400, 回収金=123400
2013-2-08 01:36:58.624 : INFO  :  : TEST 業務終了
2013-2-08 01:36:58.627 : INFO  :  : START TEST
2013-2-08 01:36:58.628 : WARN  :  : the loans of Mario Bros. Co. will not be covered by its loan-loss reserves. $18,000 shortage.
2013-2-08 01:36:58.628 : DEBUG :  : customer_id=668, book_credit=141400, claw_back=123400
2013-2-08 01:36:58.628 : INFO  :  : END TEST

Java#Jakarta


添付ファイル: fileslf4j-1.png 481件 [詳細] fileslf4j-2.png 495件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS   sitemap
Last-modified: 2014-03-30 (日) 17:07:04 (981d)
ISBN10
ISBN13
9784061426061