2

Linux で Tomcat 5.5 を使用しています。私たちの webapp は、そのロギングに log4j を使用し (機能ベースであり、多くのロガーはありません)、意図的にロガーの加法性を false に設定します。ロガーは独自のログファイルに記録します。それらのどれもコンソールに記録しません。

私たちが抱えている問題は、ロガーのレベルが DEBUG に設定されている場合に、サードパーティ コンポーネント、特に oscache から catalina.out に大量のデバッグ ログが記録されるようになることです。

.../common/classes に最小限の log4j.properties ファイルがあります。

log4j.rootLogger=INFO, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout

# Print the date in ISO 8601 format
log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n

.../webapps/ourapp/WEB-INF/classes に log4g.properties ファイルはありません。

最初に試したのはに変更することlog4j.rootLogger=ERROR, A1でしたが、違いはありませんでした。

次に試したのは、.../webapps/ourapp/WEB-INF/classes/log4j.properties ファイルを 1 行だけ作成することでした。

log4j.logger.com.opensymphony.oscache=ERROR

それが oscache ロギングを停止するかどうかを確認します。それはできましたが、驚くべきことに (私にとって) oscache ロギングだけでなく、不要なロギングをすべて停止しました。そのため、その行をコメントアウトして、もう一度試しました。何からの不要なログ記録もまだありません。ファイルを脇に移動したところ、不要なログが戻ってきました。長さ 0 の log4j.properties を作成したところ、不要なログはすべて削除されました (!) これは短期間のことですが、他にどのようなログが破棄されているのか (そしてその理由!) が気になります。だから頼るだけじゃもったいない。

Tomcat 5.5 ドキュメントの「ロギング」の章では、プロパティ ファイルを WEB-INF/classes に配置することでアプリごとの構成を行うことができると単に述べていますが、それがどのように相互作用するかについては (少なくとも私が見つけたわけではありませんが) 説明していません。 common/classes で指定された構成。

そう:

  • そもそも、サードパーティのコンポーネントはどのように catalina.out にログを記録していますか? 彼らのロギングはルートロガーにバブルアップする可能性があると思いますが、ルートロガーレベルがエラーにまで上がってもログを記録するのはなぜですか?
  • ロガーのロガー レベルを DEBUG に設定すると、このロギングが開始されるのはなぜですか? ロガーには独自の名前が付けられているため、oscache やその他のものがロガーの先祖になることはありません。
  • 長さがゼロの WEB-INF/classes/log4j.properties ファイルでさえ、大量のログ記録を停止するのはなぜですか?
  • これを「正しい」方法で行い、(私にとって) 奇妙な副作用に頼ってオフにするのではなく、意味のある方法でログを制限するにはどうすればよいですか?


好奇心旺盛で好奇心旺盛。デバッグをオンにするというマットの提案を試しました。また、webapp 用により広範な log4j.properties ファイルを作成しました。

log4j.rootLogger=INFO, SSOA1
log4j.appender.SSOA1=org.apache.log4j.ConsoleAppender
log4j.appender.SSOA1.layout=org.apache.log4j.PatternLayout

# Print the date in ISO 8601 format
log4j.appender.SSOA1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n

log4j.logger.com.opensymphony.oscache=ERROR
#log4j.additivity.com.opensymphony.oscache=false

Tomcat が起動すると、次のように表示されます。

log4j: Using URL [file:/srv/www/tomcat5/base/webapps/myapp/WEB-INF/classes/log4j.properties] for automatic log4j configuration.
log4j: Reading configuration from URL file:/srv/www/tomcat5/base/webapps/myapp/WEB-INF/classes/log4j.properties
log4j: Parsing for [root] with value=[INFO, SSOA1].
log4j: Level token is [INFO].
log4j: Category root set to INFO
log4j: Parsing appender named "SSOA1".
log4j: Parsing layout options for "SSOA1".
log4j: Setting property [conversionPattern] to [%d [%t] %-5p %c - %m%n].
log4j: End of parsing for "SSOA1".
log4j: Parsed "SSOA1" options.
log4j: Parsing for [com.opensymphony.oscache] with value=[ERROR].
log4j: Level token is [ERROR].
log4j: Category com.opensymphony.oscache set to ERROR
log4j: Handling log4j.additivity.com.opensymphony.oscache=[null]
log4j: Finished configuring.

しかし、oscache ロガーのレベルがエラーに設定されているという事実にもかかわらず、ログにはまだ次のようなものが表示されます。

2011-03-30 14:53:22,076 [main] DEBUG com.opensymphony.oscache.base.algorithm.AbstractConcurrentReadCache - get called (key=AUDIT_KEY_OLDEST_TIMSTAMP)

oscache ロガー レベルを ERROR に強制している場合 (log4j デバッグ出力ではエラーになっていると表示されます)、なぜこの DEBUG メッセージが送信されるのでしょうか? コード内のレベルをオーバーライドする子ロガー?

私が気付いたのは、webapp の log4j.properties ファイルで oscache ロガーの「加法性」行のコメントを外すと、ログが実際に消えてしまうことです。そのため、oscache ロギングは、独自のものではなく、祖先のアペンダーに依存しているようです。しかし、oscache logger レベルを ERROR に設定しても、これらのことが止められないというのは、さらに奇妙に思えます。

4

2 に答える 2

2

私は一体何が起こっているのかを理解しました。問題は、Web アプリケーションの別の部分の内部に埋もれているのは、そのコンポーネントがデバッグ モードになったときに実行される次のコードです。

public static synchronized void setDebugOn(boolean debugOn) {
    if (isAllDebugOn() ^ debugOn) {
        setAllDebugOn(debugOn);
        Enumeration en = LogManager.getCurrentLoggers();
        while (en.hasMoreElements()) {
            setDebugOn((Logger) en.nextElement(), debugOn);
        }
        setDebugOn(LogManager.getRootLogger(), debugOn);
    }
}

public static void setDebugOn(String name, boolean debugOn) {
    setDebugOn(getLogger(name), debugOn);
}

private static void setDebugOn(Logger logger, boolean debugOn) {
    logger.setLevel(debugOn ? Level.DEBUG : Level.INFO);
}

つまり、このコンポーネントをデバッグ モードにすると、WEBAPP 内のすべての LOG4J ロガーもデバッグ モードになります (最後のメソッド内のすべてのロガーの名前を出力するようにコードを変更して確認しました)。つまり、log4j.properties の内容に関係なく、たまたま log4j を使用するすべてのサードパーティ製のものがデバッグ出力をログに記録し始めます。

そのループでメソッドを変更して、そのコンポーネントに関連する特定のロガーのレベルのみを混乱させると、log4j.properties 構成が期待どおりに機能し始めます。

于 2011-03-30T21:39:36.337 に答える
2

以下のようにコード ログのみを取得するように log4j.properties を構成し、それを catalina.out とは別のファイルに配置することもできます。

ハンドラ = org.apache.juli.FileHandler

org.apache.juli.FileHandler.level=ALL org.apache.juli.FileHandler.directory=${catalina.base}/logs org.apache.juli.FileHandler.prefix=yourapp-name.

com.yourproject.module.package.level=ALL

于 2011-03-29T21:58:46.150 に答える