<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <!--
    Variables for simplifying logging configuration.
    http://logback.qos.ch/manual/configuration.html#variableSubstitution
    -->

    <!--
    If you want to use custom properties in this config file,
    we load the main property file for you.
    -->
    <variable file="${idp.home}/conf/idp.properties" />

    <!-- Location and retention. -->
    
    <variable name="idp.logfiles" value="${idp.logfiles:-${idp.home}/logs}" />
    <variable name="idp.loghistory" value="${idp.loghistory:-180}" />
    
    <!-- Much higher performance if you operate on DEBUG. -->
    <!-- <variable name="idp.process.appender" value="ASYNC_PROCESS" /> -->
    
    <!-- Logging level shortcuts. -->
    <variable name="idp.loglevel.idp" value="${idp.loglevel.idp:-INFO}" />
    <variable name="idp.loglevel.ldap" value="${idp.loglevel.ldap:-WARN}" />
    <variable name="idp.loglevel.messages" value="${idp.loglevel.messages:-INFO}" />
    <variable name="idp.loglevel.encryption" value="${idp.loglevel.encryption:-INFO}" />
    <variable name="idp.loglevel.opensaml" value="${idp.loglevel.opensaml:-INFO}" />
    <variable name="idp.loglevel.props" value="${idp.loglevel.props:-INFO}" />
    <variable name="idp.loglevel.httpclient" value="${idp.loglevel.httpclient:-INFO}" />
    
    <!-- Don't turn these up unless you want a *lot* of noise. -->
    <variable name="idp.loglevel.spring" value="${idp.loglevel.spring:-ERROR}" />
    <variable name="idp.loglevel.container" value="${idp.loglevel.container:-ERROR}" />
    <variable name="idp.loglevel.xmlsec" value="${idp.loglevel.xmlsec:-INFO}" />

    <!-- =========================================================== -->
    <!-- ============== Logging Categories and Levels ============== -->
    <!-- =========================================================== -->

    <!-- Logs IdP, but not OpenSAML, messages -->
    <logger name="net.shibboleth.idp" level="${idp.loglevel.idp}"/>

    <!-- Logs OpenSAML, but not IdP, messages -->
    <logger name="org.opensaml.saml" level="${idp.loglevel.opensaml}"/>
    
    <!-- Logs LDAP related messages -->
    <logger name="org.ldaptive" level="${idp.loglevel.ldap}"/>

    <!-- Logs embedded HTTP client messages -->
    <logger name="org.apache.http" level="${idp.loglevel.httpclient}"/>
    
    <!-- Logs inbound and outbound protocols messages at DEBUG level -->
    <logger name="PROTOCOL_MESSAGE" level="${idp.loglevel.messages}" />

    <!-- Logs unencrypted SAML at DEBUG level -->
    <logger name="org.opensaml.saml.saml2.encryption.Encrypter" level="${idp.loglevel.encryption}" />

    <!-- Logs system properties during startup at DEBUG level -->
    <logger name="net.shibboleth.idp.log.LogbackLoggingService" level="${idp.loglevel.props}" />

    <!-- Especially chatty. -->
    <logger name="net.shibboleth.idp.saml.attribute.mapping" level="INFO" />
    <logger name="org.apache.xml.security" level="${idp.loglevel.xmlsec}" />
    <logger name="org.springframework" level="${idp.loglevel.spring}"/>
    <logger name="org.apache.catalina" level="${idp.loglevel.container}"/>
    <logger name="org.eclipse.jetty" level="${idp.loglevel.container}"/>


    <!-- =========================================================== -->
    <!-- ============== Low Level Details or Changes =============== -->
    <!-- =========================================================== -->
    
    <!-- Process log. -->
    <appender name="IDP_PROCESS" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <charset>UTF-8</charset>
            <Pattern>%date{ISO8601} - %mdc{idp.remote_addr} - %level [%logger:%line] - %msg%n%ex{short}</Pattern>
        </encoder>

        <!-- Ignore Velocity status page error. -->
        <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
            <evaluator>
                <matcher>
                    <Name>VelocityStatusMatcher</Name>
                    <regex>ResourceManager : unable to find resource 'status.vm' in any resource loader.</regex>
                </matcher>
                <expression>VelocityStatusMatcher.matches(formattedMessage)</expression>
            </evaluator>
            <OnMatch>DENY</OnMatch>
        </filter>
    </appender>

    <appender name="ASYNC_PROCESS" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="IDP_PROCESS" />
        <discardingThreshold>0</discardingThreshold>
    </appender>

    <!-- F-TICKS syslog destination. -->
    <appender name="IDP_FTICKS" class="ch.qos.logback.classic.net.SyslogAppender">
        <syslogHost>${idp.fticks.loghost:-localhost}</syslogHost>
        <port>${idp.fticks.logport:-514}</port>
        <facility>AUTH</facility>
        <suffixPattern>[%thread] %logger %msg</suffixPattern>
    </appender>

    <logger name="Shibboleth-Audit" level="ALL">
        <appender-ref ref="${idp.audit.appender:-IDP_AUDIT}"/>
    </logger>

    <logger name="Shibboleth-FTICKS" level="ALL" additivity="false">
        <appender-ref ref="${idp.fticks.appender:-IDP_FTICKS}"/>
    </logger>

    <logger name="Shibboleth-Consent-Audit" level="ALL">
        <appender-ref ref="${idp.consent.appender:-IDP_CONSENT_AUDIT}"/>
    </logger>
    
    <root level="${idp.loglevel.root:-INFO}">
        <appender-ref ref="${idp.process.appender:-IDP_PROCESS}"/>
        <appender-ref ref="${idp.warn.appender:-IDP_WARN}" />
    </root>

</configuration>