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 | Commons-Logging |
SEVERE | logging.fatal(),logging.error() |
WARNING | logging.warn() |
INFO | logging.info() |
CONFIG | |
FINE | logging.debug() |
FINER | |
FINEST | logging.trace() |
%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 | Commons-Logging |
FATAL | logging.fatal() |
ERROR | logging.error() |
WARN | logging.warn() |
INFO | logging.info() |
DEBUG | logging.debug(),logging.trace() |
<log4j:configuration> ::= <appender>+ <category>* <root>
<appender> ::= 使用Appenderクラス名 Appenderデフォルトログレベル 出力設定 <layout>? <layout> ::= 使用Layoutクラス名 書式
<root> ::= Rootデフォルトログレベル 使用Appender名+
<category> ::= 適用カテゴリ名 ログレベル 使用Appender名+
<?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="[%-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{yyyy-MM-dd HH:mm:ss.SSS} %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{MMM dd HH:mm:ss} [%-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定義 ************************* -->
<logger name="com.xx.buggy" additivity="false"> <!-- root および他の category の設定を引き継がない -->
<level value="debug" />
<appender-ref ref="STDOUT" />
</logger>
<!-- ********************** root定義 ***************************** -->
<root>
<priority value="info" />
<appender-ref ref="STDOUT" />
<appender-ref ref="SOCKET" />
</root>
</log4j:configuration>
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>
package com.mycompany.log4jexam;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
// import org.apache.log4j.Logger;
import org.apache.log4j.NDC;
public class App {
/**
* commons-logging
* commons-logging から log4j を使った場合でも NDC が参照される
*/
private static final Log logger = LogFactory.getLog(App.class);
// log4j Logger
// private static final Logger logger = Logger.getLogger(App.class);
public static void main(String[] args) {
NDC.push("1st");
logger.debug("Message-A");
NDC.push("2nd");
logger.debug("Message-B");
NDC.push("3rd");
logger.debug("Message-C");
NDC.remove();
logger.debug("Message-D");
}
}
<?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="debug" />
<!-- レイアウトの指定 -->
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d{HH:mm:ss.SSS} [%-5p] %x %m%n" />
</layout>
</appender>
<root>
<priority value="debug" />
<appender-ref ref="STDOUT" />
</root>
</log4j:configuration>
11:00:51.717 [DEBUG] 1st Message-A 11:00:51.717 [DEBUG] 1st 2nd Message-B 11:00:51.717 [DEBUG] 1st 2nd 3rd Message-C 11:00:51.717 [DEBUG] Message-D