質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.33%

  • Java

    14473questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

SLF4J+Logbackでロガーがrootを継承しない

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,686

doju_m

score 12

Java 1.8.0_111、SLF4J 1.7.22、Logback 1.1.8を使用しています。
(開発環境はNetbeans 8.1を使用)
logback.xml にはロガーはrootロガーのみ定義しています。

LoggerFactory.getLogger(Foo.class) として取得したロガーがrootロガーの設定を引き継いでくれず、appenderがない状態になります。
getLogger("root") と明示すればrootロガーを取得してくれますし、
試しにFooのFQCNの名前でロガーを定義したところgetLogger(Foo.class)で目的のロガーを取得できたようですが、
Fooのパッケージを名前にしてロガーを定義したところgetLogger(Foo.class)では該当のロガーの設定を引き継ぎませんでした。(やはりappender等ない「設定なし」のロガーになる。)

ch.qos.logback.core.util.StatusPrinterで設定を確認してみましたが特に問題となりそうなメッセージもなく「Registering current configuration as safe fallback point」と表示されて完了しています。

ロガーがroot設定およびパッケージ名のロガーの設定を継承しない原因としてはどういったことが考えられるでしょうか?

(1/23) 当初「継承」を「フォールバック」と記述していましたが不正確な表現であったため訂正しました。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

rootのloggerのみをlogback.xmlに定義しているのであれば、正しい挙動のように思います。
下位のloggerは上位のloggerの設定を引き継ぐのではなく、上位にログ出力処理を伝搬します。
このケースではFooのloggerはlogback.xmlに定義されていないためログ出力は行われず、伝搬された先のlogback.xmlに定義されているrootのloggerで初めてログ出力処理が行われます。
FooのFQCNの名前でlogback.xmlにloggerを定義すれば、LoggerFactory.getLogger(Foo.class)でappenderは取得できるようになると思いますが、その状態だとFooのloggerとrootのloggerで二重にログが出力されることになります。
ただし、Fooのloggerのadditivityをfalseに設定すれば上位への伝搬を止めることができます。

<!-- Fooでappenderは取得できない -->
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder
            by default -->
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
            </pattern>
        </encoder>
    </appender>
    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>
<!-- Fooでappenderは取得できるがFooとrootで二重にログが出力される -->
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder
            by default -->
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
            </pattern>
        </encoder>
    </appender>
    <logger name="test.Foo" level="debug">
        <appender-ref ref="STDOUT" />
    </logger>
    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>
<!-- Fooでappenderが取得できてFooだけでログが出力される -->
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder
            by default -->
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
            </pattern>
        </encoder>
    </appender>
    <logger name="test.Foo" level="debug" additivity="false">
        <appender-ref ref="STDOUT" />
    </logger>
    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/01/20 18:21 編集

    回答ありがとうございます。
    そうしますと、Logback(ないしSLF4J)ではログ出力したいすべてのクラスについてFQCNでロガーを定義しなくてはならない、もしくはClassでなく"root"やロガーの名前を指定してLoggerを取得しなくてはならないのでしょうか。
    てっきり、Log4Jのようにrootや上位のパッケージ名のロガーを定義しておけば、Classを指定することでその定義が引き継がれるものと思っていたのですが……

    ちなみに、例示2番目相当のlogback.xmlを記述して試してみたところ、ログ出力は二重にはなりませんでした。

    キャンセル

  • 2017/01/20 18:38 編集

    > てっきり、Log4Jのようにrootや上位のパッケージ名のロガーを定義しておけば、Classを指定することでその定義が引き継がれるものと思っていたのですが……
    その認識は合っています。
    Log4Jと同様でROOTのloggerで全てのクラスのログは出力されるはずですので、全てのクラスの定義は不要です。
    もし、FooのログがROOTの設定で出力されないのであれば、何か別の問題が発生してるのかと思います。

    キャンセル

  • 2017/01/20 18:52 編集

    >もし、FooのログがROOTの設定で出力されないのであれば、
    はい、現在その状況です。
    rootのみ設定してもパッケージ名でloggerを定義してもLogFactoryにClassを与えて得たLoggerでは何も出力されず、
    FQCNでloggerを定義してLogFactoryにClassを与えるか、"root"などLogFactoryにロガー名を与えてLoggerを取得して初めて出力される、ということになっています。
    いわば、デフォルトでadditivityがfalseに設定されてでもいるような状態です。

    キャンセル

  • 2017/01/23 14:13

    すみません、どうも勘違いをしていたようです。
    ログファイルの出力先ディレクトリを実行時に差し替える必要があり、
    rootにFileAppenderを持たせて実行クラスのClassでロガーを取得していたのですが
    このとき、実行クラスのClassで取得したロガーがrootのFileAppenderを持っていると思い込んでいました。
    実際は目的のFileAppenderを持っているのはあくまでrootロガーであり、実行クラスのClassで取得したロガーはrootへ出力を委譲する、という構造なのですね。
    今回は必要なロガーを固有名で定義して使用することにしました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.33%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Java

    14473questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。