Как настроить log4j 2.x чисто программно?
Как настроить log4j 2.3
с console appender
чисто программно (без файлов конфигурации любого формата)?
В основном я ищу версию 2.x этого 1.x code.
В моих классах я использовал бы
private static final Logger logger = LogManager.getLogger();
//
// some method
logger.debug(someString);
Без какой-либо конфигурации я (как и ожидалось) обратился к
ОШИБКА StatusLogger Файл конфигурации log4j2 не найден. Использование конфигурации по умолчанию: запись только ошибок на консоль.
В то время как использование конфигурационных файлов, как представляется, правильно задокументировано, я не смог найти хороший пример случая с косой костью.
Ближайший я получил эту статью, которая по-прежнему использует фиктивный файл.
Вот мой лучший (хотя и безуспешный) выстрел:
private static void configureLog4J() {
PatternLayout layout = PatternLayout.createDefaultLayout();
ConsoleAppender appender = ConsoleAppender.createDefaultAppenderForLayout(layout);
LoggerConfig loggerConfig = new LoggerConfig();
loggerConfig.addAppender(appender, DEBUG, null);
}
Я что-то пропустил?
Если это еще файл RTFM, пожалуйста, укажите мне в правильном направлении.
Ответы
Ответ 1
package com;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.appender.ConsoleAppender;
import org.apache.logging.log4j.core.config.AppenderRef;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.logging.log4j.core.layout.PatternLayout;
import java.nio.charset.Charset;
public class MyLoggerTest {
public static void main(String[] args){
LoggerContext context= (LoggerContext) LogManager.getContext();
Configuration config= context.getConfiguration();
PatternLayout layout= PatternLayout.createLayout("%m%n", null, null, Charset.defaultCharset(),false,false,null,null);
Appender appender=ConsoleAppender.createAppender(layout, null, null, "CONSOLE_APPENDER", null, null);
appender.start();
AppenderRef ref= AppenderRef.createAppenderRef("CONSOLE_APPENDER",null,null);
AppenderRef[] refs = new AppenderRef[] {ref};
LoggerConfig loggerConfig= LoggerConfig.createLogger("false", Level.INFO,"CONSOLE_LOGGER","com",refs,null,null,null);
loggerConfig.addAppender(appender,null,null);
config.addAppender(appender);
config.addLogger("com", loggerConfig);
context.updateLoggers(config);
Logger logger=LogManager.getContext().getLogger("com");
logger.info("HELLO_WORLD");
}
}
Не уверен, что это то, что вы ищете. Это создает конфигурацию по умолчанию и добавляет консольный регистратор. Однако LogManager.getLogger() не работает и использует LogManager.getContext(). GetLogger() не допускает иерархию журналов. Честно говоря, я не рекомендую программный подход, Log4j2 аллергия на него.
Ответ 2
Вот полный пример программной конфигурации log4j 2.8.
У него есть 3 приложения: RollingFile, JDBC и SMTP.
Существует 1 файл конфигурации класса и 2 свойства, один для регистрации класса как log4j2 configurationFactory, а другой для набора свойств, таких как каталог файла журнала.
Класс № 1: MPLoggingConfiguration
package com.websitester.config;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.zip.Deflater;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.appender.RollingFileAppender;
import org.apache.logging.log4j.core.appender.SmtpAppender;
import org.apache.logging.log4j.core.appender.db.ColumnMapping;
import org.apache.logging.log4j.core.appender.db.jdbc.ColumnConfig;
import org.apache.logging.log4j.core.appender.db.jdbc.ConnectionSource;
import org.apache.logging.log4j.core.appender.db.jdbc.DataSourceConnectionSource;
import org.apache.logging.log4j.core.appender.db.jdbc.JdbcAppender;
import org.apache.logging.log4j.core.appender.rolling.CompositeTriggeringPolicy;
import org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy;
import org.apache.logging.log4j.core.appender.rolling.OnStartupTriggeringPolicy;
import org.apache.logging.log4j.core.appender.rolling.SizeBasedTriggeringPolicy;
import org.apache.logging.log4j.core.appender.rolling.TriggeringPolicy;
import org.apache.logging.log4j.core.config.AppenderRef;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.ConfigurationFactory;
import org.apache.logging.log4j.core.config.ConfigurationSource;
import org.apache.logging.log4j.core.config.DefaultConfiguration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.logging.log4j.core.config.Order;
import org.apache.logging.log4j.core.config.Property;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.layout.HtmlLayout;
import org.apache.logging.log4j.core.layout.PatternLayout;
public class MPLoggingConfiguration {
public static final String WEBSITESTER_LOGGER_NAME = "com.websitester";
public static final String FILE_PATTERN_LAYOUT = "%n[%d{yyyy-MM-dd HH:mm:ss}] [%-5p] [%l]%n\t%m%n%n";
public static final String LOG_FILE_NAME = "awmonitor.log";
public static final String LOG_FILE_NAME_PATTERN = "awmonitor-%i.log";
/**
* Just to make JVM visit this class to initialize the static parts.
*/
public static void configure() {
}
@Plugin(category = ConfigurationFactory.CATEGORY, name = "MPConfigurationFactory")
@Order(15)
public static class MPConfigurationFactory extends ConfigurationFactory {
public static final String[] SUFFIXES = new String[] {".json", "*"};
@Override
protected String[] getSupportedTypes() {
return SUFFIXES;
}
@Override
public Configuration getConfiguration(LoggerContext arg0, ConfigurationSource arg1) {
return new Log4j2Configuration(arg1);
}
}
private static class Log4j2Configuration extends DefaultConfiguration {
public Log4j2Configuration(ConfigurationSource source) {
super.doConfigure();
setName("mp-log4j2");
String logFilePath = "/log/weblogic/wl-moniport/";
// LOGGERS
// com.websitester
AppenderRef[] refs = new AppenderRef[] {};
Property[] properties = new Property[] {};
LoggerConfig websitesterLoggerConfig = LoggerConfig.createLogger(true, Level.INFO, WEBSITESTER_LOGGER_NAME, "true", refs, properties, this, null);
addLogger(WEBSITESTER_LOGGER_NAME, websitesterLoggerConfig);
// APPENDERS
final Charset charset = Charset.forName("UTF-8");
// MP ROLLING FILE
TriggeringPolicy mpFileCompositePolicy = CompositeTriggeringPolicy.createPolicy(
SizeBasedTriggeringPolicy.createPolicy("3 M"),
OnStartupTriggeringPolicy.createPolicy(1));
final DefaultRolloverStrategy mpFileRolloverStrategy = DefaultRolloverStrategy.createStrategy("9", "1", "max", Deflater.NO_COMPRESSION + "", null, true, this);
Layout<? extends Serializable> mpFileLayout = PatternLayout.newBuilder()
.withPattern(FILE_PATTERN_LAYOUT)
.withPatternSelector(null)
.withConfiguration(this)
.withRegexReplacement(null)
.withCharset(charset)
.withAlwaysWriteExceptions(isShutdownHookEnabled)
.withNoConsoleNoAnsi(isShutdownHookEnabled)
.withHeader(null)
.withFooter(null)
.build();
Appender mpFileAppender = RollingFileAppender.newBuilder()
.withAdvertise(Boolean.parseBoolean(null))
.withAdvertiseUri(null)
.withAppend(true)
.withBufferedIo(true)
.withBufferSize(8192)
.setConfiguration(this)
.withFileName(logFilePath + LOG_FILE_NAME)
.withFilePattern(logFilePath + LOG_FILE_NAME_PATTERN)
.withFilter(null)
.withIgnoreExceptions(true)
.withImmediateFlush(true)
.withLayout(mpFileLayout)
.withCreateOnDemand(false)
.withLocking(false)
.withName("error_file_web")
.withPolicy(mpFileCompositePolicy)
.withStrategy(mpFileRolloverStrategy)
.build();
mpFileAppender.start();
addAppender(mpFileAppender);
getLogger(WEBSITESTER_LOGGER_NAME).addAppender(mpFileAppender, Level.DEBUG, null);
// JDBC
if (System.getProperty("log4jjdbcjndiName") != null){
ColumnConfig[] columnConfigs = new ColumnConfig[] {
ColumnConfig.newBuilder()
.setConfiguration(this)
.setName("DATED")
.setPattern(null)
.setLiteral(null)
.setEventTimestamp(true)
.setUnicode(false)
.setClob(false)
.build(),
ColumnConfig.newBuilder()
.setConfiguration(this)
.setName("LOGGER")
.setPattern("%logger")
.setLiteral(null)
.setEventTimestamp(false)
.setUnicode(false)
.setClob(false)
.build(),
ColumnConfig.newBuilder()
.setConfiguration(this)
.setName("LOG_LEVEL")
.setPattern("%level")
.setLiteral(null)
.setEventTimestamp(false)
.setUnicode(false)
.setClob(false)
.build(),
ColumnConfig.newBuilder()
.setConfiguration(this)
.setName("MESSAGE")
.setPattern("%message")
.setLiteral(null)
.setEventTimestamp(false)
.setUnicode(false)
.setClob(false)
.build(),
ColumnConfig.newBuilder()
.setConfiguration(this)
.setName("NODE")
.setPattern("" + System.getProperty("log4jmpserverid"))
.setLiteral(null)
.setEventTimestamp(false)
.setUnicode(false)
.setClob(false)
.build()
};
ConnectionSource dataSourceConnectionSource = DataSourceConnectionSource.createConnectionSource(System.getProperty("log4jjdbcjndiName"));
if (dataSourceConnectionSource != null){
Appender jdbcAppender = JdbcAppender.newBuilder()
.setBufferSize(0)
.setColumnConfigs(columnConfigs)
.setColumnMappings(new ColumnMapping[]{})
.setConnectionSource(dataSourceConnectionSource)
.setTableName("MTDTLOGS")
.withName("databaseAppender")
.withIgnoreExceptions(true)
.withFilter(null)
.build();
jdbcAppender.start();
addAppender(jdbcAppender);
getLogger(WEBSITESTER_LOGGER_NAME).addAppender(jdbcAppender, Level.WARN, null);
}
};
// SMTP
if (System.getProperty("log4jemailSubject") != null){
if (System.getProperty("log4jemailLevel").equalsIgnoreCase("error")) {
Layout<? extends Serializable> mpHtmlLayout = HtmlLayout.createLayout(false, "Monitor de Portales", null, null, "x-small", null);
Appender smtpAppender = SmtpAppender.createAppender(
this,
"SMTP",
System.getProperty("log4jemailTo"),
System.getProperty("log4jemailcc"),
System.getProperty("log4jemailbcc"),
System.getProperty("log4jemailFrom"),
System.getProperty("log4jemailreplyTo"),
System.getProperty("log4jemailSubject"),
System.getProperty("log4jemailProtocol"),
System.getProperty("log4jemailHost"),
System.getProperty("log4jemailPort"),
System.getProperty("log4jemailUserName"),
System.getProperty("log4jemailPassword"),
"false",
"50",
mpHtmlLayout,
null,
"true");
smtpAppender.start();
addAppender(smtpAppender);
getLogger(WEBSITESTER_LOGGER_NAME).addAppender(smtpAppender, Level.ERROR, null);
}
}
}
}
}
Файл конфигурации: src/main/resources/log4j2.component.properties
log4j.configurationFactory=com.websitester.config.MPLoggingConfiguration$MPConfigurationFactory
log4j.configurationFile=log4j2websitester.json
Файл конфигурации: src/main/resources/log4j2websitester.json
{"logFilePath" : "/log/weblogic/wl-moniport/"}
В моем случае я установил все свойства (доступ к которым осуществляется через MPLoggingConfiguration через System.getProperty) в других классах, например:
System.setProperty("log4jjdbcjndiName", "weblogic-monitor");
Когда вы изменили некоторые свойства и хотите перенастроить log4j2, вы должны сделать этот вызов:
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
ctx.reconfigure();
Надеюсь, это поможет
Ответ 3
Вы можете настроить свой собственный ConfigurationFactory в log4j.
Pls ссылается на https://logging.apache.org/log4j/2.x/manual/customconfig.html. Кажется, он может удовлетворить ваши потребности.
Извините за это. Соответствует ли это вашим потребностям? Я просто тестирую, и он работает хорошо, хотя он все еще выводит сообщение об ошибке, о котором вы говорили выше.
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
final Configuration config = ctx.getConfiguration();
Layout<? extends Serializable> layout = PatternLayout.createLayout(PatternLayout.SIMPLE_CONVERSION_PATTERN, config, null,
null,true, true,null,null);
Appender appender = FileAppender.createAppender("/tmp/log4jtest.txt", "false", "false", "File", "true",
"false", "false", "4000", layout, null, "false", null, config);
appender.start();
config.addAppender(appender);
AppenderRef ref = AppenderRef.createAppenderRef("File", null, null);
AppenderRef[] refs = new AppenderRef[] {ref};
LoggerConfig loggerConfig = LoggerConfig.createLogger("false", Level.INFO, "org.apache.logging.log4j",
"true", refs, null, config, null );
loggerConfig.addAppender(appender, null, null);
config.addLogger("simpleTestLogger", loggerConfig);
ctx.updateLoggers();
Logger l = ctx.getLogger("simpleTestLogger");
l.info("message of info level shoud be output properly");
l.error("error message");
Ответ 4
если вы хотите использовать консольный appender, есть очень простой способ, если вы используете maven, просто поместите эти 2 зависимости в свой pom.xml, и все будет напечатано на консоли ур. ничего не нужно... нет файла log4j.properties. slf4j расширяет log4j и имеет так много богатых функций.
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.5</version>
</dependency>
Ответ 5
документация рекомендует API-интерфейс компоновщика для программной конфигурации. Используя этот API, ваш метод configureLog4J()
может выглядеть примерно так:
public static void configureLog4J() {
ConfigurationBuilder<BuiltConfiguration> builder =
ConfigurationBuilderFactory.newConfigurationBuilder();
// configure a console appender
builder.add(
builder.newAppender("stdout", "Console")
.add(
builder.newLayout(PatternLayout.class.getSimpleName())
.addAttribute(
"pattern",
"%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"
)
)
);
// configure the root logger
builder.add(
builder.newRootLogger(Level.INFO)
.add(builder.newAppenderRef("stdout"))
);
// apply the configuration
Configurator.initialize(builder.build());
}
Теперь дело в том, что, на самом деле, в руководстве недостаточно четко сказано, что
этот метод статической инициализации должен вызываться до любых вызовов
LogManager.getLogger()
.
В качестве минимального рабочего примера вы можете использовать статический блок инициализации, например, так
private static final Logger log;
static {
configureLog4J();
log = LogManager.getLogger(MyAwesomeClass.class);
}
Тем не менее, настройка ведения журнала программным способом, IMHO, не очень хорошая идея для любого
нетривиальный проект: вам придется каждый раз перекомпилировать, тестировать и отправлять код
Вы хотите временно увеличить уровни журналов на определенных регистраторах для диагностики
производственные проблемы. Поэтому я настоятельно рекомендую не использовать его.
Ответ 6
Ответ Yiping в основном правильный. Ответ, предполагающий, что Log4j 2 не предназначен для этого или использовать SLF4J, неверен. Я добавил пример в Log4j, чтобы продемонстрировать, как это сделать. Пожалуйста, посмотрите пример проекта https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;a=tree;f=log4j-samples/configuration