ログ設定¶
Resinは JDK logging インタフェース の出力先を指定し、Webアプリケーションの標準出力、標準エラー出力をリダイレクトすることができます。
java.util.logging¶
概要¶
Resinは すべての内部ログにJDK 標準の java.util.logging を使用し、ログフォーマット、ログレベルの構成を柔軟に提供します。
ログ設定は、ログハンドラとロガーレベルの2つの部分があります。
ログハンドラはResinのログをどこに出力するかを指示します。Resinには、ファイルベースのログハンドラ、メールハンドラ、syslogのハンドラ、およびJDK標準に準拠する任意のカスタムログハンドラが含まれています。
ファイルベースログハンドラの例
<log-handler name="com.foo" level="all"
path="${resin.root}/log/foo.log"
timestamp="[%y-%m-%d %H:%M:%S.%s] {%{thread}} "/>
<logger> は名前付きロガーのログレベルを設定します。<logger> は一般的に複数のログハンドラを持ちますので、ロガーレベルとログハンドラレベルの出力は一致している必要があります。
ロガーおよびログハンドラ名は階層的であるため、「com.foo」<logger> は「com.foo.bar」を有効にします。
「fine」レベルのログ出力設定の例
<logger name="com.foo" level="fine"/>
<logger name="com.foo.bar" level="finest"/>
ログ名¶
JDK logging API は階層型の命名方式を使用しています。通常、名前はJavaクラス名と同じものです。名前を指定すると、指定した名前で始まる名前をもった全てのロギングの要求が照合されます。
例えば、 <logger name=”example.hogwarts” ...> は “example.hogwarts.System” と “example.hogwarts.gryffindor.System” のロギングの要求と一致します。
Resin自身のロギングは、Resinのクラス名に基づいています。以下はResinの便利なログ名の一覧です。
名前 | 意味 |
---|---|
“” | すべてをデバッグします。 |
com.caucho.ejb | EJBの処理。 |
com.caucho.jsp | JSPのデバッグ。 |
com.caucho.java | Java コンパイル。 |
com.caucho.server.port | TCPポートのデバッグおよびスレッド。 |
com.caucho.server.http | HTTP関連のデバッグ。 |
com.caucho.server.webapp | Webアプリケーション関連のデバッグ。 |
com.caucho.server.cache | キャッシュ関連のデバッグ。 |
com.caucho.sql | データベースプール。 |
com.caucho.transaction | トランザクションの処理。 |
ログレベル¶
ロガーレベルは、与えられたデバッグ粒度のログを有効にします。「severe」レベルは、サーバの安定性を脅かすログを示しており、「fine」レベルは、アプリケーション/ライブラリのユーザ向けのデバッグ情報を表示します。
ログレベルは JDK java.util.logging.Level に定義される値と一致しています。
名前 | API | 用途 |
---|---|---|
off | ログをオフにする。 | |
severe | log.severe(”...”) | Webアプリケーションの起動の失敗やサーバの再起動などプログラムの実行を妨げる障害。 |
warning | log.warning(”...”) | ブラウザにレスポンスコード500を返す可能性があるような深刻な問題。 |
info | log.info(”...”) | Webアプリケーションの起動などの主要なライフサイクル イベント。 |
config | log.config(”...”) | 設定に関する詳細なログ。 |
fine | log.fine(”...”) | ソースコードに精通していない開発者のためのユーザレベルのデバッグ。 |
finer | log.finer(”...”) | 開発者が使用する詳細なデバッグ。 |
finest | log.finest(”...”) | 詳細なトレースを行うデバッグ。 |
all | 全てのメッセージがログに記録される。 |
<log-handler>¶
JDK java.util.logging.* API のためのログハンドラを設定します。
java.util.logging には 2 つの手順があります。ログハンドラのセットの設定と、各ロガーのレベルの設定です。<log-handler>はログの送信先を作成し、ハンドラの最低ログレベルを設定し、ログ名にハンドラをアタッチします。
カスタムハンドラを構成する <log-handler> には最も共通的な設定であるログファイルのローテートがあります。設定の大部分はログのローテートのものであり、他のロギング設定と共有されます。
ログハンドラ タイムスタンプ¶
logタグのタイムスタンプは、日付と時刻の値に置換される「%」のコードを含めることができるフォーマットの文字列です。
コード | 意味 |
---|---|
%a | 曜日(省略) |
%A | 曜日(詳細) |
%b | 月(省略) |
%B | 月(詳細) |
%c | Javaロケールの日付 |
%d | 月(数字2桁) |
%H | 24時間の時(数字2桁) |
%I | 12時間の時(数字2桁) |
%j | 年の日数 |
%m | 月(数字2桁) |
%M | 分 |
%p | 午前/午後 |
%S | 秒 |
%s | ミリ秒 |
%W | 年の週数(数字3桁) |
%w | 週の日数(数字1桁) |
%y | 年(数字2桁) |
%Y | 年(数字4桁) |
%Z | タイムゾーン(名称) |
%z | タイムゾーン(+/-0800) |
%{thread} | 現在のスレッドの名前 |
%{level} | 現在のログレベル |
%{env} | 現在のクラスローダ環境 |
典型的なlogタグのタイムスタンプの例
<log-handler name='' path='stderr:' timestamp="[%H:%M:%S.%s] {%{thread}}"/>
[22:50:11.648] WebApp[/doc] starting
[22:50:11.698] http listening to *:8080
[22:50:11.828] hmux listening to *:6800
ログハンドラ アーカイブ¶
以下の例はロールオーバー ファイルに書き込む標準的なログハンドラです。ハンドラのレベルは「all」なので、<logger>が実際のログレベルを設定します。
<log-handler name="" level="all"
timestamp="[%Y/%m/%d %H:%M:%S.%s] {%{thread}} "/>
<logger name="com.caucho" level="info"/>
デフォルトのアーカイブ形式は以下の通りです。
rollover-period が 1日(1D)以上の場合。
path + ".%Y%m%d"
rollover-period が 1日(1D)より小さい場合。
path + ".%Y%m%d.%H"
たとえば、標準エラー出力を使用するすべてのログに設定する例は以下の通りです。
<log-handler name='' level='all' path='stderr:' timestamp="[%H:%M:%S.%s]"/>
役立つテクニックとして、問題を追跡するために全てのデバッグログの出力を有効にします。
<log-handler name='' level='finer' path='log/debug.log'
timestamp="[%H:%M:%S.%s]"
rollover-period='1h' rollover-count='1'/>
ログハンドラ ELフォーマット¶
Resinの <log-handler> のformat属性には、各ログメッセージのフォーマット文字列を指定します。フォーマットはEL式を認識します。
フォーマット文字列の例
<log-handler name='' level='all' path='stderr:' timestamp="[%H:%M:%S.%s]"
format=" ${log.level} ${log.name} ${log.message}"/>
ログ EL 変数
変数 | 説明 |
---|---|
${log.level} | ログレベル。 |
${log.name} | ロガー名。 |
${log.shortName} | ロガー名を短くしたもの(”com.hogwarts.Foo” ではなく “Foo”) |
${log.message} | ログメッセージ。 |
${log.millis} | イベントが発生した時間。1970年からのミリ秒。 |
${log.sourceClassName} | ロギングを要求したクラス名。(実行時に使用できない場合があります。) |
${log.sourceMethodName} | ロギングを要求したメソッド名。(実行時に使用できない場合があります。) |
${log.threadID} | ロギングの要求が発信されたスレッドのint型の識別子を取得。 |
${log.thrown} | ロギングの要求に関連付けられたjava.lang.Throwableを取得。 |
${thread} | 現在のスレッドの名前。 |
${request} | サーブレットリクエストの値。 |
${session} | HTTPセッション。 |
${cookie[‘JSESSIONID’]} | リクエスト クッキーの値。 |
また、フォーマット文字列で環境EL変数を使用することもできます。
<web-app>
<log name='' level='all' path='log/debug.log' timestamp="[%H:%M:%S.%s]"
format=" [${app.contextPath}] ${log.message}"/>
...
</web-app>
[14:55:10.189] [/foo] `null' returning JNDI java:
model for EnvironmentClassLoader[web-app:http://localhost:8080/foo]
[14:55:10.189] [/foo] JNDI lookup `java:comp/env/caucho/auth'
exception javax.naming.NameNotFoundException: java:comp/env/caucho/auth
[14:55:10.199] [/foo] Application[http://localhost:8080/foo] starting
Logger: アプリケーションのロギング¶
アプリケーションでロギングを行うために、JDKのロギング機能を利用することができます。適切なログ名とレベルにすることは、トラブルシューティングとコードのデバッグを行うために重要です。多すぎるロギングは少ないロギングと同じくらい開発者の混乱を招きます。
ログ名は実装しているクラスの完全なクラス名にすべきです。別の名前を付けることも可能ですがクラス名にすることにより保守性が向上します。
ログレベルは、アプリケーション全体で一貫しているべきです。Resinでは、以下のレベルの表記法を使用しています。
finerのロギングの例
import java.util.logging.Logger;
import java.util.logging.Level;
public class Foo {
private static final Logger log
= Logger.getLogger(Foo.class.getName());
...
void doFoo(String bar)
{
// check for log level if your logging call does anything more
// than pass parameters
if (log.isLoggable(Level.FINER))
log.finer(this + "doFoo(" + bar + ")");
...
log.info(...);
try {
...
} catch (ExpectedException ex) {
log.log(Level.FINEST, "expected exception", ex);
}
}
...
}
カスタムログハンドラとライブラリログハンドラ¶
カスタムハンドラとライブラリのログハンドラは、CanDI XMLの構文を使って設定できます。
JDK FileHandler の例
<web-app xmlns="http://caucho.com/ns/resin"
xmlns:jdk-logging="urn:java.util.logging">
<log-handler name="com.foo" level="info">
<jdk-logging:FileHandler>
<new>
<value>/tmp/test.out</value>
</new>
</jdk-logging:FileHandler>
</logger>
</web-app>
package com.foo.demo;
import java.util.logging.*;
public class MyHandler extends Handler
{
@Override
public void publish(LogRecord record)
{
System.out.println(getFormatter().format(record));
}
@Override
public void flush();
{
}
@Override
public void close();
{
}
}
カスタムログフォーマット¶
ログハンドラと同様に、ログメッセージの書式をカスタマイズできます。フォーマッタは、java.util.logging インタフェースをResinが認識し、<log-handler> を使用して設定することができます。
サイトの情報をより適切に収集するために、ログメッセージの書式を変更したい場合があります。フォーマッタもハンドラと同様にカスタム設定することができます。
カスタムフォーマットの設定例
<log-handler name="com.foo" level="warning" path="WEB-INF/log.log">
<formatter><mypkg:MyFormatter/></formatter>
</log-handler>
MyFormatter.java
package com.mycom.mypkg;
import java.util.logging.*;
public class MyFormatter extends Formatter
{
@Override
public String format(LogRecord record)
{
return "[" + record.getLevel() + "] " + record.getMessage();
}
}
Resinビルトイン ログハンドラ¶
ResinはJMS、HMTPおよび syslog サービスなどに一般的なログパターンでメッセージを送信するカスタムログハンドラがあらかじめ用意されています。
また、カスタム ハンドラを作成することも簡単です。
BamLogHandler¶
BAMハンドラは、BAMエージェントにログメッセージを発行します。エージェントは、ログメッセージを処理するためのカスタムHMTPサービスを行えます。 BamHandlerは、対象サービスのアドレスとしてJID(Jabber id)が必要です。
BAM ハンドラ設定の例
<logger name="com.foo">
<resin:BamLogHandler level="warning">
<to>test@localhost</to>
</resin:BamLogHandler>
</logger>
EventLogHandler¶
イベントハンドラは、CanDIイベントシステムへの LogEvent を発行します。 LogEventは通知を受信するために、@Observes メソッドを持つ任意の CanDI コンポーネントが通知を受信します。ログハンドラのクラス名は com.caucho.log.EventLogHandler です。
イベントハンドラ設定の例
<logger name="com.foo">
<resin:EventLogHandler level="warning"/>
</logger>
JmsLogHandler¶
JMS ハンドラは JMS キューにログ メッセージを発行します。
JMS ハンドラ設定の例
<web-app xmlns="http://caucho.com/ns/resin"
xmlns:ee="urn:java:ee"
xmlns:resin="urn:java:com.caucho.resin">
<resin:MemoryQueue ee:Named="myQueue"/>
<logger name="com.foo">
<resin:JmsLogHandler level="warning">
<target>${myQueue}</target>
</resin:JmsLogHandler>
</logger>
</web-app>
MailLogHandler¶
メールハンドラは email アドレスにログメッセージを送信します。メールの数を抑えるために、ハンドラがメッセージを連結し一定期間の後に送信します。
MailLogHandler 属性
属性名 | 説明 | デフォルト |
---|---|---|
to | メールアドレス | なし(必須) |
delay-time | 最初のメールを送信する前に待機する時間 | 1m(1分) |
mail-interval-min | メールメッセージの最小間隔 | 1h(1時間) |
properties | JavaMailのプロパティ | なし |
メールハンドラ設定の例
<logger name="">
<resin:MailLogHandler level="warning">
<to>admin@foo.com</to>
<properties>
mail.smtp.host=127.0.0.1
mail.smtp.port=25
</properties>
</resin:MailLogHandler>
</logger>
SyslogHandler¶
UNIXシステムでは、SyslogHandlerを使用してsyslogにメッセージを記録することができます。
SyslogHandler 設定の例
<logger name="">
<resin:SyslogLogHandler level="warning">
<facility>daemon</facility>
<severity>notice</severity>
</resin:SyslogLogHandler>
</logger>
facility に使用可能な値は、user, mail, daemon、auth、lpr、news、uucp、cron、authpriv、ftp、local0、local1、local2、local3、local4、local5、local6、local7。デフォルトは daemon です。
severityには、emerg、alert、crit、err、warning、notice、info、debugが使用可能です。
「man 3 syslog」 と 「man syslog.conf」を参照してください。
ログローテーションとアーカイブ¶
ログローテーションは毎週または毎日ごとにログファイルをアーカイブします。ロールオーバーが発生すると既存のログファイルの名前が変更され新しいログファイルにログが出力されます。
ResinのログローテーションはJDK logging、HTTPアクセスログ、標準入出力ログで使用されます。
サイズによるロールオーバー¶
ファイルサイズが一定量に達したときにロールオーバーが行われます。Resinのデフォルトの動作はファイルサイズが1MBに達したときにロールオーバーが行われます。
「rollover-size」は最大サイズを指定するために使用し、バイト(50000)、キロバイト(128kb)、メガバイト(10mb)が指定可能です。-1の場合はサイズによるロールオーバーを無効にします。
時間によるロールオーバー¶
最後にロールオーバーされてから一定の期間が経過したときにロールオーバーされます。Resinのデフォルトの動作は、「rollover-size」に-1が設定されてサイズによるロールオーバーが無効にされていなければ、時間によるロールオーバーを実行しません。サイズによるロールオーバーが無効になっている場合のデフォルト期間は1ヶ月です。
「rollover-period」は期間を指定するために使用し、日(15D)、 週(2W)、 月(1M)、 または 時間(1h)が指定可能です。
アーカイブファイル¶
ロールオーバーが行われると、ログファイルの名前が変更され(アーカイブ)新しいログファイルにログが出力されます。
「archive-format」は、アーカイブファイルの名前を指定します。これは、通常の文字、EL環境変数、%コードを使用して現在の日付と時刻を含めることができます。%コードはタイムスタンプに使用するものと同じです。
デフォルトの動作は「rollover-period」の値に依存します。「rollover-period」が一日よりも大きい、または「rollover-size」が指定されているため使用されていない場合、アーカイブファイル名はオリジナルのパスに「.%Y%m%d」が追加されたものです。
「rollover-period」が一日未満の場合、アーカイブファイル名はオリジナルのパスに「 .%Y%m%d.%H」が追加されたものです。
ロール オーバーの無効¶
ロールオーバーを無効にするには、「rollover-size」に起こりえないような大きな数を設定してください。
<stdout-log path="log//stdout.log" rollover-size="1024mb"/>
標準出力のリダイレクト¶
stdoutログ¶
System.out の送信先を設定します。
stdoutログの設定は、親の設定より優先されます。例えば、<web-app>の子としてstdoutログを指定すると、Webアプリケーションで行われるSystem.outのリダイレクトが行われ、親<host>のstdoutログの設定より優先されます。
注意
「path」はコマンドライン「-stdout」で指定されたパスと同じであってはいけません。もし同じパスを指定した場合プロセスがファイルの所有で競合します。
属性¶
属性名 | 説明 | デフォルト |
---|---|---|
archive-format | ロールオーバーされたアーカイブファイル名のフォーマット | 以下を参照 |
path | 出力先のパス | なし(必須) |
path-format | パスを決定するためのフォーマットを指定します。構文は「archive-format」と同じです。 | なし(任意) |
rollover-count | ロールオーバーファイルの最大数。 | なし |
rollover-period | ロールオーバーを行う頻度。日(15D)、週(2W)、月(1M)、時間(1H)。 | なし |
rollover-size | ロールオーバーを行うファイルの最大サイズ。バイト(50000)、KB(128kb)、メガバイト(10mb)。 | 1メガバイト(1mb) |
timestamp | 行の先頭に使用する タイムスタンプ のフォーマット。 | タイムスタンプなし |
デフォルトのアーカイブフォーマットは以下の通りです。
rollover-period が 1日(1D)以上の場合。
path + ".%Y%m%d"
rollover-period が 1日(1D)より小さい場合。
path + ".%Y%m%d.%H"
次の例は <host> に System.out を構成します。<web-app>の出力ログ設定がオーバーライドしない限り、ホスト内のすべての Webアプリケーションは同じ出力ファイルに書き込みます。
<host id='foo.com'>
<stdout-log path='/var/log/foo/stdout.log'
rollover-period='1W'/>
...
</host>
stderrログ¶
System.err の送信先を設定します。
stderrログの設定は、親の設定より優先されます。例えば、<web-app>の子としてstderrログを指定すると、Webアプリケーションで行われるSystem.errのリダイレクトが行われ、親<host>のstderrログの設定より優先されます。
注意
「path」はコマンドライン「-stderr」で指定されたパスと同じであってはいけません。もし同じパスを指定した場合プロセスがファイルの所有で競合します。
属性¶
属性名 | 説明 | デフォルト |
---|---|---|
archive-format | ロールオーバーされたアーカイブファイル名のフォーマット | 以下を参照 |
path | 出力先のパス | なし(必須) |
path-format | パスを決定するためのフォーマットを指定します。構文は「archive-format」と同じです。 | なし(任意) |
rollover-count | ロールオーバーファイルの最大数。 | なし |
rollover-period | ロールオーバーを行う頻度。日(15D)、週(2W)、月(1M)、時間(1H)。 | なし |
rollover-size | ロールオーバーを行うファイルの最大サイズ。バイト(50000)、KB(128kb)、メガバイト(10mb)。 | 1メガバイト(1mb) |
timestamp | 行の先頭に使用する タイムスタンプ のフォーマット。 | タイムスタンプなし |
デフォルトのアーカイブフォーマットは以下の通りです。
rollover-period が 1日(1D)以上の場合。
path + ".%Y%m%d"
rollover-period が 1日(1D)より小さい場合。
path + ".%Y%m%d.%H"
次の例は <host> に System.out を構成します。<web-app>の出力ログ設定がオーバーライドしない限り、ホスト内のすべての Webアプリケーションは同じ出力ファイルに書き込みます。
<host id='foo.com'>
<stderr-log path='/var/log/foo/stderr.log'
rollover-period='1W'/>
...
</host>
<access-log>¶
<access-log> は、アクセス ログ ファイルを構成します。
<web-app> の子に定義されている場合、<host>の定義をオーバーライドします。<host> の子に定義されている場合、<server> の定義をオーバーライドします。
デフォルトのアーカイブフォーマットは以下の通りです。
rollover-period が 1日(1D)以上の場合。
path + ".%Y%m%d"
rollover-period が 1日(1D)より小さい場合。
path + ".%Y%m%d.%H"
アクセス ログのフォーマット変数は Apache 変数に従ってください。
フォーマットパターン¶
パターン | 説明 |
---|---|
%b | 返却されるコンテンツの長さ。 |
%D | リクエストの処理が完了するまでにかかった時間。(マイクロ秒) |
%h | リモートIPアドレス。 |
%{xxx}i | リクエストヘッダ。 |
%{xxx}o | レスポンスヘッダ。 |
%{xxx}c | Cookieの値。 |
%n | リクエストの属性値。 |
%r | リクエストURL。 |
%s | ステータスコード。 |
%S | セッションID。 |
%{xxx}t | 日時のフォーマット。 |
%T | リクエストの処理が完了するまでにかかった時間。(秒) |
%u | リモートユーザ。 |
%U | リクエストURI。 |
%v | バーチャルホストのサーバ名。 |
デフォルトのフォーマットは以下の通りです。
"%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""
属性¶
属性名 | 説明 | デフォルト |
---|---|---|
path | 出力先のパス | なし(必須) |
path-format | パスを決定するためのフォーマットを指定します。構文は「archive-format」と同じです。 | なし(任意) |
archive-format | ロールオーバーされたアーカイブファイル名のフォーマット。 | 以下を参照 |
auto-flush | 要求のたびにメモリバッファーをフラッシュする場合は true。 | false |
auto-flush-time | メモリ バッファーをフラッシュする時間間隔。 | 60秒(60s) |
exclude | リクエストのURIが一致する場合、アクセス ログに記録されません。 | なし(任意) |
format | アクセス ログのフォーマット。 | 上記を参照。 |
hostname-dns-lookup | IPアドレスの代わりにDNS名を記録。(パフォーマンスに影響があります。) | false |
rollover-period | ロールオーバーを行う頻度。日(15D)、週(2W)、月(1M)または時(1h)で指定します。 | なし(任意) |
rollover-size | ロールオーバーを行うログファイルの最大サイズ。バイト(50000)、キロバイト(128kb)、またはメガバイト(10mb)で指定します。 | 1ギガバイト(1gb) |
rollover-count | ロールオーバーファイルの最大数。 | なし |
<host> に <access-log> を設定する例。
<cluster id="app-tier">
<host id="">
<access-log path='log/access.log'>
<rollover-period>2W</rollover-period>
</access-log>
</host>
</cluster>