Log4j2 markers in Logback

6k Views Asked by At

I'd like to use log4jdbc-log4j2 to log JDBC calls. The documentation providers information how to use it with Log4j2 markers.

<logger name="log4jdbc.log4j2" level="info" additivity="false">
  <MarkerFilter marker="LOG4JDBC_OTHER" onMatch="DENY" onMismatch="NEUTRAL"/>
  <appender-ref ref="Console"/>
</logger>

Is there any way how to rewrite the above code to work with Logback?

UPDATE: I already tried to put a TurboFilter outside the logger directly inside the configuration element. It however doesn't change the log output.

<turboFilter class="ch.qos.logback.classic.turbo.MarkerFilter">
    <Name>LOG4JDBC_LOGBACK_FILTER</Name>
    <Marker>LOG4JDBC_OTHER</Marker>
    <OnMatch>DENY</OnMatch>
</turboFilter>
4

There are 4 best solutions below

0
On

This works for me in logback.xml. This doesn't use markers at all but does what I need i.e. filters only sql statements (with timing).

<logger name="jdbc.sqlonly" level="error" additivity="false" ><appender-ref ref="CONSOLE"/></logger>
<logger name="jdbc.sqltiming" level="info" additivity="false" ><appender-ref ref="CONSOLE"/></logger>
<logger name="jdbc.audit" level="error" additivity="false" ><appender-ref ref="CONSOLE"/></logger>
<logger name="jdbc.resultset" level="error" additivity="false" ><appender-ref ref="CONSOLE"/></logger>
<logger name="jdbc.resultsettable" level="info" additivity="false" ><appender-ref ref="CONSOLE"/></logger>
<logger name="jdbc.connection" level="error" additivity="false" ><appender-ref ref="CONSOLE"/></logger>

These 6 loggers are described in log4jdbc-log4j2 documentation.

7
On

I believe what you are looking for is called TurboFilters in Logback. See http://logback.qos.ch/manual/filters.html

Update: if I understand your question correctly, you have an application that uses the Log4j 2 API (or one of its dependencies does). You want to use Logback as the logger implementation. Now, the question is, how to route calls from the Log4j 2 API to the Logback implementation, ideally translating Log4j 2 Markers into SLF4J Markers?

Perhaps all you need to do is add the Log4j to SLF4J adapter (log4j-to-slf4j-2.x.jar).

Be careful:

Use of the SLF4J adapter (log4j-to-slf4j-2.x.jar) together with the SLF4J bridge (log4j-slf4j-impl-2.x.jar) should never be attempted as it will cause events to endlessly be routed between SLF4J and Log4j 2.

5
On

Markers in log4j2 work this way:

package org.so.log4j2.test;

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;

public class Log4j2Test {
    public static void main(String[] args)
    {
        Logger logger = LogManager.getLogger("Test");
        Marker LOG4JDBC_OTHER = MarkerManager.getMarker("LOG4JDBC_OTHER");

        logger.info("Line to show.");
        logger.info(LOG4JDBC_OTHER, "Line to hide");
    }
}

With below log4j2.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <MarkerFilter marker="LOG4JDBC_OTHER" onMatch="DENY" onMismatch="NEUTRAL"/>
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="error">
            <AppenderRef ref="Console"/>
        </Root>
        <Logger name="Test" level="info" additivity="false">
            <AppenderRef ref="Console"/>
        </Logger>
    </Loggers>
</Configuration>

Output:

12:37:22.416 [main] INFO  Test - Line to show.

Markers in Logback work this way:

package org.so.logback.test;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;

public class LogbackTest {
    public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger("Test");
        Marker LOG4JDBC_OTHER = MarkerFactory.getMarker("LOG4JDBC_OTHER");
        logger.info("Line to show");
        logger.info(LOG4JDBC_OTHER, "Line to hide");
    }
}

With this logback.xml

<?xml version="1.0" ?>
<configuration>
    <property name="log.folder" value="./log"/>
    <turboFilter class="ch.qos.logback.classic.turbo.MarkerFilter">
        <Marker>LOG4JDBC_OTHER</Marker>
        <OnMatch>DENY</OnMatch>
        <OnMismatch>NEUTRAL</OnMismatch>
    </turboFilter>

  <appender class="ch.qos.logback.core.ConsoleAppender" name="CONSOLE">
    <encoder>
      <pattern>[%p] [%thread] %logger - %msg%n</pattern>
    </encoder>
  </appender>

  <root>
    <level value="INFO"/>
    <appender-ref ref="CONSOLE"/>
  </root>

  <logger name="Test" additivity="false">
    <level value="INFO" />
    <appender-ref ref="CONSOLE"/>
  </logger>     
</configuration>

Output:

[INFO] [main] Test - Line to show

Hope it helps.

P.s. maybe additivity flag again?..

0
On

I tried to put log4jdbc.dump.sql.select=false in log4jdbc.log4j2.properties, and it filtered out select statements. You can replace 'select' with other key words like 'create', 'update'...

If you want to have more control on the logging, you can extend Slf4jSpyLogDelegator, point log4jdbc.spylogdelegator.name to your new class and override methods as needed.