Не удается отключить ведение журнала для конкретного приложения

#java #log4j2 #slf4j

#java #log4j2 #slf4j

Вопрос:

Здесь log4j.xml

 <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration debug="true"
    xmlns:log4j="http://jakarta.apache.org/log4j/">

    <appender name="Console" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <!-- l, L, M - is extremely slow. It's use should be avoided unless execution 
                speed is not an issue. -->
            <param name="ConversionPattern" value="%d{[dd.MM.yyyy HH:mm:ss.SSS]} %l %p:%n    %m%n" />
        </layout>
    </appender>

    <appender name="File" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="Encoding" value="UTF-8" />
        <param name="File" value="logs/trace.log" />
        <param name="Append" value="true" />
        <layout class="org.apache.log4j.PatternLayout">
            <!-- l, L, M - is extremely slow. It's use should be avoided unless execution 
                speed is not an issue. -->
            <param name="ConversionPattern" value="%d{[dd.MM.yyyy HH:mm:ss.SSS]} %l %p:%n    %m%n" />
        </layout>
    </appender>

    <root>
        <level value="ALL" />
        <appender-ref ref="Console" />
        <appender-ref ref="File" />
    </root>

</log4j:configuration>
 

Используйте org.apache.log4j

 import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;

private static Logger logger = Logger.getLogger(UserOptions.class);;

AppenderSkeleton consoleAppender = (AppenderSkeleton) Logger.getRootLogger().getAppender("Console");
        AppenderSkeleton fileAppender = (AppenderSkeleton) Logger.getRootLogger().getAppender("File");
        if (!getOptionsAdditionalLoggingIsToConsole()) {
            consoleAppender.setThreshold(Level.OFF);
        }
        if (!getOptionsAdditionalLoggingIsToFile()) {
            fileAppender.setThreshold(Level.OFF);
}
 

В результате я могу отключить ведение журнала для конкретного приложения (консоль, файл)

Неплохо.

Здесь мой log4j2.xml

 <?xml version="1.0" encoding="UTF-8"?>
<Configuration package="log4j.test" status="WARN">
    <Properties>
        <Property name="baseDir">logs</Property>
        <Property name="patterLayout">%d{[dd.MM.yyyy HH:mm:ss.SSS]} [%t] %l %p:%n
            %m%n</Property>
    </Properties>

    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="${patterLayout}" />
        </Console>
        <RollingFile name="File" fileName="${baseDir}/application.log"
            filePattern="${baseDir}/application.%d{yyyy-MM-dd}.log.gz"
            ignoreExceptions="false">
            <PatternLayout>
                <Pattern>${patterLayout}</Pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" />
            </Policies>
            <DefaultRolloverStrategy max="5" />
        </RollingFile>
    </Appenders>

    <Loggers>
        <!-- Levels from lowest to highest are: ALL, TRACE, DEBUG, INFO, WARN, 
            ERROR, FATAL, OFF. The root category is used for all loggers unless a more 
            specific logger matches. If none of the loggers are assigned a level, then 
            all loggers inherit the level of the root logger which is set to DEBUG by 
            default -->
        <Root level="trace">
            <AppenderRef ref="Console" />
            <AppenderRef ref="File" />
        </Root>
    
    </Loggers>
</Configuration>
 

Теперь я хочу использовать org.slf4j

 import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;

private static Logger logger = LoggerFactory.getLogger(UserOptions.class);;

LoggerContext loggerContext = (LoggerContext) LogManager.getContext();
        Configuration configuration = loggerContext.getConfiguration();

        LoggerConfig rootLoggerConfig = configuration.getLoggerConfig("");
        Appender consoleAppender = rootLoggerConfig.getAppenders().get("Console");
        Appender fileAppender = rootLoggerConfig.getAppenders().get("File");

        if (!getOptionsAdditionalLoggingIsToConsole()) {
            consoleAppender.setThreshold(org.apache.log4j.Level.OFF);
}
 

Но я получаю сообщение об ошибке:

 error: cannot find symbol method setThreshold(Level)
 

Ответ №1:

«Теперь я хочу использовать org.slf4j«: если вы просто хотите использовать SLF4j, вы можете использовать его привязку Log4j 1.2. Я предполагаю, что вы также хотите обновить серверную часть ведения журнала с Log4j 1.2 до Log4j 2.x.

Вы получаете ошибку компиляции, поскольку LoggerConfig у него нет setThreshold метода. Поэтому вы должны использовать другие методы, имеющиеся в вашем распоряжении.

Если вы просто хотите удалить приложение консоли, используйте:

         LoggerConfig rootLoggerConfig = configuration.getRootLogger();
        rootLoggerConfig.removeAppender("Console");
 

Если вы хотите сохранить его, но заставить его замолчать, вам нужно удалить его и добавить с другим уровнем:

         LoggerConfig rootLoggerConfig = configuration.getRootLogger();
        Appender consoleAppender = rootLoggerConfig.getAppenders().get("Console");
        rootLoggerConfig.removeAppender("Console");
        rootLoggerConfig.addAppender(consoleAppender, Level.OFF, null);
 

Редактировать: вам также необходимо заменить строку:

 LoggerContext loggerContext = (LoggerContext) LogManager.getContext();
 

с

 LoggerContext loggerContext = (LoggerContext) LogManager.getContext(false);
 

поскольку (как указано в Javadoc для LogManager.getContext() ):

ПРЕДУПРЕЖДЕНИЕ — LoggerContext, возвращаемый этим методом, может не быть LoggerContext, используемым для создания регистратора для вызывающего класса.

Комментарии:

1. Метод «rootLoggerConfig.removeAppender («Консоль»);» не помогает. Журналы генерируются на консоли после запуска приложения.

2. Попробуйте LogManager.getContext(false) вместо LogManager.getContext() , поскольку два могут давать разные контексты.