サンプルコード  †
- App.java
package com.mycompany.logbackexam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;
public class App {
    private static Logger logger = LoggerFactory.getLogger(App.class);
    public static void main(String[] args) {
        try {
            MDC.put("User", "Hiromi");
            Marker urgent = MarkerFactory.getMarker("URGENT");
            //slf4j には fatal は無い
            //logger.fatal("本当にやばいログ");
            logger.error(urgent, "本当にやばい。夜中でも運用担当者を呼び出せ!");
            logger.error("普通にやばいログ");
            logger.warn("ちょっとやばいログ");
            logger.info("運用時に必要なログ");
            logger.debug("開発時に必要なログ");
            logger.trace("デスマ時に必要なログ");
        } finally {
            MDC.clear();
        }
    }
}
 
- logback.xml
<configuration>
    <appender name="STDOUT1" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>*LOGGER1* %-5level [%X{User}] %-20logger{20} %msg%n</pattern>
        </encoder>
    </appender>
    
    <root level="DEBUG">
        <appender-ref ref="STDOUT1" />
    </root>
</configuration>
 
- 出力
*LOGGER1* ERROR [Hiromi] c.m.logbackexam.App  本当にやばい。夜中でも運用担当者を呼び出せ!
*LOGGER1* ERROR [Hiromi] c.m.logbackexam.App  普通にやばいログ
*LOGGER1* WARN  [Hiromi] c.m.logbackexam.App  ちょっとやばいログ
*LOGGER1* INFO  [Hiromi] c.m.logbackexam.App  運用時に必要なログ
*LOGGER1* DEBUG [Hiromi] c.m.logbackexam.App  開発時に必要なログ
 
Marker でフィルタリング  †
<configuration>
    <appender name="STDOUT1" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.core.filter.EvaluatorFilter">      
            <evaluator> <!-- defaults to type ch.qos.logback.classic.boolex.JaninoEventEvaluator -->
                <expression>return null != marker && marker.contains("URGENT");</expression>
            </evaluator>
            <OnMismatch>ACCEPT</OnMismatch>
            <OnMatch>DENY</OnMatch>
        </filter>        
        <encoder>
            <pattern>%cyan(*LOGGER1* %-5level [%X{User}] %-20logger{20} %msg) %n</pattern>
        </encoder>
    </appender>
    <appender name="STDOUT2" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.core.filter.EvaluatorFilter">      
            <evaluator> <!-- defaults to type ch.qos.logback.classic.boolex.JaninoEventEvaluator -->
                <expression>return null != marker && marker.contains("URGENT");</expression>
            </evaluator>
            <OnMismatch>DENY</OnMismatch>
            <OnMatch>ACCEPT</OnMatch>
        </filter>        
        <encoder>
            <pattern>%red(*LOGGER2* %-5level [%X{User}] %-20logger{20} %msg) %n</pattern>
        </encoder>
    </appender>
    
    <root level="DEBUG">
        <appender-ref ref="STDOUT1" />
        <appender-ref ref="STDOUT2" />
    </root>
</configuration>

MDC でフィルタリング  †
turboFilter は使わないの?  †
- turboFilter は、configuration の子要素
- appender の子要素にはできない
- つまり、logback.xml 全体に設定される
MDCInsertingServletFilter?  †
- みんな作るであろう Servlet Filter が予め用意されている
- web.xml
<filter>
  <filter-name>MDCInsertingServletFilter</filter-name>
  <filter-class>
    ch.qos.logback.classic.helpers.MDCInsertingServletFilter
  </filter-class>
</filter>
<filter-mapping>
  <filter-name>MDCInsertingServletFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
 
- logback.xml からは次の変数名で参照できる
| req.remoteHost | returned by the getRemoteHost?() method |  | req.xForwardedFor? | the "X-Forwarded-For" header |  | req.requestURI | returned by getRequestURI() method |  | req.requestURL | returned by getRequestURL() method |  | req.queryString | returned by getQueryString?() method |  | req.userAgent | the "User-Agent" header |  
 
%X{req.remoteHost} %X{req.requestURI}%n%d - %m%n
Java#Jakarta